00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FXGENERICTOOLS_H
00023 #define FXGENERICTOOLS_H
00024
00025 #include "FXString.h"
00026 #include "FXPolicies.h"
00027 #include "FXException.h"
00028 #include "FXPath.h"
00029 #include <typeinfo>
00030 #include <assert.h>
00031
00032 namespace FX {
00033
00039 namespace Generic {
00054
00055 #ifdef _MSC_VER
00056 typedef ::type_info type_info;
00057 #else
00058 typedef std::type_info type_info;
00059 #endif
00060
00061 #ifndef HAVE_CPP0XSTATICASSERT
00062 template<bool> struct StaticAssert;
00063 template<> struct StaticAssert<true>
00064 {
00065 StaticAssert() { }
00066 };
00067 #define FXSTATIC_ASSERT2(expr, msg) \
00068 FX::Generic::StaticAssert<(expr)!=0> ERROR_##msg
00069
00079 #define FXSTATIC_ASSERT(expr, msg) \
00080 { \
00081 FXSTATIC_ASSERT2(expr, msg); \
00082 }
00083
00084 template<typename foo> struct StaticError;
00085 #else
00086 #define FXSTATIC_ASSERT(expr, msg) static_assert((expr)!=0, #msg )
00087 #define FXSTATIC_ASSERT2(expr, msg) static_assert((expr)!=0, #msg )
00088 #endif
00089
00094 struct NullType { };
00101 template<int n> struct IntToType { static const int value=n; };
00107 template<typename type> struct TypeToType { typedef type value; };
00112 template<bool v, typename type=NullType> struct Boolean { static const bool value=v; };
00113
00122 template<bool v, typename A, typename B> struct select
00123 {
00124 typedef A value;
00125 };
00126 template<typename A, typename B> struct select<false, A, B>
00127 {
00128 typedef B value;
00129 };
00134 template<typename A, typename B> struct sameType
00135 {
00136 static const bool value=false;
00137 };
00138 template<typename T> struct sameType<T, T>
00139 {
00140 static const bool value=true;
00141 };
00146 template<typename type> struct addRef { typedef type &value; };
00147 template<typename type> struct addRef<type &> { typedef type value; };
00148 template<> struct addRef<void> { typedef void value; };
00149 template<> struct addRef<const void> { typedef const void value; };
00154 template<typename type> struct addConstRef { typedef const type &value; };
00155 template<typename type> struct addConstRef<type &> { typedef typename addConstRef<type>::value value; };
00156 template<typename type> struct addConstRef<const type> { typedef typename addConstRef<type>::value value; };
00157 template<typename type> struct addConstRef<const type &> { typedef const type &value; };
00158 template<> struct addConstRef<void> { typedef void value; };
00159
00160 namespace convertiblePrivate {
00161 struct TwoChar { char foo[2]; };
00162 template<typename to, typename from> struct impl
00163 {
00164 static from makeFrom();
00165 static TwoChar test(...);
00166 static char test(to);
00167 };
00168 }
00169 #ifdef _MSC_VER
00170 #pragma warning(push)
00171 #pragma warning(disable: 4244) // possible loss of data
00172 #pragma warning(disable: 4800) // forcing value to bool true or false
00173 #endif
00174
00178 template<typename to, typename from> struct convertible
00179 {
00180 private:
00181 typedef typename addConstRef<to>::value refTo;
00182 typedef typename addConstRef<from>::value refFrom;
00183 typedef convertiblePrivate::impl<refTo, refFrom> impl;
00184 public:
00185 static const bool value=sizeof(impl::test(impl::makeFrom()))==sizeof(char);
00186 };
00187 template<typename T> struct convertible<void, T> { static const bool value=false; };
00188 template<typename T> struct convertible<T, void> { static const bool value=false; };
00189 template<> struct convertible<void, void> { static const bool value=true; };
00190 #ifdef _MSC_VER
00191 #pragma warning(pop)
00192 #endif
00193
00202 template<typename ptr> struct lessIndir
00203 {
00204 typedef ptr value;
00205 static const bool failed=true;
00206 };
00207 template<typename ptr> struct lessIndir<ptr *>
00208 {
00209 typedef ptr value;
00210 static const bool failed=false;
00211 };
00212 template<typename ptr> struct lessIndir<const ptr *>
00213 {
00214 typedef ptr value;
00215 static const bool failed=false;
00216 };
00217 template<typename ptr> struct lessIndir<volatile ptr *>
00218 {
00219 typedef ptr value;
00220 static const bool failed=false;
00221 };
00222 template<typename ptr> struct lessIndir<const volatile ptr *>
00223 {
00224 typedef ptr value;
00225 static const bool failed=false;
00226 };
00227 template<typename ptr> struct lessIndir<ptr &>
00228 {
00229 typedef ptr value;
00230 static const bool failed=false;
00231 };
00232 template<typename ptr> struct lessIndir<const ptr &>
00233 {
00234 typedef ptr value;
00235 static const bool failed=false;
00236 };
00237 template<typename ptr> struct lessIndir<volatile ptr &>
00238 {
00239 typedef ptr value;
00240 static const bool failed=false;
00241 };
00242 template<typename ptr> struct lessIndir<const volatile ptr &>
00243 {
00244 typedef ptr value;
00245 static const bool failed=false;
00246 };
00251 template<typename type> struct indirs { static const int value=0; };
00252 template<typename type> struct indirs<type &> { static const int value=1+indirs<type>::value; };
00253 template<typename type> struct indirs<const type &> { static const int value=1+indirs<type>::value; };
00254 template<typename type> struct indirs<volatile type &> { static const int value=1+indirs<type>::value; };
00255 template<typename type> struct indirs<const volatile type &> { static const int value=1+indirs<type>::value; };
00256 template<typename type> struct indirs<type *> { static const int value=1+indirs<type>::value; };
00257 template<typename type> struct indirs<const type *> { static const int value=1+indirs<type>::value; };
00258 template<typename type> struct indirs<volatile type *> { static const int value=1+indirs<type>::value; };
00259 template<typename type> struct indirs<const volatile type *> { static const int value=1+indirs<type>::value; };
00264 template<typename ptr> struct leastIndir { typedef ptr value; };
00265 template<typename ptr> struct leastIndir<ptr *> { typedef typename leastIndir<ptr>::value value; };
00266 template<typename ptr> struct leastIndir<const ptr *> { typedef typename leastIndir<ptr>::value value; };
00267 template<typename ptr> struct leastIndir<volatile ptr *> { typedef typename leastIndir<ptr>::value value; };
00268 template<typename ptr> struct leastIndir<const volatile ptr *> { typedef typename leastIndir<ptr>::value value; };
00269 template<typename ptr> struct leastIndir<ptr &> { typedef typename leastIndir<ptr>::value value; };
00270 template<typename ptr> struct leastIndir<const ptr &> { typedef typename leastIndir<ptr>::value value; };
00271 template<typename ptr> struct leastIndir<volatile ptr &> { typedef typename leastIndir<ptr>::value value; };
00272 template<typename ptr> struct leastIndir<const volatile ptr &> { typedef typename leastIndir<ptr>::value value; };
00273
00274 #if defined(_MSC_VER) && _MSC_VER>=1400
00275 namespace msvc_typeof_impl {
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 struct msvc_extract_type_default_param {};
00305 template<int ID, typename T = msvc_extract_type_default_param> struct msvc_extract_type;
00306
00307 template<int ID> struct msvc_extract_type<ID, msvc_extract_type_default_param>
00308 {
00309 template<bool> struct id2type_impl;
00310
00311 typedef id2type_impl<true> id2type;
00312 };
00313
00314 template<int ID, typename T> struct msvc_extract_type : msvc_extract_type<ID, msvc_extract_type_default_param>
00315 {
00316 template<> struct id2type_impl<true>
00317 {
00318 typedef T type;
00319 };
00320 template<bool> struct id2type_impl;
00321
00322 typedef id2type_impl<true> id2type;
00323 };
00324
00325
00326 template<int N> class CCounter;
00327
00328
00329 template<typename TUnused, int NTested = 0> struct CCountOf
00330 {
00331 enum
00332 {
00333 __if_exists(CCounter<NTested>) { count = CCountOf<TUnused, NTested + 1>::count }
00334 __if_not_exists(CCounter<NTested>) { count = NTested }
00335 };
00336 };
00337
00338 template<class TTypeReg, class TUnused, int NValue> struct CProvideCounterValue { enum { value = NValue }; };
00339
00340
00341 #define unique_type_id(type) \
00342 (CProvideCounterValue< \
00343 typename msvc_extract_type<CCountOf<type >::count, type>::id2type, \
00344 CCounter<CCountOf<type >::count>, \
00345 CCountOf<type >::count \
00346 >::value)
00347
00348
00349 class __Increment_type_id { enum { value = unique_type_id(__Increment_type_id) }; };
00350
00351
00352 template<int NSize> class sized { char m_pad[NSize]; };
00353 template<typename T> typename sized<unique_type_id(T)> vartypeID(T&);
00354 template<typename T> typename sized<unique_type_id(const T)> vartypeID(const T&);
00355 template<typename T> typename sized<unique_type_id(volatile T)> vartypeID(volatile T&);
00356 template<typename T> typename sized<unique_type_id(const volatile T)> vartypeID(const volatile T&);
00357 }
00358
00359 #define typeof(expression) FX::Generic::msvc_typeof_impl::msvc_extract_type<sizeof(FX::Generic::msvc_typeof_impl::vartypeID(expression))>::id2type::type
00360 #endif
00361
00365 class typeInfoBase
00366 {
00367 FXString decorated, readable;
00368 public:
00369 typeInfoBase() { }
00371 typeInfoBase(const type_info &ti) :
00372 #ifdef _MSC_VER
00373 decorated(ti.raw_name()), readable(ti.name())
00374 #elif defined(__GNUC__) || defined(__DMC__)
00375 decorated(ti.name()), readable(fxdemanglesymbol(ti.name()))
00376 #else
00377 #error Method of demangling RTTI unknown
00378 #endif
00379 {
00380 assert(!decorated.empty());
00381 }
00383 bool operator!() const throw() { return !!decorated.empty(); }
00385 bool operator==(const typeInfoBase &o) const { return (decorated==o.decorated)!=0; }
00387 bool operator!=(const typeInfoBase &o) const { return (decorated!=o.decorated)!=0; }
00389 const FXString &name() const { return readable; }
00391 const FXString &mangled() const { return decorated; }
00393 FXString asIdentifier() const
00394 {
00395 FXString ret(readable);
00396 ret.substitute('<', '_'); ret.substitute('>', '_'); ret.substitute(',', '_'); ret.substitute(':', '_');
00397 return ret;
00398 }
00400 FXString asLeafIdentifier() const
00401 {
00402 FXint rpos=readable.rfind(':'); if(-1==rpos) rpos=readable.rfind(' ');
00403 FXString ret(readable.mid(rpos+1));
00404 return ret;
00405 }
00406
00407 friend FXAPI FXStream &operator<<(FXStream &s, const typeInfoBase &i);
00408 friend FXAPI FXStream &operator>>(FXStream &s, typeInfoBase &i);
00409 };
00427 template<typename type> class typeInfo : public typeInfoBase
00428 {
00429 public:
00430 typeInfo(const type_info &ti=typeid(type)) : typeInfoBase(ti) { }
00431 };
00493 template<typename type,
00494 template<class> class ownershipPolicy=FX::Pol::destructiveCopy>
00495 class ptr : public ownershipPolicy<type>
00496 {
00497 typedef ownershipPolicy<type> op;
00498 public:
00500 ptr(type *data=0) : op(data) { }
00501 ptr(const ptr &o) : op(o) { }
00503 ptr &operator=(type *data) { PtrReset(*this, data); return *this; }
00504 type &operator *() { assert(PtrPtr(*this)); return *PtrPtr(*this); }
00505 const type &operator *() const { assert(PtrPtr(*this)); return *PtrPtr(*this); }
00506 type *operator->()
00507 {
00508 type *ret=PtrPtr(*this);
00509 if(!ret)
00510 {
00511 assert(ret);
00512 }
00513 return ret;
00514 }
00515 const type *operator->() const
00516 {
00517 const type *ret=PtrPtr(*this);
00518 if(!ret)
00519 {
00520 assert(ret);
00521 }
00522 return ret;
00523 }
00525 friend type *PtrRelease(ptr &p)
00526 {
00527 type *ret=PtrRef(p);
00528 PtrRef(p)=0;
00529 return ret;
00530 }
00532 friend void PtrReset(ptr &p, type *data)
00533 {
00534 p=ptr(data);
00535 }
00536 template<typename T> bool operator==(const ptr<T> &o) const { return PtrRef(*this)==PtrRef(o); }
00537 template<typename T> bool operator==(T *o) const { return PtrRef(*this)==o; }
00538
00539 private:
00540 struct Tester
00541 {
00542 private:
00543 void operator delete(void *);
00544 };
00545 public:
00546 operator Tester *() const
00547 {
00548 if(!*this) return 0;
00549 static Tester t;
00550 return &t;
00551 }
00552
00553
00554 bool operator!() const { return PtrRef(*this)==0; }
00555 template<typename T> bool operator!=(const ptr<T> &o) const { return !(*this==o); }
00556 template<typename T> bool operator!=(T *o) const { return !(*this==o); }
00557 };
00558
00589 namespace TL
00590 {
00595 template<typename A, typename B> struct item
00596 {
00598 typedef A value;
00600 typedef B next;
00601 };
00607 template<typename T1 =NullType, typename T2 =NullType, typename T3 =NullType, typename T4 =NullType,
00608 typename T5 =NullType, typename T6 =NullType, typename T7 =NullType, typename T8 =NullType,
00609 typename T9 =NullType, typename T10=NullType, typename T11=NullType, typename T12=NullType,
00610 typename T13=NullType, typename T14=NullType, typename T15=NullType, typename T16=NullType>
00611 struct create
00612 {
00613 private:
00614 typedef typename create<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value temp;
00615 public:
00616 typedef item<T1, temp> value;
00617 };
00618 template<> struct create<> { typedef NullType value; };
00628 template<class typelist> struct length
00629 {
00630 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00631 };
00632 template<> struct length<NullType> { static const int value=0; };
00633 template<class A, class B> struct length< item<A, B> >
00634 {
00635 static const int value=1+length<B>::value;
00636 };
00641 template<class typelist, FXuint idx> struct at { typedef NullType value; };
00642 template<class A, class B> struct at<item<A, B>, 0> { typedef A value; };
00643 template<class A, class B, FXuint idx> struct at<item<A, B>, idx>
00644 {
00645 typedef typename at<B, idx-1>::value value;
00646 };
00651 template<class typelist, FXuint idx> struct atC
00652 {
00653 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Out_Of_Bounds_Or_Not_A_TypeList);
00654 };
00655 template<class A, class B> struct atC<item<A, B>, 0> { typedef A value; };
00656 template<class A, class B, FXuint idx> struct atC<item<A, B>, idx>
00657 {
00658 typedef typename atC<B, idx-1>::value value;
00659 };
00664 template<class typelist, typename type> struct find
00665 {
00666 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00667 };
00668 template<typename type> struct find<NullType, type> { static const int value=-1; };
00669 template<typename type, class next> struct find<item<type, next>, type> { static const int value=0; };
00670 template<typename A, class next, typename type> struct find<item<A, next>, type>
00671 {
00672 private:
00673 static const int temp=find<next, type>::value;
00674 public:
00675 static const int value=(temp==-1 ? -1 : 1+temp);
00676 };
00681 template<class typelist, typename type> struct findC
00682 {
00683 static const int value=find<typelist, type>::value;
00684 private:
00685 FXSTATIC_ASSERT2(value!=-1, ERROR_Type_Not_Found);
00686 };
00691 template<class typelist, typename type> struct findParent
00692 {
00693 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00694 };
00695 template<typename type> struct findParent<NullType, type> { static const int value=-1; };
00696 template<typename type, class next> struct findParent<item<type, next>, type> { static const int value=0; };
00697 template<typename A, class next, typename type> struct findParent<item<A, next>, type>
00698 {
00699 private:
00700 static const bool isSubclass=convertible<A, type>::value;
00701 static const int temp=isSubclass ? 0 : findParent<next, type>::value;
00702 public:
00703 static const int value=(temp==-1 ? -1 : 1+temp-isSubclass);
00704 };
00709 template<class typelist, typename type> struct findParentC
00710 {
00711 static const int value=findParent<typelist, type>::value;
00712 private:
00713 FXSTATIC_ASSERT2(value!=-1, ERROR_Type_Not_Found);
00714 };
00719 template<class typelist, typename type> struct append
00720 {
00721 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00722 };
00723 template<> struct append<NullType, NullType> { typedef NullType value; };
00724 template<typename type> struct append<NullType, type> { typedef typename create<type>::value value; };
00725 template<typename A, class next> struct append<NullType, item<A, next> >
00726 {
00727 typedef item<A, next> value;
00728 };
00729 template<typename A, class next, typename type> struct append<item<A,next>, type>
00730 {
00731 typedef item<A, typename append<next, type>::value> value;
00732 };
00737 template<class typelist, typename type> struct remove
00738 {
00739 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00740 };
00741 template<typename type> struct remove<NullType, type> { typedef NullType value; };
00742 template<typename type, class next> struct remove<item<type, next>, type> { typedef next value; };
00743 template<typename A, class next, typename type> struct remove<item<A, next>, type>
00744 {
00745 typedef item<A, typename remove<next, type>::value> value;
00746 };
00747 namespace numberRangePrivate {
00748 template<int no, template<int> class instance, int top> struct Impl
00749 {
00750 typedef item<instance<top-no>, typename Impl<no-1, instance, top>::value> value;
00751 };
00752 template<template<int> class instance, int top> struct Impl<0, instance, top>
00753 {
00754 typedef NullType value;
00755 };
00756 }
00766 template<int no, template<int> class instance=IntToType> struct numberRange
00767 {
00768 typedef typename numberRangePrivate::Impl<no, instance, no>::value value;
00769 };
00776 template<typename typelist, template<class> class instance> struct apply
00777 {
00778 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00779 };
00780 template<typename type, class next, template<class> class instance> struct apply<item<type, next>, instance>
00781 {
00782 typedef item<instance<type>, typename apply<next, instance>::value> value;
00783 };
00784 template<template<class> class instance> struct apply<NullType, instance>
00785 {
00786 typedef NullType value;
00787 };
00799 template<typename typelist, template<class> class filt> struct filter
00800 {
00801 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00802 };
00803 template<typename type, class next, template<class> class filt> struct filter<item<type, next>, filt>
00804 {
00805 private:
00806 typedef typename filter<next, filt>::value nextfilter;
00807 public:
00808 typedef typename select<filt<type>::value, item<type, nextfilter>, nextfilter>::value value;
00809 };
00810 template<template<class> class filt> struct filter<NullType, filt>
00811 {
00812 typedef NullType value;
00813 };
00818 template<int no, typename type> struct replicate
00819 {
00820 typedef item<type, typename replicate<no-1, type>::value> value;
00821 };
00822 template<typename type> struct replicate<0, type>
00823 {
00824 typedef NullType value;
00825 };
00826
00827 #if defined(_MSC_VER)
00828 #pragma warning(push)
00829
00830 #pragma warning(disable : 4584)
00831 #endif // _MSC_VER
00832
00837 template<typename type> struct instanceHolderH
00838 {
00839 type value;
00841 instanceHolderH() { }
00843 template<typename P1> instanceHolderH(P1 p1) : value(p1) { }
00845 template<typename P1, typename P2> instanceHolderH(P1 p1, P2 p2) : value(p1, p2) { }
00847 template<typename P1, typename P2, typename P3> instanceHolderH(P1 p1, P2 p2, P3 p3) : value(p1, p2, p3) { }
00848 };
00849
00850 namespace Private
00851 {
00852 template<int idx, class instance> struct instanceHHolder : public instance
00853 {
00854 instanceHHolder() : instance() { }
00855 template<typename P1> explicit instanceHHolder(P1 p1) : instance(p1) { }
00856 template<typename P1, typename P2> explicit instanceHHolder(P1 p1, P2 p2) : instance(p1, p2) { }
00857 template<typename P1, typename P2, typename P3> explicit instanceHHolder(P1 p1, P2 p2, P3 p3) : instance(p1, p2, p3) { }
00858 };
00859 }
00889 template<typename typelist, template<class> class instance=instanceHolderH, int idx=0> struct instantiateH
00890 {
00891 FXSTATIC_ASSERT2((Boolean<false, typelist>::value), ERROR_Not_A_TypeList);
00892 };
00893 template<typename type, class next, template<class> class instance, int idx> struct instantiateH<item<type, next>, instance, idx>
00894 : public Private::instanceHHolder<idx, instance<type> >, public instantiateH<next, instance, idx+1>
00895 {
00897 instantiateH() : Private::instanceHHolder<idx, instance<type> >(), instantiateH<next, instance, idx+1>() { }
00899 template<typename P1> explicit instantiateH(P1 p1)
00900 : Private::instanceHHolder<idx, instance<type> >(p1), instantiateH<next, instance, idx+1>(p1) { }
00902 template<typename P1, typename P2> explicit instantiateH(P1 p1, P2 p2)
00903 : Private::instanceHHolder<idx, instance<type> >(p1, p2), instantiateH<next, instance, idx+1>(p1, p2) { }
00905 template<typename P1, typename P2, typename P3> explicit instantiateH(P1 p1, P2 p2, P3 p3)
00906 : Private::instanceHHolder<idx, instance<type> >(p1, p2, p3), instantiateH<next, instance, idx+1>(p1, p2, p3) { }
00907 };
00908 template<template<class> class instance, int idx> struct instantiateH<NullType, instance, idx>
00909 {
00910 instantiateH() { }
00911 template<typename P1> explicit instantiateH(P1 p1) { }
00912 template<typename P1, typename P2> explicit instantiateH(P1 p1, P2 p2) { }
00913 template<typename P1, typename P2, typename P3> explicit instantiateH(P1 p1, P2 p2, P3 p3) { }
00914 };
00915
00916 namespace Private
00917 {
00918
00919 template<int i, class container> struct accessInstantiateH
00920 {
00921 FXSTATIC_ASSERT2((Boolean<false, container>::value), ERROR_Not_An_InstantiateH_Container);
00922 };
00923 template<int i, typename typelist, template<class> class instance> struct accessInstantiateH<i, instantiateH<typelist, instance, 0> >
00924 {
00925 typedef instance<typename atC<typelist, i>::value> IdxType;
00926 typedef instantiateH<typelist, instance, 0> containerType;
00927 static IdxType &Get(containerType &c)
00928 {
00929 return static_cast<instanceHHolder<i, IdxType> &>(c);
00930 }
00931 };
00932 template<int i, typename typelist, template<class> class instance> struct accessInstantiateH<i, const instantiateH<typelist, instance, 0> >
00933 {
00934 typedef instance<typename atC<typelist, i>::value> IdxTypeO;
00935 typedef const IdxTypeO IdxType;
00936 typedef const instantiateH<typelist, instance, 0> containerType;
00937 static IdxType &Get(const containerType &c)
00938 {
00939 return static_cast<const instanceHHolder<i, IdxTypeO> &>(c);
00940 }
00941 };
00942 }
00949 template<int i, class container> typename Private::accessInstantiateH<i, container>::IdxType &instance(container &c)
00950 {
00951 return Private::accessInstantiateH<i, container>::Get(c);
00952 }
00953 #if defined(_MSC_VER)
00954 #pragma warning(pop)
00955 #endif
00956 }
00957 #define FXTYPELIST1(P1) FX::Generic::TL::list<P1, FX::Generic::NullType>
00958 #define FXTYPELIST2(P1,P2) FX::Generic::TL::list<P1, FXTYPELIST1(P2) >
00959 #define FXTYPELIST3(P1,P2,P3) FX::Generic::TL::list<P1, FXTYPELIST2(P2,P3) >
00960 #define FXTYPELIST4(P1,P2,P3,P4) FX::Generic::TL::list<P1, FXTYPELIST3(P2,P3,P4) >
00961 #define FXTYPELIST5(P1,P2,P3,P4,P5) FX::Generic::TL::list<P1, FXTYPELIST4(P2,P3,P4,P5) >
00962 #define FXTYPELIST6(P1,P2,P3,P4,P5,P6) FX::Generic::TL::list<P1, FXTYPELIST5(P2,P3,P4,P5,P6) >
00963 #define FXTYPELIST7(P1,P2,P3,P4,P5,P6,P7) FX::Generic::TL::list<P1, FXTYPELIST6(P2,P3,P4,P5,P6,P7) >
00964 #define FXTYPELIST8(P1,P2,P3,P4,P5,P6,P7,P8) FX::Generic::TL::list<P1, FXTYPELIST7(P2,P3,P4,P5,P6,P7,P8) >
00965 #define FXTYPELIST9(P1,P2,P3,P4,P5,P6,P7,P8,P9) FX::Generic::TL::list<P1, FXTYPELIST8(P2,P3,P4,P5,P6,P7,P8,P9) >
00966 #define FXTYPELIST10(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10) \
00967 FX::Generic::TL::list<P1, FXTYPELIST9(P2,P3,P4,P5,P6,P7,P8,P9,P10) >
00968 #define FXTYPELIST11(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11) \
00969 FX::Generic::TL::list<P1, FXTYPELIST10(P2,P3,P4,P5,P6,P7,P8,P9,P10,P11) >
00970 #define FXTYPELIST12(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12) \
00971 FX::Generic::TL::list<P1, FXTYPELIST11(P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12) >
00972 #define FXTYPELIST13(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13) \
00973 FX::Generic::TL::list<P1, FXTYPELIST12(P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13) >
00974 #define FXTYPELIST14(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14) \
00975 FX::Generic::TL::list<P1, FXTYPELIST13(P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14) >
00976 #define FXTYPELIST15(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15) \
00977 FX::Generic::TL::list<P1, FXTYPELIST14(P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15) >
00978 #define FXTYPELIST16(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16) \
00979 FX::Generic::TL::list<P1, FXTYPELIST15(P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16) >
00980
01013 template<typename fn> struct FnInfo
01014 {
01015 typedef fn resultType;
01016 typedef NullType objectType;
01017 static const bool isConst=false;
01018 static const int arity=-1;
01019 typedef typename TL::create<resultType>::value asList;
01020 };
01021 template<typename R, typename O> struct FnInfo<R (O::*)()>
01022 {
01023 typedef R resultType;
01024 typedef O objectType;
01025 static const bool isConst=false;
01026 static const int arity=0;
01027 typedef typename TL::create<resultType>::value asList;
01028 };
01029 template<typename R, typename O> struct FnInfo<R (O::*)() const>
01030 {
01031 typedef R resultType;
01032 typedef O objectType;
01033 static const bool isConst=true;
01034 static const int arity=0;
01035 typedef typename TL::create<resultType>::value asList;
01036 };
01037 template<typename R> struct FnInfo<R (*)(void)>
01038 {
01039 typedef R resultType;
01040 typedef NullType objectType;
01041 static const bool isConst=false;
01042 static const int arity=0;
01043 typedef typename TL::create<resultType>::value asList;
01044 };
01045 template<typename R, typename O, typename P1> struct FnInfo<R (O::*)(P1)>
01046 {
01047 typedef R resultType;
01048 typedef O objectType;
01049 typedef P1 par1Type;
01050 static const bool isConst=false;
01051 static const int arity=1;
01052 typedef typename TL::create<resultType, par1Type>::value asList;
01053 };
01054 template<typename R, typename O, typename P1> struct FnInfo<R (O::*)(P1) const>
01055 {
01056 typedef R resultType;
01057 typedef O objectType;
01058 typedef P1 par1Type;
01059 static const bool isConst=true;
01060 static const int arity=1;
01061 typedef typename TL::create<resultType, par1Type>::value asList;
01062 };
01063 template<typename R, typename P1> struct FnInfo<R (*)(P1)>
01064 {
01065 typedef R resultType;
01066 typedef NullType objectType;
01067 typedef P1 par1Type;
01068 static const bool isConst=false;
01069 static const int arity=1;
01070 typedef typename TL::create<resultType, par1Type>::value asList;
01071 };
01072 template<typename R, typename O, typename P1, typename P2> struct FnInfo<R (O::*)(P1, P2)>
01073 {
01074 typedef R resultType;
01075 typedef O objectType;
01076 typedef P1 par1Type;
01077 typedef P2 par2Type;
01078 static const bool isConst=false;
01079 static const int arity=2;
01080 typedef typename TL::create<resultType, par1Type, par2Type>::value asList;
01081 };
01082 template<typename R, typename O, typename P1, typename P2> struct FnInfo<R (O::*)(P1, P2) const>
01083 {
01084 typedef R resultType;
01085 typedef O objectType;
01086 typedef P1 par1Type;
01087 typedef P2 par2Type;
01088 static const bool isConst=true;
01089 static const int arity=2;
01090 typedef typename TL::create<resultType, par1Type, par2Type>::value asList;
01091 };
01092 template<typename R, typename P1, typename P2> struct FnInfo<R (*)(P1, P2)>
01093 {
01094 typedef R resultType;
01095 typedef NullType objectType;
01096 typedef P1 par1Type;
01097 typedef P2 par2Type;
01098 static const bool isConst=false;
01099 static const int arity=2;
01100 typedef typename TL::create<resultType, par1Type, par2Type>::value asList;
01101 };
01102 template<typename R, typename O, typename P1, typename P2, typename P3> struct FnInfo<R (O::*)(P1, P2, P3)>
01103 {
01104 typedef R resultType;
01105 typedef O objectType;
01106 typedef P1 par1Type;
01107 typedef P2 par2Type;
01108 typedef P3 par3Type;
01109 static const bool isConst=false;
01110 static const int arity=3;
01111 typedef typename TL::create<resultType, par1Type, par2Type, par3Type>::value asList;
01112 };
01113 template<typename R, typename O, typename P1, typename P2, typename P3> struct FnInfo<R (O::*)(P1, P2, P3) const>
01114 {
01115 typedef R resultType;
01116 typedef O objectType;
01117 typedef P1 par1Type;
01118 typedef P2 par2Type;
01119 typedef P3 par3Type;
01120 static const bool isConst=true;
01121 static const int arity=3;
01122 typedef typename TL::create<resultType, par1Type, par2Type, par3Type>::value asList;
01123 };
01124 template<typename R, typename P1, typename P2, typename P3> struct FnInfo<R (*)(P1, P2, P3)>
01125 {
01126 typedef R resultType;
01127 typedef NullType objectType;
01128 typedef P1 par1Type;
01129 typedef P2 par2Type;
01130 typedef P3 par3Type;
01131 static const bool isConst=false;
01132 static const int arity=3;
01133 typedef typename TL::create<resultType, par1Type, par2Type, par3Type>::value asList;
01134 };
01135 template<typename R, typename O, typename P1, typename P2, typename P3, typename P4> struct FnInfo<R (O::*)(P1, P2, P3, P4)>
01136 {
01137 typedef R resultType;
01138 typedef O objectType;
01139 typedef P1 par1Type;
01140 typedef P2 par2Type;
01141 typedef P3 par3Type;
01142 typedef P4 par4Type;
01143 static const bool isConst=false;
01144 static const int arity=4;
01145 typedef typename TL::create<resultType, par1Type, par2Type, par3Type, par4Type>::value asList;
01146 };
01147 template<typename R, typename O, typename P1, typename P2, typename P3, typename P4> struct FnInfo<R (O::*)(P1, P2, P3, P4) const>
01148 {
01149 typedef R resultType;
01150 typedef O objectType;
01151 typedef P1 par1Type;
01152 typedef P2 par2Type;
01153 typedef P3 par3Type;
01154 typedef P4 par4Type;
01155 static const bool isConst=true;
01156 static const int arity=4;
01157 typedef typename TL::create<resultType, par1Type, par2Type, par3Type, par4Type>::value asList;
01158 };
01159 template<typename R, typename P1, typename P2, typename P3, typename P4> struct FnInfo<R (*)(P1, P2, P3, P4)>
01160 {
01161 typedef R resultType;
01162 typedef NullType objectType;
01163 typedef P1 par1Type;
01164 typedef P2 par2Type;
01165 typedef P3 par3Type;
01166 typedef P4 par4Type;
01167 static const bool isConst=false;
01168 static const int arity=4;
01169 typedef typename TL::create<resultType, par1Type, par2Type, par3Type, par4Type>::value asList;
01170 };
01171 namespace FnFromListPrivate {
01172 template<typename list, int pars> struct impl;
01173 template<typename list> struct impl<list, 0> { typedef typename TL::at<list, 0>::value (*value)(); };
01174 template<typename list> struct impl<list, 1>
01175 { typedef typename TL::at<list, 0>::value (*value)(typename TL::at<list, 1>::value); };
01176 template<typename list> struct impl<list, 2>
01177 { typedef typename TL::at<list, 0>::value (*value)(typename TL::at<list, 1>::value, typename TL::at<list, 2>::value); };
01178 template<typename list> struct impl<list, 3>
01179 { typedef typename TL::at<list, 0>::value (*value)(typename TL::at<list, 1>::value, typename TL::at<list, 2>::value, typename TL::at<list, 3>::value); };
01180 template<typename list> struct impl<list, 4>
01181 { typedef typename TL::at<list, 0>::value (*value)(typename TL::at<list, 1>::value, typename TL::at<list, 2>::value, typename TL::at<list, 3>::value, typename TL::at<list, 4>::value); };
01182 }
01190 template<typename list> struct FnFromList
01191 {
01192 public:
01193 typedef typename FnFromListPrivate::impl<list, TL::length<list>::value-1>::value value;
01194 };
01195
01200 struct IntegralLists
01201 {
01203 typedef TL::create<unsigned char, FXushort, FXuint, unsigned long, FXulong>::value unsignedInts;
01205 typedef TL::create<signed char, FXshort, FXint, signed long, FXlong>::value signedInts;
01207 typedef TL::create<bool, char>::value otherInts;
01209 typedef TL::create<FXfloat, FXdouble>::value floats;
01210
01212 typedef TL::append<TL::append<unsignedInts, signedInts>::value, otherInts>::value Ints;
01214 typedef TL::append<TL::append<unsignedInts, signedInts>::value, floats>::value Arithmetical;
01216 typedef TL::append<signedInts, floats>::value Signeds;
01218 typedef TL::append<Ints, floats>::value All;
01219
01221 typedef TL::at<unsignedInts, 0>::value smallestUnsignedInt;
01223 typedef TL::at<signedInts, 0>::value smallestSignedInt;
01225 typedef TL::at<floats, 0>::value smallestFloat;
01227 typedef TL::at<unsignedInts, TL::length<unsignedInts>::value-1>::value biggestUnsignedInt;
01229 typedef TL::at<signedInts, TL::length<signedInts>::value-1>::value biggestSignedInt;
01231 typedef TL::at<floats, TL::length<floats>::value-1>::value biggestFloat;
01232 };
01233
01238 template<typename type, bool minus=false> struct BiggestValue
01239 {
01240 protected:
01241 static const int UnsignedIntIdx=TL::find<IntegralLists::unsignedInts, type>::value;
01242 static const int SignedIntIdx =TL::find<IntegralLists::signedInts, type>::value;
01243 static const int intIdx=(-1==UnsignedIntIdx) ? SignedIntIdx : UnsignedIntIdx;
01244 typedef typename TL::atC<IntegralLists::unsignedInts, intIdx>::value typeAsUnsigned;
01245 static const typeAsUnsigned maxUnsignedValue=(typeAsUnsigned)-1;
01246 static const typeAsUnsigned maxUnsignedValueL1=(typeAsUnsigned)((-1==UnsignedIntIdx) ? maxUnsignedValue<<1 : maxUnsignedValue);
01247 static const typeAsUnsigned maxSignedValue=(typeAsUnsigned)((-1==UnsignedIntIdx) ? maxUnsignedValueL1>>1 : maxUnsignedValue);
01248 public:
01249 static const type value=(type)(minus ? ~maxSignedValue : maxSignedValue);
01250 };
01255 template<typename type, bool minus=false> struct SmallestValue : public BiggestValue<type, minus>
01256 {
01257 static const type value=1;
01258 };
01259 template<typename type> struct SmallestValue<type, true> : public BiggestValue<type, true>
01260 {
01261 static const type value=(BiggestValue<type, true>::UnsignedIntIdx==-1) ? -1 : 1;
01262 };
01263 #if defined(_MSC_VER) && _MSC_VER<=1400
01264
01265 namespace Impl { namespace
01266 {
01267 template<typename type, bool minus> struct MSVCBiggestValue;
01268 template<typename type, bool minus> struct MSVCSmallestValue;
01269 template<> struct MSVCBiggestValue<float, false> { static float value; };
01270 template<> struct MSVCBiggestValue<float, true> { static float value; };
01271 template<> struct MSVCBiggestValue<double, false>{ static double value; };
01272 template<> struct MSVCBiggestValue<double, true> { static double value; };
01273 template<> struct MSVCSmallestValue<float, false> { static float value; };
01274 template<> struct MSVCSmallestValue<float, true> { static float value; };
01275 template<> struct MSVCSmallestValue<double, false>{ static double value; };
01276 template<> struct MSVCSmallestValue<double, true> { static double value; };
01277 float MSVCBiggestValue <float, false>::value=3.402823466e+38F;
01278 float MSVCBiggestValue <float, true>::value=-3.402823466e+38F;
01279 double MSVCBiggestValue <double, false>::value=1.7976931348623158e+308;
01280 double MSVCBiggestValue <double, true>::value=-1.7976931348623158e+308;
01281 float MSVCSmallestValue<float, false>::value=1.175494351e-38F;
01282 float MSVCSmallestValue<float, true>::value=-1.175494351e-38F;
01283 double MSVCSmallestValue<double, false>::value=2.2250738585072014e-308;
01284 double MSVCSmallestValue<double, true>::value=-2.2250738585072014e-308;
01285 } }
01286 template<bool minus> struct BiggestValue<float, minus> : public Impl::MSVCBiggestValue <float , minus> { };
01287 template<bool minus> struct BiggestValue<double, minus> : public Impl::MSVCBiggestValue <double, minus> { };
01288 template<bool minus> struct SmallestValue<float, minus> : public Impl::MSVCSmallestValue<float , minus> { };
01289 template<bool minus> struct SmallestValue<double, minus> : public Impl::MSVCSmallestValue<double, minus> { };
01290 #else
01291 template<> struct FXAPI BiggestValue<float, false>
01292 {
01293 static const float value;
01294 };
01295 template<> struct FXAPI BiggestValue<float, true>
01296 {
01297 static const float value;
01298 };
01299 template<> struct FXAPI BiggestValue<double, false>
01300 {
01301 static const double value;
01302 };
01303 template<> struct FXAPI BiggestValue<double, true>
01304 {
01305 static const double value;
01306 };
01307
01308 template<> struct FXAPI SmallestValue<float, false>
01309 {
01310 static const float value;
01311 };
01312 template<> struct FXAPI SmallestValue<float, true>
01313 {
01314 static const float value;
01315 };
01316 template<> struct FXAPI SmallestValue<double, false>
01317 {
01318 static const double value;
01319 };
01320 template<> struct FXAPI SmallestValue<double, true>
01321 {
01322 static const double value;
01323 };
01324 #endif
01325
01334 namespace ClassTraits
01335 {
01336 struct POD;
01342 template<class T1=NullType> struct combine
01343 {
01344 typedef typename TL::create<T1>::value pars;
01345 static const bool PODness=TL::find<pars, POD>::value>=0;
01346 };
01361 template<class type> struct has : public combine<> { };
01362 }
01426 namespace TraitsHelper
01427 {
01428 template<typename par> struct isVoidI { static const bool value=false; };
01429 template<> struct isVoidI<void> { static const bool value=true; };
01430 template<typename par> struct polyA : public par
01431 {
01432 char foo[64];
01433 };
01434 template<typename par> struct polyB : public par
01435 {
01436 char foo[64];
01437 virtual ~polyB() { }
01438 };
01439 template<bool isComplex, typename par> struct isPolymorphicI { static const bool value=false; };
01440 template<typename par> struct isPolymorphicI<true, par>
01441 {
01442 static const bool value=sizeof(polyA<par>)==sizeof(polyB<par>);
01443 };
01444 }
01445 template<typename type> class TraitsBasic
01446 {
01447 protected:
01448 template<typename par> struct isVoidI { static const bool value=TraitsHelper::isVoidI<par>::value; };
01449 template<typename par> struct isPtrI { static const bool value=false; };
01450 template<typename par> struct isPtrI<par *> { static const bool value=true; };
01451 template<typename par> struct isRefI { static const bool value=false; };
01452 template<typename par> struct isRefI<par &> { static const bool value=true; };
01453 template<typename par> struct isArrayI { static const bool value=false; };
01454 template<typename T, unsigned int len> struct isArrayI<T[len]> { static const bool value=true; };
01455 template<typename T, unsigned int len> struct isArrayI<T const[len]> { static const bool value=true; };
01456 template<typename T, unsigned int len> struct isArrayI<T volatile[len]> { static const bool value=true; };
01457 template<typename T, unsigned int len> struct isArrayI<T const volatile[len]> { static const bool value=true; };
01458 template<typename par> struct isConstI { static const bool value=false; };
01459 template<typename par> struct isConstI<const par> { static const bool value=true; };
01460 template<typename par> struct isVolatileI { static const bool value=false; };
01461 template<typename par> struct isVolatileI<volatile par> { static const bool value=true; };
01462 typedef FnInfo<type> fnInfo;
01463 template<bool wantConst, typename par> struct addConstI { typedef par value; };
01464 template<typename par> struct addConstI<true, par> { typedef const par value; };
01465 public:
01466 static const bool isVoid=isVoidI<type>::value;
01467 static const bool isPtr=isPtrI<type>::value;
01468 static const bool isRef=isRefI<type>::value;
01469 static const bool isPtrToCode=fnInfo::arity>=0;
01470 static const bool isMemberPtr=isPtrToCode && !sameType<typename fnInfo::objectType, NullType>::value;
01471 static const bool isFunctionPtr=isPtrToCode && sameType<typename fnInfo::objectType, NullType>::value;
01472 static const bool isValue=!isPtr && !isRef && !isPtrToCode;
01473 static const bool isIndirect=!isValue;
01474 static const bool isConst=isConstI<type>::value;
01475 static const bool isVolatile=isVolatileI<type>::value;
01476
01477 typedef typename leastIndir<type>::value baseType;
01478 static const bool isArray=isArrayI<baseType>::value;
01479 static const bool isFloat=TL::find<IntegralLists::floats, baseType>::value>=0;
01480 static const bool isInt=TL::find<IntegralLists::Ints, baseType>::value>=0;
01481 static const bool isSigned=TL::find<IntegralLists::Signeds, baseType>::value>=0;
01482 static const bool isUnsigned=TL::find<IntegralLists::unsignedInts, baseType>::value>=0;
01483 static const bool isArithmetical=TL::find<IntegralLists::Arithmetical, baseType>::value>=0;
01484 static const bool isIntegral=TL::find<IntegralLists::All, baseType>::value>=0;
01485 static const bool isBasic=isIntegral;
01486 static const bool holdsData=!isIntegral && !isPtrToCode;
01487
01488 static const bool isPOD=isBasic || ClassTraits::has<type>::PODness;
01489
01490 typedef typename select<isIntegral || isIndirect, type, typename addRef<type>::value >::value asRWParam;
01491 typedef typename addConstI<!isIntegral && !isRef, type>::value asConstParam;
01492 private:
01493 typedef typename TL::create<asRWParam, asConstParam, typename addRef<asConstParam>::value>::value ROParams;
01494 public:
01495 typedef typename TL::at<ROParams, ((isValue && isBasic) || isRef) ? 0 : (isIndirect) ? 1 : 2>::value asROParam;
01496 };
01497 template<typename type> class Traits : public TraitsBasic<type>
01498 {
01499 enum TestEnum {};
01500 template<bool isCodePtr, typename par> struct isEnumSizeI { static const bool value=false; };
01501 template<typename par> struct isEnumSizeI<false, par> { static const bool value=sizeof(TestEnum)==sizeof(par); };
01502 private:
01503 static const bool int_baseTypeIsVoid=TraitsHelper::isVoidI<typename TraitsBasic<type>::baseType>::value;
01504 static const bool int_isEnumSize=isEnumSizeI<TraitsBasic<type>::isPtrToCode || int_baseTypeIsVoid, typename TraitsBasic<type>::baseType>::value;
01505 static const bool int_isConvertibleToInt=!TraitsBasic<type>::isPtrToCode && convertible<int, typename TraitsBasic<type>::baseType>::value;
01506 public:
01507 static const bool isEnum=TraitsBasic<type>::holdsData && !TraitsBasic<type>::isArray && int_isEnumSize && int_isConvertibleToInt;
01508 static const bool isPolymorphic=TraitsHelper::isPolymorphicI<TraitsBasic<type>::holdsData && !TraitsBasic<type>::isArray && !isEnum && !int_baseTypeIsVoid, typename TraitsBasic<type>::baseType>::value;
01509 };
01510
01511
01512
01513
01514 namespace FunctorHelper {
01515 template<typename parslist> struct ImplBaseBase
01516 {
01517 typedef typename TL::at<parslist, 0>::value R;
01518 typedef typename TL::at<parslist, 1>::value P1base;
01519 typedef typename TraitsBasic<P1base>::asROParam P1;
01520 typedef typename TL::at<parslist, 2>::value P2base;
01521 typedef typename TraitsBasic<P2base>::asROParam P2;
01522 typedef typename TL::at<parslist, 3>::value P3base;
01523 typedef typename TraitsBasic<P3base>::asROParam P3;
01524 typedef typename TL::at<parslist, 4>::value P4base;
01525 typedef typename TraitsBasic<P4base>::asROParam P4;
01526 virtual ~ImplBaseBase() { }
01527 virtual ImplBaseBase *copy() const=0;
01528 };
01529 template<typename parslist, int pars> struct ImplBaseOp;
01530 template<typename parslist> struct ImplBaseOp<parslist, 0> : public ImplBaseBase<parslist>
01531 { virtual bool operator==(const ImplBaseOp &) const=0; virtual typename ImplBaseBase<parslist>::R operator()()=0; };
01532 template<typename parslist> struct ImplBaseOp<parslist, 1> : public ImplBaseBase<parslist>
01533 { virtual bool operator==(const ImplBaseOp &) const=0; virtual typename ImplBaseBase<parslist>::R operator()(typename ImplBaseBase<parslist>::P1 p1)=0; };
01534 template<typename parslist> struct ImplBaseOp<parslist, 2> : public ImplBaseBase<parslist>
01535 { virtual bool operator==(const ImplBaseOp &) const=0; virtual typename ImplBaseBase<parslist>::R operator()(typename ImplBaseBase<parslist>::P1 p1, typename ImplBaseBase<parslist>::P2 p2)=0; };
01536 template<typename parslist> struct ImplBaseOp<parslist, 3> : public ImplBaseBase<parslist>
01537 { virtual bool operator==(const ImplBaseOp &) const=0; virtual typename ImplBaseBase<parslist>::R operator()(typename ImplBaseBase<parslist>::P1 p1, typename ImplBaseBase<parslist>::P2 p2, typename ImplBaseBase<parslist>::P3 p3)=0; };
01538 template<typename parslist> struct ImplBaseOp<parslist, 4> : public ImplBaseBase<parslist>
01539 { virtual bool operator==(const ImplBaseOp &) const=0; virtual typename ImplBaseBase<parslist>::R operator()(typename ImplBaseBase<parslist>::P1 p1, typename ImplBaseBase<parslist>::P2 p2, typename ImplBaseBase<parslist>::P3 p3, typename ImplBaseBase<parslist>::P4 p4)=0; };
01540
01541 template<typename parentfunctor, typename fn> class ImplFn : public parentfunctor::ImplBase
01542 {
01543 typedef typename parentfunctor::ImplBase::R R;
01544 typedef typename parentfunctor::ImplBase::P1 P1;
01545 typedef typename parentfunctor::ImplBase::P2 P2;
01546 typedef typename parentfunctor::ImplBase::P3 P3;
01547 typedef typename parentfunctor::ImplBase::P4 P4;
01548 fn fnptr;
01549 public:
01550 ImplFn(fn _fnptr) : fnptr(_fnptr) { }
01551 ImplFn(const ImplFn &o) : fnptr(o.fnptr) { }
01552 ImplFn *copy() const { return new ImplFn(*this); }
01553 bool operator==(typename parentfunctor::ImplBase const &o) const { return fnptr==static_cast<const ImplFn &>(o).fnptr; }
01554 R operator()() { return fnptr(); }
01555 R operator()(P1 p1) { return fnptr(p1); }
01556 R operator()(P1 p1, P2 p2) { return fnptr(p1, p2); }
01557 R operator()(P1 p1, P2 p2, P3 p3) { return fnptr(p1, p2, p3); }
01558 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) { return fnptr(p1, p2, p3, p4); }
01559 };
01560 template<typename parentfunctor, class obj, typename fn> class ImplMemFn : public parentfunctor::ImplBase
01561 {
01562 typedef typename parentfunctor::ImplBase::R R;
01563 typedef typename parentfunctor::ImplBase::P1 P1;
01564 typedef typename parentfunctor::ImplBase::P2 P2;
01565 typedef typename parentfunctor::ImplBase::P3 P3;
01566 typedef typename parentfunctor::ImplBase::P4 P4;
01567 obj &objinst;
01568 fn fnptr;
01569 public:
01570 ImplMemFn(obj &_objinst, fn _fnptr) : objinst(_objinst), fnptr(_fnptr) { }
01571 ImplMemFn(const ImplMemFn &o) : objinst(o.objinst), fnptr(o.fnptr) { }
01572 ImplMemFn *copy() const { return new ImplMemFn(*this); }
01573 bool operator==(typename parentfunctor::ImplBase const &o) const { return &objinst==&static_cast<const ImplMemFn &>(o).objinst && fnptr==static_cast<const ImplMemFn &>(o).fnptr; }
01574 R operator()() { return (objinst.*fnptr)(); }
01575 R operator()(P1 p1) { return (objinst.*fnptr)(p1); }
01576 R operator()(P1 p1, P2 p2) { return (objinst.*fnptr)(p1, p2); }
01577 R operator()(P1 p1, P2 p2, P3 p3) { return (objinst.*fnptr)(p1, p2, p3); }
01578 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) { return (objinst.*fnptr)(p1, p2, p3, p4); }
01579 };
01580 }
01581
01605 template<typename parslist> class Functor
01606 {
01607 public:
01608 typedef typename FunctorHelper::ImplBaseOp<parslist, TL::length<parslist>::value-1> ImplBase;
01609 private:
01610 ImplBase *fnimpl;
01611 typedef typename FnFromList<parslist>::value ParsListAsFnType;
01612 public:
01613 typedef parslist ParsList;
01614 typedef typename ImplBase::R R;
01615 typedef typename ImplBase::P1 P1;
01616 typedef typename ImplBase::P2 P2;
01617 typedef typename ImplBase::P3 P3;
01618 typedef typename ImplBase::P4 P4;
01620 Functor() : fnimpl(0) { }
01622 template<typename fn> explicit Functor(fn fnptr) : fnimpl(0)
01623 { FXERRHM((fnimpl=new FunctorHelper::ImplFn<Functor, fn>(fnptr))); }
01625 template<typename obj, typename fn> Functor(obj &objinst, fn fnptr) : fnimpl(0)
01626 { FXERRHM((fnimpl=new FunctorHelper::ImplMemFn<Functor, obj, fn>(objinst, fnptr))); }
01628 template<typename obj, typename fn> Functor(obj *objinst, fn fnptr) : fnimpl(0)
01629 { FXERRHM((fnimpl=new FunctorHelper::ImplMemFn<Functor, obj, fn>(*objinst, fnptr))); }
01630 struct void_ {};
01633 Functor(void_ *fnptr) : fnimpl(0)
01634 { if(fnptr) FXERRHM((fnimpl=new FunctorHelper::ImplFn<Functor, ParsListAsFnType>((ParsListAsFnType) fnptr))); }
01636 explicit Functor(ImplBase *_fnimpl) : fnimpl(_fnimpl) { }
01637 #ifndef HAVE_CPP0XRVALUEREFS
01638 #ifdef HAVE_CONSTTEMPORARIES
01639 Functor(const Functor &other) : fnimpl(other.fnimpl)
01640 {
01641 Functor &o=const_cast<Functor &>(other);
01642 #else
01643 Functor(Functor &o) : fnimpl(o.fnimpl)
01644 {
01645 #endif
01646 #else
01647 private:
01648 Functor(const Functor &);
01649 public:
01650 Functor(Functor &&o) : fnimpl(std::move(o.fnimpl))
01651 {
01652 #endif
01653 o.fnimpl=0;
01654 }
01655 #ifndef HAVE_CPP0XRVALUEREFS
01656 Functor &operator=(Functor &o)
01657 #else
01658 Functor &&operator=(Functor &&o)
01659 #endif
01660 {
01661 FXDELETE(fnimpl);
01662 fnimpl=o.fnimpl;
01663 o.fnimpl=0;
01664 return *this;
01665 }
01666 ~Functor() { FXDELETE(fnimpl); }
01668 Functor copy() const
01669 {
01670 ImplBase *newimpl(static_cast<ImplBase *>(fnimpl->copy()));
01671 FXERRHM(newimpl);
01672 return Functor(newimpl);
01673 }
01675 bool operator==(const Functor &o) const { return *fnimpl==*o.fnimpl; }
01677 bool operator!=(const Functor &o) const { return !(*fnimpl==*o.fnimpl); }
01678
01679 private:
01680 struct Tester
01681 {
01682 private:
01683 void operator delete(void *);
01684 };
01685 public:
01686 operator Tester *() const
01687 {
01688 if(!*this) return 0;
01689 static Tester t;
01690 return &t;
01691 }
01692
01693 bool operator!() const { return !fnimpl; }
01695 R operator()() { return (*fnimpl)(); }
01697 R operator()(P1 p1) { return (*fnimpl)(p1); }
01699 R operator()(P1 p1, P2 p2) { return (*fnimpl)(p1, p2); }
01701 R operator()(P1 p1, P2 p2, P3 p3) { return (*fnimpl)(p1, p2, p3); }
01703 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) { return (*fnimpl)(p1, p2, p3, p4); }
01704 };
01710 class BoundFunctorV
01711 {
01712 virtual void callV()=0;
01713 protected:
01714 BoundFunctorV() {}
01715 BoundFunctorV(const BoundFunctorV &) {}
01716 BoundFunctorV &operator=(const BoundFunctorV &) { return *this; }
01717 public:
01718 virtual ~BoundFunctorV() { }
01720 void operator()() { callV(); }
01721 };
01722
01786 template<typename parslist> class BoundFunctor : public BoundFunctorV
01787 {
01788 typedef typename TL::at<parslist, 0>::value R;
01789 typedef typename TraitsBasic<typename TL::at<parslist, 1>::value>::asROParam P1;
01790 typedef typename TraitsBasic<typename TL::at<parslist, 2>::value>::asROParam P2;
01791 typedef typename TraitsBasic<typename TL::at<parslist, 3>::value>::asROParam P3;
01792 typedef typename TraitsBasic<typename TL::at<parslist, 4>::value>::asROParam P4;
01793 Functor<parslist> myfunctor;
01794 typedef typename parslist::next realparslist;
01795 TL::instantiateH<realparslist> parvals;
01796
01797
01798 R call(IntToType<0>) { return myfunctor(); }
01799 R call(IntToType<1>) { return myfunctor(TL::instance<0>(parvals).value); }
01800 R call(IntToType<2>) { return myfunctor(TL::instance<0>(parvals).value, TL::instance<1>(parvals).value); }
01801 R call(IntToType<3>) { return myfunctor(TL::instance<0>(parvals).value, TL::instance<1>(parvals).value, TL::instance<2>(parvals).value); }
01802 R call(IntToType<4>) { return myfunctor(TL::instance<0>(parvals).value, TL::instance<1>(parvals).value, TL::instance<2>(parvals).value, TL::instance<3>(parvals).value); }
01803 public:
01805 template<typename fn> BoundFunctor(fn fnptr, TL::instantiateH<realparslist> &_parvals)
01806 : myfunctor(fnptr), parvals(_parvals), BoundFunctorV() { }
01808 template<typename obj, typename fn> BoundFunctor(obj &objinst, fn fnptr, TL::instantiateH<realparslist> &_parvals)
01809 : myfunctor(objinst, fnptr), parvals(_parvals), BoundFunctorV() { }
01811 #if defined(__INTEL_COMPILER) && __INTEL_COMPILER<=800
01812
01813 BoundFunctor(const Functor<parslist> &_functor)
01814 {
01815 Functor<parslist> functor=_functor.copy();
01816 myfunctor=functor;
01817 #else
01818 BoundFunctor(const Functor<parslist> &_functor) : myfunctor(_functor.copy())
01819 {
01820 #endif
01821 }
01823 #if defined(__INTEL_COMPILER) && __INTEL_COMPILER<=800
01824
01825 BoundFunctor(const Functor<parslist> &_functor, P1 p1)
01826 {
01827 Functor<parslist> functor=_functor.copy();
01828 myfunctor=functor;
01829 #else
01830 BoundFunctor(const Functor<parslist> &_functor, P1 p1) : myfunctor(_functor.copy())
01831 {
01832 #endif
01833 TL::instance<0>(parvals).value=p1;
01834 }
01836 #if defined(__INTEL_COMPILER) && __INTEL_COMPILER<=800
01837
01838 BoundFunctor(const Functor<parslist> &_functor, P1 p1, P2 p2)
01839 {
01840 Functor<parslist> functor=_functor.copy();
01841 myfunctor=functor;
01842 #else
01843 BoundFunctor(const Functor<parslist> &_functor, P1 p1, P2 p2) : myfunctor(_functor.copy())
01844 {
01845 #endif
01846 TL::instance<0>(parvals).value=p1;
01847 TL::instance<1>(parvals).value=p2;
01848 }
01850 #if defined(__INTEL_COMPILER) && __INTEL_COMPILER<=800
01851
01852 BoundFunctor(const Functor<parslist> &_functor, P1 p1, P2 p2, P3 p3)
01853 {
01854 Functor<parslist> functor=_functor.copy();
01855 myfunctor=functor;
01856 #else
01857 BoundFunctor(const Functor<parslist> &_functor, P1 p1, P2 p2, P3 p3) : myfunctor(_functor.copy())
01858 {
01859 #endif
01860 TL::instance<0>(parvals).value=p1;
01861 TL::instance<1>(parvals).value=p2;
01862 TL::instance<2>(parvals).value=p3;
01863 }
01865 #if defined(__INTEL_COMPILER) && __INTEL_COMPILER<=800
01866
01867 BoundFunctor(const Functor<parslist> &_functor, P1 p1, P2 p2, P3 p3, P4 p4)
01868 {
01869 Functor<parslist> functor=_functor.copy();
01870 myfunctor=functor;
01871 #else
01872 BoundFunctor(const Functor<parslist> &_functor, P1 p1, P2 p2, P3 p3, P4 p4) : myfunctor(_functor.copy())
01873 {
01874 #endif
01875 TL::instance<0>(parvals).value=p1;
01876 TL::instance<1>(parvals).value=p2;
01877 TL::instance<2>(parvals).value=p3;
01878 TL::instance<3>(parvals).value=p4;
01879 }
01880 BoundFunctor(const BoundFunctor &o) : myfunctor(o.myfunctor.copy()), parvals(o.parvals), BoundFunctorV(o) { }
01881 BoundFunctor &operator=(const BoundFunctor &o)
01882 {
01883 myfunctor=o.myfunctor.copy();
01884 parvals=o.parvals;
01885 return *this;
01886 }
01888 Functor<parslist> &functor() { return myfunctor; }
01890 TL::instantiateH<realparslist> ¶meters() { return parvals; }
01892 R operator()() { return call(IntToType<TL::length<parslist>::value-1>()); }
01893 private:
01894 void callV() { (*this)(); }
01895
01896
01897
01898
01899
01900
01901
01902
01903 };
01904 #ifdef DOXYGEN_SHOULD_SKIP_THIS
01905
01908 BoundFunctor BindFunctor(FX::Generic::Functor &functor [, par1 [, par2 ...]]);
01912 BoundFunctor *BindFunctorN(FX::Generic::Functor &functor [, par1 [, par2 ...]]);
01913 #else
01914 template<typename F> BoundFunctor<typename F::ParsList>
01915 BindFunctor(F &functor)
01916 {
01917 return BoundFunctor<typename F::ParsList>(functor);
01918 }
01919 template<typename F> BoundFunctor<typename F::ParsList> *
01920 BindFunctorN(F &functor)
01921 {
01922 return new BoundFunctor<typename F::ParsList>(functor);
01923 }
01924 template<typename F> BoundFunctor<typename F::ParsList>
01925 BindFunctor(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1)
01926 {
01927 return BoundFunctor<typename F::ParsList>(functor, p1);
01928 }
01929 template<typename F> BoundFunctor<typename F::ParsList> *
01930 BindFunctorN(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1)
01931 {
01932 return new BoundFunctor<typename F::ParsList>(functor, p1);
01933 }
01934 template<typename F> BoundFunctor<typename F::ParsList>
01935 BindFunctor(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1,
01936 typename TraitsBasic<typename F::P2>::asROParam p2)
01937 {
01938 return BoundFunctor<typename F::ParsList>(functor, p1, p2);
01939 }
01940 template<typename F> BoundFunctor<typename F::ParsList> *
01941 BindFunctorN(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1,
01942 typename TraitsBasic<typename F::P2>::asROParam p2)
01943 {
01944 return new BoundFunctor<typename F::ParsList>(functor, p1, p2);
01945 }
01946 template<typename F> BoundFunctor<typename F::ParsList>
01947 BindFunctor(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1,
01948 typename TraitsBasic<typename F::P2>::asROParam p2, typename TraitsBasic<typename F::P3>::asROParam p3)
01949 {
01950 return BoundFunctor<typename F::ParsList>(functor, p1, p2, p3);
01951 }
01952 template<typename F> BoundFunctor<typename F::ParsList> *
01953 BindFunctorN(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1,
01954 typename TraitsBasic<typename F::P2>::asROParam p2, typename TraitsBasic<typename F::P3>::asROParam p3)
01955 {
01956 return new BoundFunctor<typename F::ParsList>(functor, p1, p2, p3);
01957 }
01958 template<typename F> BoundFunctor<typename F::ParsList>
01959 BindFunctor(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1,
01960 typename TraitsBasic<typename F::P2>::asROParam p2, typename TraitsBasic<typename F::P3>::asROParam p3,
01961 typename TraitsBasic<typename F::P4>::asROParam p4)
01962 {
01963 return BoundFunctor<typename F::ParsList>(functor, p1, p2, p3, p4);
01964 }
01965 template<typename F> BoundFunctor<typename F::ParsList> *
01966 BindFunctorN(F &functor, typename TraitsBasic<typename F::P1>::asROParam p1,
01967 typename TraitsBasic<typename F::P2>::asROParam p2, typename TraitsBasic<typename F::P3>::asROParam p3,
01968 typename TraitsBasic<typename F::P4>::asROParam p4)
01969 {
01970 return new BoundFunctor<typename F::ParsList>(functor, p1, p2, p3, p4);
01971 }
01972 #endif
01973 #ifdef DOXYGEN_SHOULD_SKIP_THIS
01974
01977 BoundFunctor<> BindFunc(functptr [, par1 [, par2 ...]]);
01981 BoundFunctor<> BindFuncN(functptr [, par1 [, par2 ...]]);
01985 BoundFunctor<> BindObj(obj &, memfunctptr [, par1 [, par2 ...]]);
01989 BoundFunctor<> BindObjN(obj &, memfunctptr [, par1 [, par2 ...]]);
01990 #else
01991 namespace Bind {
01992 template<int pars, typename fn> struct Impl
01993 {
01994 typedef typename FnInfo<fn>::asList fnspec;
01995 TL::instantiateH<typename fnspec::next> parvals;
01996 void checkParms()
01997 {
01998 FXSTATIC_ASSERT(TL::length<fnspec>::value-1==pars, Function_Spec_Not_Equal_To_Parameters_Specified);
01999 }
02000 Impl() {}
02001 template<typename P1> Impl(P1 p1)
02002 {
02003 TL::instance<0>(parvals).value=p1;
02004 }
02005 template<typename P1, typename P2> Impl(P1 p1, P2 p2)
02006 {
02007 TL::instance<0>(parvals).value=p1;
02008 TL::instance<1>(parvals).value=p2;
02009 }
02010 template<typename P1, typename P2, typename P3> Impl(P1 p1, P2 p2, P3 p3)
02011 {
02012 TL::instance<0>(parvals).value=p1;
02013 TL::instance<1>(parvals).value=p2;
02014 TL::instance<2>(parvals).value=p3;
02015 }
02016 template<typename P1, typename P2, typename P3, typename P4> Impl(P1 p1, P2 p2, P3 p3, P4 p4)
02017 {
02018 TL::instance<0>(parvals).value=p1;
02019 TL::instance<1>(parvals).value=p2;
02020 TL::instance<2>(parvals).value=p3;
02021 TL::instance<3>(parvals).value=p4;
02022 }
02023 };
02024 }
02025 template<typename fn> BoundFunctor<typename FnInfo<fn>::asList>
02026 BindFunc(fn fnptr)
02027 {
02028 typedef typename Bind::Impl<0, fn> Impl;
02029 Impl impl;
02030 return BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02031 }
02032 template<typename fn> BoundFunctor<typename FnInfo<fn>::asList> *
02033 BindFuncN(fn fnptr)
02034 {
02035 typedef typename Bind::Impl<0, fn> Impl;
02036 Impl impl;
02037 return new BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02038 }
02039 template<typename fn, typename P1> BoundFunctor<typename FnInfo<fn>::asList>
02040 BindFunc(fn fnptr, P1 p1)
02041 {
02042 typedef typename Bind::Impl<1, fn> Impl;
02043 Impl impl(p1);
02044 return BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02045 }
02046 template<typename fn, typename P1> BoundFunctor<typename FnInfo<fn>::asList> *
02047 BindFuncN(fn fnptr, P1 p1)
02048 {
02049 typedef typename Bind::Impl<1, fn> Impl;
02050 Impl impl(p1);
02051 return new BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02052 }
02053 template<typename fn, typename P1, typename P2> BoundFunctor<typename FnInfo<fn>::asList>
02054 BindFunc(fn fnptr, P1 p1, P2 p2)
02055 {
02056 typedef typename Bind::Impl<2, fn> Impl;
02057 Impl impl(p1, p2);
02058 return BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02059 }
02060 template<typename fn, typename P1, typename P2> BoundFunctor<typename FnInfo<fn>::asList> *
02061 BindFuncN(fn fnptr, P1 p1, P2 p2)
02062 {
02063 typedef typename Bind::Impl<2, fn> Impl;
02064 Impl impl(p1, p2);
02065 return new BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02066 }
02067 template<typename fn, typename P1, typename P2, typename P3> BoundFunctor<typename FnInfo<fn>::asList>
02068 BindFunc(fn fnptr, P1 p1, P2 p2, P3 p3)
02069 {
02070 typedef typename Bind::Impl<3, fn> Impl;
02071 Impl impl(p1, p2, p3);
02072 return BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02073 }
02074 template<typename fn, typename P1, typename P2, typename P3> BoundFunctor<typename FnInfo<fn>::asList> *
02075 BindFuncN(fn fnptr, P1 p1, P2 p2, P3 p3)
02076 {
02077 typedef typename Bind::Impl<3, fn> Impl;
02078 Impl impl(p1, p2, p3);
02079 return new BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02080 }
02081 template<typename fn, typename P1, typename P2, typename P3, typename P4> BoundFunctor<typename FnInfo<fn>::asList>
02082 BindFunc(fn fnptr, P1 p1, P2 p2, P3 p3, P4 p4)
02083 {
02084 typedef typename Bind::Impl<4, fn> Impl;
02085 Impl impl(p1, p2, p3, p4);
02086 return BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02087 }
02088 template<typename fn, typename P1, typename P2, typename P3, typename P4> BoundFunctor<typename FnInfo<fn>::asList> *
02089 BindFuncN(fn fnptr, P1 p1, P2 p2, P3 p3, P4 p4)
02090 {
02091 typedef typename Bind::Impl<3, fn> Impl;
02092 Impl impl(p1, p2, p3, p4);
02093 return new BoundFunctor<typename Impl::fnspec>(fnptr, impl.parvals);
02094 }
02095 template<typename obj, typename fn> BoundFunctor<typename FnInfo<fn>::asList>
02096 BindObj(obj &objinst, fn fnptr)
02097 {
02098 typedef typename Bind::Impl<0, fn> Impl;
02099 Impl impl;
02100 return BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02101 }
02102 template<typename obj, typename fn> BoundFunctor<typename FnInfo<fn>::asList> *
02103 BindObjN(obj &objinst, fn fnptr)
02104 {
02105 typedef typename Bind::Impl<0, fn> Impl;
02106 Impl impl;
02107 return new BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02108 }
02109 template<typename obj, typename fn, typename P1> BoundFunctor<typename FnInfo<fn>::asList>
02110 BindObj(obj &objinst, fn fnptr, P1 p1)
02111 {
02112 typedef typename Bind::Impl<1, fn> Impl;
02113 Impl impl(p1);
02114 return BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02115 }
02116 template<typename obj, typename fn, typename P1> BoundFunctor<typename FnInfo<fn>::asList> *
02117 BindObjN(obj &objinst, fn fnptr, P1 p1)
02118 {
02119 typedef typename Bind::Impl<1, fn> Impl;
02120 Impl impl(p1);
02121 return new BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02122 }
02123 template<typename obj, typename fn, typename P1, typename P2> BoundFunctor<typename FnInfo<fn>::asList>
02124 BindObj(obj &objinst, fn fnptr, P1 p1, P2 p2)
02125 {
02126 typedef typename Bind::Impl<2, fn> Impl;
02127 Impl impl(p1, p2);
02128 return BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02129 }
02130 template<typename obj, typename fn, typename P1, typename P2> BoundFunctor<typename FnInfo<fn>::asList> *
02131 BindObjN(obj &objinst, fn fnptr, P1 p1, P2 p2)
02132 {
02133 typedef typename Bind::Impl<2, fn> Impl;
02134 Impl impl(p1, p2);
02135 return new BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02136 }
02137 template<typename obj, typename fn, typename P1, typename P2, typename P3> BoundFunctor<typename FnInfo<fn>::asList>
02138 BindObj(obj &objinst, fn fnptr, P1 p1, P2 p2, P3 p3)
02139 {
02140 typedef typename Bind::Impl<3, fn> Impl;
02141 Impl impl(p1, p2, p3);
02142 return BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02143 }
02144 template<typename obj, typename fn, typename P1, typename P2, typename P3> BoundFunctor<typename FnInfo<fn>::asList> *
02145 BindObjN(obj &objinst, fn fnptr, P1 p1, P2 p2, P3 p3)
02146 {
02147 typedef typename Bind::Impl<3, fn> Impl;
02148 Impl impl(p1, p2, p3);
02149 return new BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02150 }
02151 template<typename obj, typename fn, typename P1, typename P2, typename P3, typename P4> BoundFunctor<typename FnInfo<fn>::asList>
02152 BindObj(obj &objinst, fn fnptr, P1 p1, P2 p2, P3 p3, P4 p4)
02153 {
02154 typedef typename Bind::Impl<4, fn> Impl;
02155 Impl impl(p1, p2, p3, p4);
02156 return BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02157 }
02158 template<typename obj, typename fn, typename P1, typename P2, typename P3, typename P4> BoundFunctor<typename FnInfo<fn>::asList> *
02159 BindObjN(obj &objinst, fn fnptr, P1 p1, P2 p2, P3 p3, P4 p4)
02160 {
02161 typedef typename Bind::Impl<4, fn> Impl;
02162 Impl impl(p1, p2, p3, p4);
02163 return new BoundFunctor<typename Impl::fnspec>(objinst, fnptr, impl.parvals);
02164 }
02165 #endif
02166
02167 namespace TL
02168 {
02169 namespace dynamicAtHelper
02170 {
02171 template<typename fnspeclist, typename typelist, template<class> class instance> struct Impl
02172 {
02173 typedef typename FnFromList<fnspeclist>::value fnspec;
02174 static fnspec getArray(FXuint idx)
02175 {
02176 FXSTATIC_ASSERT(length<typelist>::value<=16, DynamicAt_Maximum_Exceeded);
02177 typedef instance<NullType> nullinst;
02178 if(idx>=length<typelist>::value)
02179 return &nullinst::Do;
02180 typedef typename apply<typelist, instance>::value instancedtypelist;
02181 typedef typename replicate<16-length<typelist>::value, instance<NullType> >::value instancedtypelistend;
02182 typedef typename append<instancedtypelist, instancedtypelistend>::value atypelist;
02183
02184 static const fnspec mytable[16]={
02185 &at<atypelist, 0>::value::Do, &at<atypelist, 1>::value::Do,
02186 &at<atypelist, 2>::value::Do, &at<atypelist, 3>::value::Do,
02187 &at<atypelist, 4>::value::Do, &at<atypelist, 5>::value::Do,
02188 &at<atypelist, 6>::value::Do, &at<atypelist, 7>::value::Do,
02189 &at<atypelist, 8>::value::Do, &at<atypelist, 9>::value::Do,
02190 &at<atypelist, 10>::value::Do, &at<atypelist, 11>::value::Do,
02191 &at<atypelist, 12>::value::Do, &at<atypelist, 13>::value::Do,
02192 &at<atypelist, 14>::value::Do, &at<atypelist, 15>::value::Do
02193 };
02194 return mytable[idx];
02195 }
02196 };
02197 }
02226 template<typename typelist, template<class> class instance> struct dynamicAt
02227 {
02228 static const FXuint MaxEntries=16;
02229 static const FXuint DisableMagicIdx=1<<28;
02230
02231 dynamicAt(FXuint idx)
02232 {
02233 typedef typename create<void>::value parslist;
02234 if(DisableMagicIdx!=idx)
02235 dynamicAtHelper::Impl<parslist, typelist, instance>::getArray(idx)();
02236 }
02238 template<typename P1> dynamicAt(FXuint idx, P1 p1)
02239 {
02240 typedef typename create<void, P1>::value parslist;
02241 if(DisableMagicIdx!=idx)
02242 dynamicAtHelper::Impl<parslist, typelist, instance>::getArray(idx)(p1);
02243 }
02245 template<typename P1, typename P2> dynamicAt(FXuint idx, P1 p1, P2 p2)
02246 {
02247 typedef typename create<void, P1, P2>::value parslist;
02248 if(DisableMagicIdx!=idx)
02249 dynamicAtHelper::Impl<parslist, typelist, instance>::getArray(idx)(p1,p2);
02250 }
02252 template<typename P1, typename P2, typename P3> dynamicAt(FXuint idx, P1 p1, P2 p2, P3 p3)
02253 {
02254 typedef typename create<void, P1, P2, P3>::value parslist;
02255 if(DisableMagicIdx!=idx)
02256 dynamicAtHelper::Impl<parslist, typelist, instance>::getArray(idx)(p1,p2,p3);
02257 }
02259 template<typename P1, typename P2, typename P3, typename P4> dynamicAt(FXuint idx, P1 p1, P2 p2, P3 p3, P4 p4)
02260 {
02261 typedef typename create<void, P1, P2, P3, P4>::value parslist;
02262 if(DisableMagicIdx!=idx)
02263 dynamicAtHelper::Impl<parslist, typelist, instance>::getArray(idx)(p1,p2,p3,p4);
02264 }
02265
02266 };
02267 }
02268
02285 template<int len> struct MapBools
02286 {
02287 FXSTATIC_ASSERT2(len<=sizeof(FXulong)*8, ERROR_Too_Many_Bools_To_Fit_Into_Integral_Type);
02288 typedef typename Generic::select<(len>sizeof(FXuchar)*8),
02289 typename Generic::select<(len>sizeof(FXushort)*8),
02290 typename Generic::select<(len>sizeof(FXuint)*8),
02291 FXulong,
02292 FXuint>::value,
02293 FXushort>::value,
02294 FXuchar>::value
02295 holdtype;
02296 bool *base;
02297 MapBools(const bool *_base) throw() : base(const_cast<bool *>(_base)) { }
02298
02299
02300 friend inline FXStream &operator<<(FXStream &s, const MapBools<len> i) throw()
02301 {
02302 holdtype val=0;
02303 for(int n=len-1; n>=0; n--)
02304 {
02305 val=(val<<1)|((FXuchar)i.base[n]);
02306 }
02307 s << val;
02308 return s;
02309 }
02310 friend inline FXStream &operator>>(FXStream &s, MapBools<len> i) throw()
02311 {
02312 holdtype val; s >> val;
02313 for(int n=0; n<len; n++)
02314 {
02315 i.base[n]=(bool)(val & 1); val>>=1;
02316 }
02317 return s;
02318 }
02319 };
02320
02343 template<class obj=NullType, typename doaddr=NullType, typename undoaddr=NullType> class DoUndo
02344 {
02345 bool done;
02346 obj *instance;
02347 doaddr doa;
02348 undoaddr undoa;
02349 public:
02351 DoUndo(obj *_instance, doaddr _doa, undoaddr _undoa) : done(false), instance(_instance), doa(_doa), undoa(_undoa) { redo(); }
02353 ~DoUndo() { undo(); }
02355 void undo()
02356 {
02357 if(done)
02358 {
02359 (*instance.*undoa)();
02360 done=false;
02361 }
02362 }
02364 void redo()
02365 {
02366 if(!done)
02367 {
02368 (*instance.*doa)();
02369 done=true;
02370 }
02371 }
02372 };
02373 template<typename doaddr, typename undoaddr> class DoUndo<void, doaddr, undoaddr>
02374 {
02375 bool done;
02376 doaddr doa;
02377 undoaddr undoa;
02378 public:
02379 DoUndo(doaddr _doa, undoaddr _undoa) : done(false), doa(_doa), undoa(_undoa) { redo(); }
02380 ~DoUndo() { undo(); }
02381 void undo()
02382 {
02383 if(done)
02384 {
02385 (undoa)();
02386 done=false;
02387 }
02388 }
02389 void redo()
02390 {
02391 if(!done)
02392 {
02393 (doa)();
02394 done=true;
02395 }
02396 }
02397 };
02398 template<> class DoUndo<NullType, NullType, NullType>
02399 {
02400 bool done;
02401 BoundFunctorV *do_, *undo_;
02402 public:
02403 DoUndo(BoundFunctorV *_do_, BoundFunctorV *_undo_)
02404 : done(false), do_(_do_), undo_(_undo_) { redo(); }
02405 ~DoUndo() { undo(); FXDELETE(do_); FXDELETE(undo_); }
02406 void undo()
02407 {
02408 if(done)
02409 {
02410 (*undo_)();
02411 done=false;
02412 }
02413 }
02414 void redo()
02415 {
02416 if(!done)
02417 {
02418 (*do_)();
02419 done=true;
02420 }
02421 }
02422 };
02423
02424 }
02425
02438 #define FXAutoPtr FX::Generic::ptr // TODO: FIXME when templated typedefs get implemented
02439
02459 #if defined(WIN32) && defined(UNICODE)
02460 template<size_t fastlen=2048> class FXUnicodify
02461 {
02462 bool myIsPath;
02463 FXnchar stkbuff[fastlen], *mybuffer;
02464 FXAutoPtr<FXnchar> membuff;
02465 FXint bufflen;
02466 void doConv(const FXString &_str)
02467 {
02468 FXString str(_str);
02469 if(myIsPath)
02470 {
02471 str=FXPath::absolute(str);
02472 str.prepend("\\\\?\\");
02473
02474 str.substitute('/', '\\');
02475 }
02476 FXint strlen=str.length()+1;
02477 if(strlen>sizeof(stkbuff))
02478 FXERRHM(membuff=mybuffer=new FXnchar[strlen]);
02479 else mybuffer=stkbuff;
02480 bufflen=utf2ncs(mybuffer, str.text(), strlen)*sizeof(FXnchar);
02481 }
02482 public:
02484 FXUnicodify(bool isPath=false) : myIsPath(isPath), mybuffer(0), bufflen(0) { }
02486 FXUnicodify(const FXString &str, bool isPath=false) : myIsPath(isPath), mybuffer(0), bufflen(0) { doConv(str); }
02488 const FXnchar *buffer() const throw() { return mybuffer; }
02490 const FXnchar *buffer(const FXString &str) { if(!mybuffer) doConv(str); return mybuffer; }
02492 FXint length() const throw() { return bufflen; }
02494 FXint length(const FXString &str) { if(!mybuffer) doConv(str); return bufflen; }
02495 };
02496 #else
02497 template<size_t fastlen=2048> class FXUnicodify
02498 {
02499 const FXchar *mybuffer;
02500 FXint bufflen;
02501 public:
02502 FXUnicodify(bool isPath=false) : mybuffer(0) { }
02503 FXUnicodify(const FXString &str, bool isPath=false) : mybuffer(str.text()), bufflen(str.length()) { }
02504 const FXchar *buffer() const throw() { return mybuffer; }
02505 const FXchar *buffer(const FXString &str) const throw() { return str.text(); }
02506 FXint length() const throw() { return bufflen; }
02507 FXint length(const FXString &str) const throw() { return str.length(); }
02508 };
02509 #endif
02510
02511 }
02512
02513 #endif