classTraits.h

Go to the documentation of this file.
00001 #ifndef classTraits_header_included_p
00002 #define classTraits_header_included_p
00003 //
00004 // Copyright 2008, Lowell Boggs Jr.
00005 //
00006 // This file or directory, containing source code for a computer program,
00007 // is Copyrighted by Lowell Boggs, Jr.  987 Regency Drive, Lewisville
00008 // TX (USA), 75067.  You may use, copy, modify, and distribute this
00009 // source file without charge or obligation so long as you agree to
00010 // the following:
00011 //
00012 //  1.  You must indemnify Lowell Boggs against any and all financial
00013 //      obligations caused by its use, misuse, function, or malfunction.
00014 //      Further, you acknowledge that there is no warranty of any kind,
00015 //      whatsoever.
00016 //
00017 //  2.  You agree not to attempt to patent any portion of this original
00018 //      work -- though you may attempt to patent your own extensions to
00019 //      it if you so choose.
00020 //
00021 //  3.  You keep this copyright notice with the file and all copies
00022 //      of the file and do not change it anyway except language translation.
00023 //
00024 // You are responsible for enforcing your own compliance with these
00025 // conditions and may not use this source file if you cannot agree to the
00026 // above terms and conditions.
00027 //
00028 // Warning:  not all files in this directory structure are covered by the
00029 // same copyright.  Some of them are part of the GNU source distribution
00030 // and you must obey the GPL copyright for those files.  Specifically the
00031 // "guts" of the is_polymorphic<T> mechanism comes from boost -- although
00032 // I do feel like an idiot for not having thought of it myself.  Ok, after
00033 // careful consideration of exactly how the algorithm works, including the
00034 // _selector mechanism, which is a work of genius (appearing in the STL)
00035 // I no longer feel like an idiot.  Whether I am or not, is an exercise left
00036 // to the observer...
00037 
00047 
00048 
00049 #include <memory>  // to get size_t
00050 
00051 namespace cxxtls
00052 {
00053 
00054 // And now to the class type traits helpers...
00055 
00056 //
00057 // the true and false types exist only to aid in template function selection.
00058 //
00059 //  Basically you can include a nested typedef like this in your own class:
00060 //
00061 //   typedef true_value_type  flagType;
00062 //
00063 //  Then when templates are instantiated using your class, they can look at the flag type
00064 //  and make decisions as to whether flagType is typedef'd to true_value_type or false_value_type.
00065 //
00066 
00067 struct true_value_type 
00073 {
00074   typedef true_value_type type;
00075 
00076   enum constants { value = 1 };              // compile time constant usable in EvalTypeIf
00077                                              // or regular code.
00078 };
00079 
00080 struct false_value_type 
00086 {
00087   typedef false_value_type type;
00088 
00089   enum constants { value = 0 };              // compile time constant usable in EvalTypeIf
00090                                              // or regular code.
00091 };
00092 
00093 struct not_a_type{};  // a type that represents "not a type"
00094 
00095 template<bool, class ZeroClass, class OneClass> 
00096 struct  EvalTypeIf
00165 {
00166   // the default implementation is unusable.
00167 };
00168 
00169 template<class ZeroClass, class OneClass> 
00170 struct  EvalTypeIf<0, ZeroClass, OneClass>
00171 {
00172   typedef ZeroClass type;  // the false case:
00173 };
00174 
00175 template<class ZeroClass, class OneClass> 
00176 struct  EvalTypeIf<1, ZeroClass, OneClass>
00177 {
00178   typedef OneClass type;  // the true case
00179 };
00180 
00181 template<class T, class U>
00182 struct isSameType
00210 {
00211   // neither of these functions is ever called or instantiated
00212 
00213   template<class V> static char is_same_type_func(V&,V&);  // this one only takes a pair of ptrs
00214                                                            // which are equal
00215   static int is_same_type_func(...);                       // this one takes any number of any type
00216 
00217   static T t;
00218   static U u;
00219 
00220   // if the two types of template parms are the same, the first func will be called  in the
00221   // following constant expression -- except that it won't ACTUALLY be called
00222 
00223   enum { value =    (sizeof( is_same_type_func(t,u) ) == sizeof(char))
00224                  && (sizeof( is_same_type_func(u,t) ) == sizeof(char))
00225        };
00226 
00227 };
00228 
00229 
00230 template<class T>
00231 struct isConstType
00254 {
00255   typedef T type;
00256 
00257   typedef false_value_type valueType; 
00258 
00259   enum constants { value = 0 };
00260 
00261 };
00262 
00263 template<class T>
00264 struct isConstType<const T>
00265 {
00266   typedef T type; // for const, remove the const
00267 
00268   enum constants { value = 1 };
00269 
00270   typedef true_value_type valueType; 
00271 
00272 };
00273 
00274 template<class T>
00275 struct removeConst
00299 {
00300   typedef typename isConstType<T>::type type;
00301 };
00302 
00303 
00304 
00305 template<class T>
00306 struct removeVolatile
00330 {
00331   typedef T type; // for non-volatle, just use the class 
00332 };
00333 
00334 
00335 template<class T>
00336 struct removeVolatile<volatile T>
00337 {
00338   typedef T type; // for volatile, remove it
00339 };
00340 
00341 template<class T>
00342 struct removeCV
00347 {
00348   typedef typename removeConst< typename removeVolatile<T>::type >::type type;
00349 };
00350 
00351 //
00352 //  removeReference<T>  has a member, type, which is T without the &, if any
00353 //
00354 
00355 template<class U> struct removeReference_impl { typedef U type; };
00356 template<class V> struct removeReference_impl <V&> { typedef V type; };
00357 
00358 template<class T>
00359 struct removeReference
00364 {
00365 
00366   typedef typename removeReference_impl<T>::type type; 
00367 
00368 };
00369 
00370 
00371 
00372 //
00373 // template isConvertibleType<FromType, ToType> tells you whether or not
00374 // FromType is assignment compatible with ToType, that is, can you construct a
00375 // ToType object from a FromType object.
00376 //
00377 
00378 
00379 template<class From, class To>
00380 struct isConvertibleType
00389 {
00390    // these functions and variables are never instantiated
00391 
00392    static char f(...);  // this function will take anything as a parm
00393    static int  f(To); // this function will only take a ToType object as a parm
00394 
00395    // note that the f(...) and f(To&) forms return different data types.  
00396 
00397    static From fromp;  
00398    static To   top;
00399 
00400    // The following code defines a constant named "value" whose value is defined
00401    // by the size of the data that would be returned by one of the two 'f' overloads
00402    // above.  No actual call is made, but the compiler can tell which of the two
00403    // overloaded forms WOULD be called with the given arguments and thus it can tell
00404    // the return type -- and thus you can take the size thereof and compare the size of
00405    // the returned value of the two different function calls.
00406    //
00407    // 
00408    // If the from and two classes are assignment compatible then the f(To&) form will
00409    // be called.  If they are not, then different functions will be called -- and thus
00410    // the size of the return value will be different.  Of course, they are not REALLY called
00411    // only evaluated for call...
00412 
00413    enum constants
00414    {
00415      value = sizeof( f(fromp) ) ==  sizeof( f(top) )
00416    };
00417 
00418 
00419 };
00420 
00421 template<class To>
00422 struct isConvertibleType<void, To>
00424 {
00425   enum { value = false };
00426 };
00427 template<class To>
00428 struct isConvertibleType<const void, To>
00430 {
00431   enum { value = false };
00432 };
00433 
00434 template<>
00435 struct isConvertibleType<float, int>
00436 {
00437   enum { value = true };
00438 };
00439 template<>
00440 struct isConvertibleType<const float, int>
00441 {
00442   enum { value = true };
00443 };
00444 template<>
00445 struct isConvertibleType<double, int>
00446 {
00447   enum { value = true };
00448 };
00449 template<>
00450 struct isConvertibleType<const double, int>
00451 {
00452   enum { value = true };
00453 };
00454 template<>
00455 struct isConvertibleType<long double, int>
00456 {
00457   enum { value = true };
00458 };
00459 template<>
00460 struct isConvertibleType<const long double, int>
00461 {
00462   enum { value = true };
00463 };
00464 
00465 
00466 
00467 template<class Type>
00468 struct isClassType
00473 {
00474   
00475   template <typename ClassType>
00476   static short fun(void (ClassType::*)());
00477   
00478   template <typename NonClassType>   // this has to be a template
00479   static char fun(...);
00480 
00481   enum { value = sizeof(fun<Type>(0)) == sizeof(short) };
00482 };
00483 
00484 
00485 template<class T>
00486 struct isFunctionType
00491 {
00492   // works on functions up to 9 parameters -- feel free to add more
00493 
00494   template<class RV> static char f(RV (*func0)());
00495   template<class RV, class A> static char f(RV (*func1)(A));
00496   template<class RV, class A, class B> static char f(RV (*func2)(A, B));
00497   template<class RV, class A, class B, class C> static char f(RV (*func3)(A, B, C));
00498   template<class RV, class A, class B, class C, class D> static char f(RV (*func4)(A, B, C, D));
00499   template<class RV, class A, class B, class C, class D, class E> static char f(RV (*func5)(A, B, C, D, E));
00500   template<class RV, class A, class B, class C, class D, class E, class F> static char f(RV (*func6)(A, B, C, D, E, F));
00501   template<class RV, class A, class B, class C, class D, class E, class F, class G> static char f(RV (*func7)(A, B, C, D, E, F, G));
00502   template<class RV, class A, class B, class C, class D, class E, class F, class G, class H> static char f(RV (*func8)(A, B, C, D, E, F, G, H));
00503   template<class RV, class A, class B, class C, class D, class E, class F, class G, class H, class I> static char f(RV (*func9)(A, B, C, D, E, F, G, H, I));
00504 
00505   static int f(...);
00506 
00507   static T t;
00508 
00509   enum { value = sizeof(char) == sizeof( f(t) ) };
00510 
00511 };
00512 
00513 template<>
00514 struct isFunctionType<void>
00515 {
00516   enum { value = false };
00517 };
00518 
00519 template<>
00520 struct isFunctionType<const void>
00521 {
00522   enum { value = false };
00523 };
00524 
00525 
00526 
00527 template<class T>
00528 struct isPointerType
00534 {
00535   enum constants { value = 0 };
00536 };
00537 
00538 template<class T>
00539 struct isPointerType<T*>
00540 {
00541   enum constants { value = 1 };
00542 };
00543 
00544 template<class T>
00545 struct isPointerType<T const*>
00546 {
00547   enum constants { value = 1 };
00548 };
00549 
00550 template<class T>
00551 struct isPointerType<T* const>
00552 {
00553   enum constants { value = 1 };
00554 };
00555 
00556 template<class T>
00557 struct isPointerType<T const* const>
00558 {
00559   enum constants { value = 1 };
00560 };
00561 
00562 template<class T, size_t N>
00563 struct isPointerType<T [N]>
00564 {
00565   enum constants { value = 1 };
00566 };
00567 
00568 template<class T, size_t N>
00569 struct isPointerType<T const [N]>
00570 {
00571   enum constants { value = 1 };
00572 };
00573 
00574 template<class T>
00575 struct isArrayType
00579 {
00580    enum constants { value = 0 }; 
00581 };
00582 
00583 
00584 template<class T, size_t N>
00585 struct isArrayType<T [N]>
00589 {
00590   enum constants { value = 1 };
00591 };
00592 
00593 template<class T, size_t N>
00594 struct isArrayType<T const [N]>
00598 {
00599   enum constants { value = 1 };
00600 };
00601 
00602 
00603 
00604 //
00605 //  typename pointerReferent<T>::type is a type gives you the base type from a pointer type.
00606 //
00607 //  non-pointers are their own pointee type
00608 
00609 
00610 template<class T>
00611 struct pointerReferent
00617 {
00618   typedef T type; // non-pointers should not cause compile errors since you can use isPointer
00619                   // at run time to tell if it really is a pointer or not
00620 };
00621 
00622 template<class T>
00623 struct pointerReferent<T*>
00625 {
00626   typedef T type;
00627 };
00628 
00629 template<class T>
00630 struct pointerReferent<T const*>
00632 {
00633   typedef T const type;
00634 };
00635 
00636 template<class T, size_t N>
00638 struct pointerReferent<T [N]>
00639 {
00640   typedef T type;
00641 };
00642 
00643 template<class T, size_t N>
00644 struct pointerReferent<T const [N]>
00646 {
00647   typedef T const type;
00648 };
00649 
00650 
00651 template<class T>struct ispodtype_impl: public false_value_type {};  
00655 
00656 
00657 // only the following are pod:
00658 
00659 template<class T> struct ispodtype_impl<T*>          : public true_value_type {}; 
00660 template<class T> struct ispodtype_impl<T* const>    : public true_value_type {}; 
00661 template<> struct ispodtype_impl<char>               : public true_value_type {}; 
00662 template<> struct ispodtype_impl<short>              : public true_value_type {}; 
00663 template<> struct ispodtype_impl<int>                : public true_value_type {}; 
00664 template<> struct ispodtype_impl<long>               : public true_value_type {}; 
00665 template<> struct ispodtype_impl<long long>          : public true_value_type {}; 
00666 template<> struct ispodtype_impl<unsigned char>      : public true_value_type {}; 
00667 template<> struct ispodtype_impl<unsigned short>     : public true_value_type {}; 
00668 template<> struct ispodtype_impl<unsigned int>       : public true_value_type {}; 
00669 template<> struct ispodtype_impl<unsigned long long> : public true_value_type {}; 
00670 template<> struct ispodtype_impl<float>              : public true_value_type {}; 
00671 template<> struct ispodtype_impl<double>             : public true_value_type {}; 
00672 
00673 // arrays are pod
00674 
00675 
00676 template<class T>
00677 struct isPodType
00683 {
00684   enum { value = ispodtype_impl<T>::value || isConvertibleType<T,int>::value || isFunctionType<T>::value };
00685 };
00686 
00687 template<class T, size_t N> struct ispodtype_impl<T [N]> : public isPodType<T> {};  
00688 
00689 
00690 //
00691 //  The isPolymorphicType<T> template lets you find out if a class has virtual methods.
00692 //  Note that its purpose is to define nested class members which give you information
00693 //  about T -- is it polymorphic or not.
00694 //
00695 
00696 
00697 
00698 template <class plainT>
00699 struct isPolymorphicType_impl
00700   //
00701   //  This definition handles non-POD types
00702   //
00703 {
00704   // to tell if a data type is polymorphic, you check to see if it has a virtual
00705   // function table.  The way you tell that is to derive new classes from it.  You
00706   // derive a new class with a new virtual method and a different class without any
00707   // new virtual methods.  If if sizeof the new types is equal then you know that the
00708   // base class has virtual methods to start with, but if the sizes are not the same
00709   // then the it was not originally polymorphic.
00710 
00711 
00712    struct d1 : public plainT
00713    {
00714       d1();
00715       ~d1()throw();
00716       char padding[256];
00717    };
00718 
00719    struct d2 : public plainT
00720    {
00721       d2();
00722       virtual ~d2() throw();
00723       char padding[256];
00724    };
00725 
00726    enum constants { value = sizeof(d1) == sizeof(d2) };
00727 
00728    typedef typename EvalTypeIf<value, false_value_type, true_value_type>::type type;
00729 
00730    operator bool() const { return value; }
00731 
00732 };
00733 
00751 
00752 template <bool is_class>
00753 struct isPolymorphicType_selector
00754 {
00755   // non-class case
00756 
00757    template <class T>
00758    struct rebind
00759    {
00760       typedef false_value_type type;
00761    };
00762 };
00763 
00764 template<>
00765 struct isPolymorphicType_selector<true>
00766 {
00767   // isClassType case
00768 
00769    template <class T>
00770    struct rebind
00771    {
00772       typedef isPolymorphicType_impl<T> type;
00773    };
00774 };
00775 
00776 template <class T>
00777 struct isPolymorphicType
00787 {
00788    // Normally, we would just use isPolymorphicType_impl<T>::value, but
00789    // the isPolymorphicType_impl<T> class would produce a compile error if
00790    // T is an enumeration, pointer, or arithmetic data type name.
00791    //
00792    // The following syntax to select a guaranteed false data type for non-class 
00793    // values of T, but for true classes, select isPolymorphicType_impl<T> -- 
00794    // which will compile successfully.
00795 
00796    typedef isPolymorphicType_selector< isClassType<T>::value> selector;
00797 
00798    // since isPolymorphicType_selector<false> has a rebind template that defines
00799    // a guaranteed false_value_type, we are assured that selector will compile
00800    // no matter what data type is used for T -- and for class types, which gives
00801    // defines a selector with a rebind method that refers to isPolymorphicType_impl,
00802    // we get proper operation for that case too.
00803    // 
00804 
00805    // the following code invokes a template on the selector type.
00806    // I'm not sure why you need the template keyword, but you do.
00807 
00808 
00809    typedef typename selector::template rebind<T> binder;
00810    typedef typename binder::type imp_type;
00811    enum { value = imp_type::value };
00812 };
00813 
00814 
00815 
00816 
00817 //
00818 //  this template tells you if a class represents an signed number
00819 //
00820 
00821 template<class T>
00822 struct isSignedType
00828 {
00829   typedef typename removeCV<T>::type mutableType;
00830 
00831   static char f(char &);
00832   static char f(int &);
00833   static char f(short &);
00834   static char f(long &);
00835   static char f(long long &);
00836   static char f(float &);
00837   static char f(double &);
00838   static char f(long double &);
00839 
00840   static int  f(...);
00841 
00842   static mutableType t;
00843 
00844   enum { value = (sizeof(f(t)) == sizeof(char) ) };
00845 
00846 
00847 };
00848 
00849 template<>
00850 struct isSignedType<void>
00851 {
00852   enum { value = 0 };
00853 };
00854 template<>
00855 struct isSignedType<const void>
00856 {
00857   enum { value = 0 };
00858 };
00859 
00860 template<class T>
00861 struct isUnsignedType
00870 {
00871   typedef typename removeCV<T>::type mutableType;
00872   typedef typename removeReference<mutableType>::type UnrefType;
00873 
00874   static char f(unsigned char &);
00875   static char f(unsigned int &);
00876   static char f(unsigned short &);
00877   static char f(unsigned long &);
00878   static char f(unsigned long long&);
00879 
00880   static int  f(...);
00881 
00882   static UnrefType t;
00883 
00884   enum { value =sizeof(f(t)) == sizeof(char) };
00885 
00886 };
00887 
00888 template<>
00889 struct isUnsignedType<void>
00890 {
00891   enum { value = 0 };
00892 };
00893 template<>
00894 struct isUnsignedType<const void>
00895 {
00896   enum { value = 0 };
00897 };
00898 
00899 
00900 
00901 template<class T>
00902 struct isFloatType
00908 {
00909   typedef typename removeCV<T>::type mutableType;
00910   typedef typename removeReference<T>::type unrefType;
00911 
00912   static char f(float &);
00913   static char f(double &);
00914   static char f(long double &);
00915   static int  f(...);
00916 
00917   static unrefType *t;
00918 
00919   enum { value = sizeof(f(*t)) == sizeof(char) };
00920 };
00921 
00922 template<>
00923 struct isFloatType<void>
00927 {
00928   enum { value = 0 };
00929 };
00930 
00931 template<>
00932 struct isFloatType<const void>
00936 {
00937   enum { value = 0 };
00938 };
00939 
00940 
00941 
00942 
00943 
00944 
00945 template<class T>
00946 struct isEnumType
00953 {
00954   typedef typename removeCV<T>::type mutableType;
00955   typedef typename removeReference<mutableType>::type UnrefType;
00956 
00957   static char f(unsigned char &);
00958   static char f(unsigned int &);
00959   static char f(unsigned short &);
00960   static char f(unsigned long &);
00961   static char f(unsigned long long&);
00962   static char f(char &);
00963   static char f(int &);
00964   static char f(short &);
00965   static char f(long &);
00966   static char f(long long&);
00967   static char f(float &);
00968   static char f(double &);
00969   static char f(long double &);
00970 
00971 
00972   static int  f(...);
00973 
00974   static UnrefType t;
00975 
00976   enum { value =    !isClassType<UnrefType>::value 
00977                  && isConvertibleType<UnrefType, int>::value 
00978                  && sizeof( f(t) ) != sizeof(char)
00979        };
00980 };
00981 
00982 template<>
00983 struct isEnumType<void>
00984 {
00985   enum { value = 0 };
00986 };
00987 template<>
00988 struct isEnumType<const void>
00989 {
00990   enum { value = 0 };
00991 };
00992 
00993 
00994 
00995 template<class T>
00996 struct isIntegralType
01002 {
01003   typedef typename removeCV<T>::type MutableType;
01004   typedef typename removeReference<MutableType>::type U;
01005 
01006 
01007   enum { value = (   isSignedType<U>::value 
01008                   || isUnsignedType<U>::value 
01009                  )
01010                  && !isEnumType<U>::value
01011                  && !isFloatType<U>::value
01012        } ;
01013 };
01014 
01015 template<class T>
01016 struct isArithmeticType
01022 {
01023   typedef typename removeCV<T>::type MutableType;
01024   typedef typename removeReference<MutableType>::type U;
01025 
01026 
01027   enum { value = isIntegralType<U>::value || isFloatType<U>::value };
01028 };
01029 
01030 template<>
01031 struct isArithmeticType<void>
01032 : public false_value_type
01037 {
01038 };
01039 
01040 template<>
01041 struct isIntegralType<void>
01042 : public false_value_type
01047 {
01048 };
01049 
01050 template<>
01051 struct isArithmeticType<const void>
01052 : public false_value_type
01057 {
01058 };
01059 
01060 template<>
01061 struct isIntegralType<const void>
01062 : public false_value_type
01067 {
01068 };
01069 
01070 
01071 template<class T>
01072 struct isTemplate // supports up to 9 template parameters (all class)
01073                   // DOESN'T COMPILE EVERYWHERE!
01083 {
01084   static typename removeCV<T>::type *t;
01085 
01086   static int f(...);  // all types but templates
01087 
01088   template<class A, 
01089            template<class A1> class Template
01090           > 
01091           static char f( Template<A> *);
01092 
01093   template<class A, class B,
01094            template<class A1, class B1> class Template
01095           > 
01096           static char f( Template<A,B> *);
01097 
01098   template<class A, class B, class C,
01099            template<class A1, class B1, class C1> class Template
01100           > 
01101           static char f( Template<A,B,C> *);
01102 
01103   template<class A, class B, class C, class D,
01104            template<class A1, class B1, class C1, class D1> class Template
01105           > 
01106           static char f( Template<A,B,C,D> *);
01107 
01108   template<class A, class B, class C, class D, class E,
01109            template<class A1, class B1, class C1, class D1, class E1> 
01110            class Template
01111           > 
01112           static char f( Template<A,B,C,D,E> *);
01113 
01114   template<class A, class B, class C, class D, class E, class F,
01115            template<class A1, class B1, class C1, class D1, class E1, class F1> 
01116            class Template
01117           > 
01118           static char f( Template<A,B,C,D,E,F> *);
01119 
01120   template<class A, class B, class C, class D, class E, class F, class G,
01121            template<class A1, class B1, class C1, class D1, class E1, class F1, class G1> 
01122            class Template
01123           > 
01124           static char f( Template<A,B,C,D,E,F,G> *);
01125 
01126   template<class A, class B, class C, class D, class E, class F, class G, class H,
01127            template<class A1, class B1, class C1, class D1, class E1, class F1, class G1, class H1> 
01128            class Template
01129           > 
01130           static char f( Template<A,B,C,D,E,F,G,H> *);
01131 
01132   template<class A, class B, class C, class D, class E, class F, class G, class H, class I,
01133            template<class A1, class B1, class C1, class D1, class E1, class F1, class G1, class H1, class I1> 
01134            class Template
01135           > 
01136           static char f( Template<A,B,C,D,E,F,G,H,I> *);
01137 
01138 
01139   enum { value = sizeof( f(t) ) == 1 };
01140 };
01141 
01142 
01143 enum basicClassTypes
01146 {
01147     bctUnknownType  =0,
01148     bctVoidType     =1,
01149     bctIntegralType =2,  // int, long, char
01150     bctEnumType     =3,
01151     bctPointerType  =4,
01152     bctArrayType    =5,
01153     bctFloatType    =6,
01154     bctFunctionType =7,
01155     bctClassType    =8,
01156 };
01157 
01158 template<class T> struct basicClassType; 
01159 
01160 template<> 
01161 struct basicClassType<void> 
01169 { 
01170     enum { value = bctVoidType    }; 
01171 };
01172 
01173 template<class T> 
01174 struct basicClassType
01218 {
01219     typedef typename removeCV<T>::type MutableType;
01220     typedef typename removeReference<MutableType>::type RawType;
01221 
01222     enum {
01223             value = ( isIntegralType<RawType>::value
01224                       ? bctIntegralType
01225                       : ( isEnumType<RawType>::value
01226                           ? bctEnumType
01227                           : ( isArrayType<RawType>::value
01228                               ? bctArrayType
01229                               : ( isFunctionType<RawType>::value
01230                                   ? bctFunctionType
01231                                   : ( isFloatType<RawType>::value
01232                                      ? bctFloatType
01233                                      : ( isPointerType<RawType>::value
01234                                         ? bctPointerType
01235                                         : ( isClassType<RawType>::value
01236                                            ? bctClassType
01237                                            : bctUnknownType  // should not happen.
01238                                           )
01239                                        )
01240                                     )
01241                                 )
01242                             )
01243                         )
01244                     )
01245          };
01246 };
01247 
01248 template<class Base, class Derived>
01249 void derivedFromBase(Base *bptr, Derived *&dref)
01277 {
01278     static Derived *d= (Derived *)(0x100);  // can't use 0 here.
01279     static Base    *b=d;  // if Derived is not derived from Base this will cause a compile error.
01280 
01281     static size_t  const  bOffset = ((char *)b) - ((char *)d);
01282 
01283     dref =  (Derived*)( ((char*)bptr) - bOffset);
01284 
01285 }
01286 
01287 template<class T, class U, class W=false_value_type, class X=false_value_type>
01288 struct EvalOr
01293 {
01294    enum { value = T::value || U::value || W::value || X::value };
01295 };
01296 
01297 
01298 template<class T, class U, class W=true_value_type, class X=true_value_type>
01299 struct EvalAnd
01304 {
01305    enum { value = T::value && U::value && W::value && X::value};
01306 };
01307 
01308 
01309 
01310 template<class T>
01311 struct  removeAllExtents
01317 {
01318 
01319    typedef typename removeReference<T>::type                 ReferenceStripped;
01320    typedef typename pointerReferent<ReferenceStripped>::type PointerStripped;
01321    typedef typename removeCV<T>::type                        CVStripped;
01322 
01323    typedef CVStripped type;
01324     
01325 };
01326 
01327 template<class T, unsigned long long N>
01328 struct  removeAllExtents<T [N]>
01330 {
01331 
01332   typedef typename removeAllExtents<T>::type type;
01333     
01334 };
01335 
01336 
01337 
01338 } // namespace cxxtls
01339 
01340 #endif
Generated on Wed Feb 29 22:50:03 2012 for CXXUtilities by  doxygen 1.6.3