CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

testCategories.cc

Go to the documentation of this file.
00001 // ======================================================================
00002 //
00003 // Test basic functionality of primary type traits
00004 //
00005 // Author:  W. E. Brown, 2010-03-27, adapted in part from the boost
00006 // library's type_traits and related functionality whose internal
00007 // attributions bear the following various notices:
00008 //
00009 //   (C) Copyright John Maddock 2000.
00010 //   Distributed under the Boost Software License, Version 1.0.
00011 //   See http://www.boost.org/LICENSE_1_0.txt
00012 //
00013 // ======================================================================
00014 
00015 
00016 #include "CLHEP/Utility/noncopyable.h"
00017 #include "CLHEP/Utility/type_traits.h"
00018 
00019 #include <cassert>
00020 #include <iostream>
00021 
00022 
00023 using namespace CLHEP;
00024 
00025 
00026 // primary type category codes:
00027 unsigned  _unknown                 = 0uL    ;
00028 unsigned  _void                    = 1uL <<  0;
00029 unsigned  _integral                = 1uL <<  1;
00030 unsigned  _floating_point          = 1uL <<  2;
00031 unsigned  _array                   = 1uL <<  3;
00032 unsigned  _pointer                 = 1uL <<  4;
00033 unsigned  _lvalue_reference        = 1uL <<  5;
00034 unsigned  _rvalue_reference        = 1uL <<  6;
00035 unsigned  _member_object_pointer   = 1uL <<  7;
00036 unsigned  _member_function_pointer = 1uL <<  8;
00037 unsigned  _enum                    = 1uL <<  9;
00038 unsigned  _union                   = 1uL << 10;  // Help, compiler!
00039 unsigned  _class                   = 1uL << 11;
00040 unsigned  _function                = 1uL << 12;
00041 
00042 // composite type category codes:
00043 unsigned  _reference               = 1uL << 13;
00044 unsigned  _arithmetic              = 1uL << 14;
00045 unsigned  _fundamental             = 1uL << 15;
00046 unsigned  _object                  = 1uL << 16;
00047 unsigned  _scalar                  = 1uL << 17;
00048 unsigned  _compound                = 1uL << 18;
00049 unsigned  _member_pointer          = 1uL << 19;
00050 
00051 
00052 // evaluate categories:
00053 template< typename T >
00054   unsigned
00055   evaluate()
00056 {
00057   unsigned  ans = _unknown;
00058 
00059   if( is_void                   <T>::value )  ans += _void;
00060   if( is_integral               <T>::value )  ans += _integral;
00061   if( is_floating_point         <T>::value )  ans += _floating_point;
00062   if( is_array                  <T>::value )  ans += _array;
00063   if( is_pointer                <T>::value )  ans += _pointer;
00064   if( is_lvalue_reference       <T>::value )  ans += _lvalue_reference;
00065   if( is_rvalue_reference       <T>::value )  ans += _rvalue_reference;
00066   if( is_member_object_pointer  <T>::value )  ans += _member_object_pointer;
00067   if( is_member_function_pointer<T>::value )  ans += _member_function_pointer;
00068   if( is_enum                   <T>::value )  ans += _enum;
00069   if( is_union                  <T>::value )  ans += _union;
00070   if( is_class                  <T>::value )  ans += _class;
00071   if( is_function               <T>::value )  ans += _function;;
00072 
00073   if( is_reference              <T>::value )  ans += _reference;
00074   if( is_arithmetic             <T>::value )  ans += _arithmetic;
00075   if( is_fundamental            <T>::value )  ans += _fundamental;
00076   if( is_object                 <T>::value )  ans += _object;
00077   if( is_scalar                 <T>::value )  ans += _scalar;
00078   if( is_compound               <T>::value )  ans += _compound;
00079   if( is_member_pointer         <T>::value )  ans += _member_pointer;
00080 
00081   return ans;
00082 }
00083 
00084 
00085 unsigned  cat_void
00086   = _void | _fundamental;
00087 unsigned  cat_int
00088   = _integral | _arithmetic | _object | _fundamental | _scalar;
00089 unsigned  cat_flt
00090   = _floating_point | _arithmetic | _object | _fundamental | _scalar;
00091 unsigned  cat_arr
00092   = _array | _object | _compound;
00093 unsigned  cat_ptr
00094   = _pointer | _object | _compound | _scalar;
00095 unsigned  cat_lref
00096   = _lvalue_reference | _reference | _compound;
00097 unsigned  cat_rref
00098   = _rvalue_reference | _reference | _compound;
00099 unsigned  cat_mem_obj_ptr
00100   = _member_object_pointer | _member_pointer | _object | _compound | _scalar;
00101 unsigned  cat_mbr_fctn_ptr
00102   = _member_function_pointer | _member_pointer | _object | _compound | _scalar;
00103 unsigned  cat_enum
00104   = _enum | _object | _compound | _scalar;
00105 unsigned  cat_union
00106   = _union | _object | _compound;
00107 unsigned  cat_class
00108   = _class | _object | _compound;
00109 unsigned  cat_fctn
00110   = _function | _compound;
00111 
00112 
00113 // define some test types:
00114 
00115 // class type:
00116 struct mytype
00117 {
00118   int a;
00119   int * p;
00120   int f();
00121 };  // mytype
00122 
00123 
00124 // enum type:
00125 enum myenum { a=12, b=16 };
00126 
00127 
00128 // union type:
00129 union myblend
00130 {
00131   int a;
00132   int * p;
00133   int f();
00134 };
00135 
00136 enum enum_UDT{ one, two, three };
00137 struct UDT
00138 {
00139   UDT() { };
00140   ~UDT() { };
00141   UDT(const UDT&);
00142   UDT& operator=(const UDT&);
00143   int i;
00144 
00145   void f1();
00146   int f2();
00147   int f3(int);
00148   int f4(int, float);
00149 };
00150 
00151 typedef void(*f1)();
00152 typedef int(*f2)(int);
00153 typedef int(*f3)(int, bool);
00154 typedef void (UDT::*mf1)();
00155 typedef int (UDT::*mf2)();
00156 typedef int (UDT::*mf3)(int);
00157 typedef int (UDT::*mf4)(int, float);
00158 typedef int (UDT::*mp);
00159 typedef int (UDT::*cmf)(int) const;
00160 
00161 // cv-qualifiers applied to reference types should have no effect
00162 
00163 // This is intentional:
00164 // r_type and cr_type should be the same type
00165 // but some compilers wrongly apply cv-qualifiers
00166 // to reference types (this may generate a warning
00167 // on some compilers):
00168 
00169 typedef int& r_type;
00170 #if ! defined(_MSC_VER)
00171 typedef const r_type cr_type;
00172 #endif  // _MSC_VER
00173 
00174 struct POD_UDT { int x; };
00175 struct empty_UDT
00176 {
00177   empty_UDT() { };
00178   empty_UDT(const empty_UDT&) { };
00179   ~empty_UDT() { };
00180   empty_UDT& operator=(const empty_UDT&){ return *this; }
00181   bool operator==(const empty_UDT&)const
00182   { return true; }
00183 };
00184 struct empty_POD_UDT
00185 {
00186   bool operator==(const empty_POD_UDT&)const
00187   { return true; }
00188 };
00189 union union_UDT
00190 {
00191   int x;
00192   double y;
00193   ~union_UDT() { }
00194 };
00195 union POD_union_UDT
00196 {
00197   int x;
00198   double y;
00199 };
00200 union empty_union_UDT
00201 {
00202   ~empty_union_UDT() { }
00203 };
00204 union empty_POD_union_UDT { };
00205 
00206 struct nothrow_copy_UDT
00207 {
00208   nothrow_copy_UDT();
00209   nothrow_copy_UDT(const nothrow_copy_UDT&)throw();
00210   ~nothrow_copy_UDT() { };
00211   nothrow_copy_UDT& operator=(const nothrow_copy_UDT&){ return *this; }
00212   bool operator==(const nothrow_copy_UDT&)const
00213   { return true; }
00214 };
00215 
00216 struct nothrow_assign_UDT
00217 {
00218   nothrow_assign_UDT();
00219   nothrow_assign_UDT(const nothrow_assign_UDT&);
00220   ~nothrow_assign_UDT() { };
00221   nothrow_assign_UDT& operator=(const nothrow_assign_UDT&)throw(){ return *this; }
00222   bool operator==(const nothrow_assign_UDT&)const
00223   { return true; }
00224 };
00225 
00226 struct nothrow_construct_UDT
00227 {
00228   nothrow_construct_UDT()throw();
00229   nothrow_construct_UDT(const nothrow_construct_UDT&);
00230   ~nothrow_construct_UDT() { };
00231   nothrow_construct_UDT& operator=(const nothrow_construct_UDT&){ return *this; }
00232   bool operator==(const nothrow_construct_UDT&)const
00233   { return true; }
00234 };
00235 
00236 class Base { };
00237 
00238 class Derived : public Base { };
00239 class Derived2 : public Base { };
00240 class MultiBase : public Derived, public Derived2  { };
00241 class PrivateBase : private Base { };
00242 
00243 class NonDerived { };
00244 
00245 enum enum1
00246 { one_,two_ };
00247 
00248 enum enum2
00249 { three_,four_ };
00250 
00251 struct VB
00252 { virtual ~VB() { }; };
00253 
00254 struct VD : VB
00255 { ~VD() { }; };
00256 
00257 // struct non_pointer:
00258 // used to verify that is_pointer does not return
00259 // true for class types that implement operator void*()
00260 
00261 struct non_pointer
00262 { operator void*(){return this;} };
00263 struct non_int_pointer
00264 {
00265   int i;
00266   operator int*(){return &i;}
00267 };
00268 struct int_constructible
00269 { int_constructible(int); };
00270 struct int_convertible
00271 { operator int(); };
00272 
00273 // struct non_empty:
00274 // used to verify that is_empty does not emit
00275 // spurious warnings or errors.
00276 
00277 struct non_empty : private noncopyable
00278 { int i; };
00279 
00280 // abstract base classes:
00281 struct test_abc1
00282 {
00283   test_abc1();
00284   virtual ~test_abc1();
00285   test_abc1(const test_abc1&);
00286   test_abc1& operator=(const test_abc1&);
00287   virtual void foo() = 0;
00288   virtual void foo2() = 0;
00289 };
00290 
00291 struct test_abc2
00292 {
00293   virtual ~test_abc2();
00294   virtual void foo() = 0;
00295   virtual void foo2() = 0;
00296 };
00297 
00298 struct test_abc3 : public test_abc1
00299 { virtual void foo3() = 0; };
00300 
00301 struct incomplete_type;
00302 
00303 struct polymorphic_base
00304 {
00305   virtual ~polymorphic_base();
00306   virtual void method();
00307 };
00308 
00309 struct polymorphic_derived1 : polymorphic_base
00310 { };
00311 
00312 struct polymorphic_derived2 : polymorphic_base
00313 { virtual void method(); };
00314 
00315 struct virtual_inherit1 : virtual Base { };
00316 struct virtual_inherit2 : virtual_inherit1 { };
00317 struct virtual_inherit3 : private virtual Base { };
00318 struct virtual_inherit4 : virtual noncopyable { };
00319 struct virtual_inherit5 : virtual int_convertible { };
00320 struct virtual_inherit6 : virtual Base { virtual ~virtual_inherit6()throw(); };
00321 
00322 typedef void foo0_t();
00323 typedef void foo1_t(int);
00324 typedef void foo2_t(int&, double);
00325 typedef void foo3_t(int&, bool, int, int);
00326 typedef void foo4_t(int, bool, int*, int[], int, int, int, int, int);
00327 
00328 struct trivial_except_construct
00329 {
00330   trivial_except_construct();
00331   int i;
00332 };
00333 
00334 struct trivial_except_destroy
00335 {
00336   ~trivial_except_destroy();
00337   int i;
00338 };
00339 
00340 struct trivial_except_copy
00341 {
00342   trivial_except_copy(trivial_except_copy const&);
00343   int i;
00344 };
00345 
00346 struct trivial_except_assign
00347 {
00348   trivial_except_assign& operator=(trivial_except_assign const&);
00349   int i;
00350 };
00351 
00352 template <class T>
00353 struct wrap
00354 {
00355   T t;
00356   int j;
00357 protected:
00358   wrap();
00359   wrap(const wrap&);
00360   wrap& operator=(const wrap&);
00361 };
00362 
00363 
00364 struct convertible_to_pointer
00365 { operator char*() const; };
00366 
00367 
00368 typedef const double (UDT::*mp2) ;
00369 
00370 
00371 int
00372   main()
00373 {
00374   // void types
00375   assert(evaluate<void                   >() == cat_void);
00376   assert(evaluate<void    const          >() == cat_void);
00377   assert(evaluate<void          volatile >() == cat_void);
00378   assert(evaluate<void    const volatile >() == cat_void);
00379 
00380   // integral types
00381   assert(evaluate<bool                   >() == cat_int);
00382   assert(evaluate<bool    const          >() == cat_int);
00383   assert(evaluate<bool          volatile >() == cat_int);
00384   assert(evaluate<bool    const volatile >() == cat_int);
00385   assert(evaluate<char                   >() == cat_int);
00386   assert(evaluate<char    const          >() == cat_int);
00387   assert(evaluate<char          volatile >() == cat_int);
00388   assert(evaluate<char    const volatile >() == cat_int);
00389   typedef  signed char  schar;
00390   assert(evaluate<schar                  >() == cat_int);
00391   assert(evaluate<schar   const          >() == cat_int);
00392   assert(evaluate<schar         volatile >() == cat_int);
00393   assert(evaluate<schar   const volatile >() == cat_int);
00394   typedef  unsigned char  uchar;
00395   assert(evaluate<uchar                  >() == cat_int);
00396   assert(evaluate<uchar   const          >() == cat_int);
00397   assert(evaluate<uchar         volatile >() == cat_int);
00398   assert(evaluate<uchar   const volatile >() == cat_int);
00399   assert(evaluate<short                  >() == cat_int);
00400   assert(evaluate<short   const          >() == cat_int);
00401   assert(evaluate<short         volatile >() == cat_int);
00402   assert(evaluate<short   const volatile >() == cat_int);
00403   typedef  unsigned short  ushort;
00404   assert(evaluate<ushort                 >() == cat_int);
00405   assert(evaluate<ushort  const          >() == cat_int);
00406   assert(evaluate<ushort        volatile >() == cat_int);
00407   assert(evaluate<ushort  const volatile >() == cat_int);
00408   assert(evaluate<int                    >() == cat_int);
00409   assert(evaluate<int     const          >() == cat_int);
00410   assert(evaluate<int           volatile >() == cat_int);
00411   assert(evaluate<int     const volatile >() == cat_int);
00412   typedef  unsigned int  uint;
00413   assert(evaluate<uint                   >() == cat_int);
00414   assert(evaluate<uint    const          >() == cat_int);
00415   assert(evaluate<uint          volatile >() == cat_int);
00416   assert(evaluate<uint    const volatile >() == cat_int);
00417   assert(evaluate<long                   >() == cat_int);
00418   assert(evaluate<long    const          >() == cat_int);
00419   assert(evaluate<long          volatile >() == cat_int);
00420   assert(evaluate<long    const volatile >() == cat_int);
00421   typedef  unsigned long  ulong;
00422   assert(evaluate<ulong                  >() == cat_int);
00423   assert(evaluate<ulong   const          >() == cat_int);
00424   assert(evaluate<ulong         volatile >() == cat_int);
00425   assert(evaluate<ulong   const volatile >() == cat_int);
00426 
00427   // floating-point types
00428   assert(evaluate<float                  >() == cat_flt);
00429   assert(evaluate<float   const          >() == cat_flt);
00430   assert(evaluate<float         volatile >() == cat_flt);
00431   assert(evaluate<float   const volatile >() == cat_flt);
00432   assert(evaluate<double                 >() == cat_flt);
00433   assert(evaluate<double  const          >() == cat_flt);
00434   assert(evaluate<double        volatile >() == cat_flt);
00435   assert(evaluate<double  const volatile >() == cat_flt);
00436   typedef  long double  ldouble;
00437   assert(evaluate<ldouble                >() == cat_flt);
00438   assert(evaluate<ldouble const          >() == cat_flt);
00439   assert(evaluate<ldouble       volatile >() == cat_flt);
00440   assert(evaluate<ldouble const volatile >() == cat_flt);
00441 
00442   // array types
00443   assert(evaluate<double              [1]>() == cat_arr);
00444   assert(evaluate<char const          [2]>() == cat_arr);
00445   assert(evaluate<float volatile      [3]>() == cat_arr);
00446   assert(evaluate<long const volatile [4]>() == cat_arr);
00447   assert(evaluate<mytype *            [6]>() == cat_arr);
00448   assert(evaluate<unsigned *          [6]>() == cat_arr);
00449   assert(evaluate<long double      [7][7]>() == cat_arr);
00450   assert(evaluate<UDT                 [2]>() == cat_arr);
00451 
00452   // pointer types
00453   assert(evaluate<char *                 >() == cat_ptr);
00454   assert(evaluate<int *                  >() == cat_ptr);
00455   assert(evaluate<int const *            >() == cat_ptr);
00456   assert(evaluate<int volatile *         >() == cat_ptr);
00457   assert(evaluate<int * *                >() == cat_ptr);
00458   assert(evaluate<int * * volatile       >() == cat_ptr);
00459   assert(evaluate<uint volatile *        >() == cat_ptr);
00460   assert(evaluate<long volatile * const  >() == cat_ptr);
00461   assert(evaluate<double * const *       >() == cat_ptr);
00462   assert(evaluate<float * const * const  >() == cat_ptr);
00463   assert(evaluate<int (*)(int)           >() == cat_ptr);
00464   assert(evaluate<non_pointer*           >() == cat_ptr);
00465   assert(evaluate<f1                     >() == cat_ptr);
00466   assert(evaluate<f2                     >() == cat_ptr);
00467   assert(evaluate<f3                     >() == cat_ptr);
00468 
00469   // lvalue reference types
00470   assert(evaluate<int &                  >() == cat_lref);
00471   assert(evaluate<int const &            >() == cat_lref);
00472   assert(evaluate<int volatile &         >() == cat_lref);
00473   assert(evaluate<int const volatile &   >() == cat_lref);
00474   assert(evaluate<int * &                >() == cat_lref);
00475   assert(evaluate<int (&)(int)           >() == cat_lref);
00476   assert(evaluate<int (&)[2]             >() == cat_lref);
00477   assert(evaluate<r_type                 >() == cat_lref);
00478   #if ! defined(_MSC_VER)
00479   assert(evaluate<cr_type                >() == cat_lref);
00480   #endif  // _MSC_VER
00481   assert(evaluate<UDT &                  >() == cat_lref);
00482   assert(evaluate<const UDT &            >() == cat_lref);
00483   assert(evaluate<volatile UDT &         >() == cat_lref);
00484   assert(evaluate<const volatile UDT &   >() == cat_lref);
00485 
00486   // member object pointer types
00487   assert(evaluate<int mytype::*          >() == cat_mem_obj_ptr);
00488   assert(evaluate<int mytype::* const    >() == cat_mem_obj_ptr);
00489   assert(evaluate<int mytype::* volatile >() == cat_mem_obj_ptr);
00490   assert(evaluate<mp                     >() == cat_mem_obj_ptr);
00491   assert(evaluate<mp2                    >() == cat_mem_obj_ptr);
00492 
00493   // member function pointer types
00494   assert(evaluate<int (mytype::*)()      >() == cat_mbr_fctn_ptr);
00495   assert(evaluate<int (mytype::*)()const >() == cat_mbr_fctn_ptr);
00496   assert(evaluate<int (mytype::*)(int)   >() == cat_mbr_fctn_ptr);
00497   assert(evaluate<mf1                    >() == cat_mbr_fctn_ptr);
00498   assert(evaluate<mf2                    >() == cat_mbr_fctn_ptr);
00499   assert(evaluate<mf3                    >() == cat_mbr_fctn_ptr);
00500   assert(evaluate<mf4                    >() == cat_mbr_fctn_ptr);
00501   assert(evaluate<cmf                    >() == cat_mbr_fctn_ptr);
00502 
00503   // enum types
00504   assert(evaluate<myenum                 >() == cat_enum);
00505   assert(evaluate<myenum const           >() == cat_enum);
00506   assert(evaluate<myenum volatile        >() == cat_enum);
00507   assert(evaluate<myenum const volatile  >() == cat_enum);
00508   assert(evaluate<enum_UDT               >() == cat_enum);
00509 
00510   // union types
00511   #if 0
00512   assert(evaluate<myblend                >() == cat_union);
00513   assert(evaluate<myblend const          >() == cat_union);
00514   assert(evaluate<myblend volatile       >() == cat_union);
00515   assert(evaluate<myblend const volatile >() == cat_union);
00516   assert(evaluate<union_UDT              >() == cat_union);
00517   assert(evaluate<POD_union_UDT          >() == cat_union);
00518   assert(evaluate<empty_union_UDT        >() == cat_union);
00519   assert(evaluate<empty_POD_union_UDT    >() == cat_union);
00520   assert(evaluate<union_UDT const        >() == cat_union);
00521   assert(evaluate<POD_union_UDT volatile >() == cat_union);
00522   assert(evaluate<empty_union_UDT const volatile>() == cat_union);
00523   assert(evaluate<empty_POD_union_UDT const>() == cat_union);
00524   #endif  // 0
00525 
00526   // class types
00527   assert(evaluate<UDT                    >() == cat_class);
00528   assert(evaluate<UDT const              >() == cat_class);
00529   assert(evaluate<UDT volatile           >() == cat_class);
00530   assert(evaluate<UDT const volatile     >() == cat_class);
00531   assert(evaluate<empty_UDT              >() == cat_class);
00532   assert(evaluate<test_abc1              >() == cat_class);
00533   assert(evaluate<test_abc1 const        >() == cat_class);
00534   assert(evaluate<std::iostream          >() == cat_class);
00535 
00536   // function types
00537   assert(evaluate<int (int)              >() == cat_fctn);
00538   assert(evaluate<void (int,float, long) >() == cat_fctn);
00539   assert(evaluate<foo0_t                 >() == cat_fctn);
00540   assert(evaluate<foo1_t                 >() == cat_fctn);
00541   assert(evaluate<foo2_t                 >() == cat_fctn);
00542   assert(evaluate<foo3_t                 >() == cat_fctn);
00543   assert(evaluate<foo4_t                 >() == cat_fctn);
00544 
00545   return 0;
00546 }

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7