// Semantics Consulting's Tyr Library // http://www.semantics.org // // Copyright (c) 2003 by Stephen C. Dewhurst // // Permission to use, copy, modify, distribute, and sell this software // for any purpose is hereby granted without fee, provided that the above // copyright notice appears in all copies and that both that copyright // notice and this permission notice appear in supporting documentation. // The author makes no representations about the suitability of this // software for any purpose. It is provided "as is" without express // or implied warranty. #ifndef UTILS_H #define UTILS_H // // Background utilities. Lots of them are taken from Alexandrescu's // Modern C++ Design, so I'll include the following for good measure: //////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2001 by Andrei Alexandrescu // This code accompanies the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author or Addison-Welsey Longman make no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #include namespace Tyr { template struct Select { typedef A R; }; template struct Select { typedef B R; }; // A different Select for testing adapters template struct ForeignSelect { typedef A Result; }; template struct ForeignSelect { typedef B Result; }; template struct IsSame { enum { r = false }; }; template struct IsSame { enum { r = true }; }; // A different IsSame for testing adapters template struct ForeignIsSame { enum { result = false }; }; template struct ForeignIsSame { enum { result = true }; }; // Some compilers can't handle Conversion correctly. typedef char MySmall; class MyBig { char dummy[2]; }; template class Conversion { static MySmall Test(U); static MyBig Test(...); static T MakeT(); public: enum { exists = (sizeof(Test(MakeT())) == sizeof(MySmall)) }; }; #define SUPERSUBCLASS(T, U) \ (Conversion::exists && \ !IsSame::r) #define SUPERSUBCLASS_STRICT(T, U) \ (SUPERSUBCLASS(T, U) && \ !IsSame::r) template struct IsDerivedFrom { enum { r = SUPERSUBCLASS_STRICT(A,B) }; }; //XXXXXXXXXX redundant with above template struct CanConvert { typedef char True; typedef double False; static True canConvert( T2 ); static False canConvert( ... ); static T1 makeT1( ); enum { r = sizeof(canConvert( makeT1( ) )) == sizeof(True) }; }; template struct IsTrue { enum { r = true }; }; template struct enable_if { typedef T Type; }; template struct enable_if {}; template struct Dereference { typedef T R; }; template struct Dereference { typedef T R; }; template struct Deref { typedef T R; }; template struct Deref { typedef T R; }; template struct Deref { typedef T R; }; template struct IsConst { enum { r = false }; }; template struct IsConst { enum { r = true }; }; template struct IsRef { enum { r = false }; }; template struct IsRef { enum { r = true }; }; template struct IsPcm { enum { r = false }; }; template struct IsPcm { enum { r = true }; }; template struct IsPcm { enum { r = true }; }; template struct IsPcm { enum { r = true }; }; template struct IsPcm { enum { r = true }; }; //xxx need other cases or an SFINAE solution for cv-quals, member funcs, etc. template struct IsPtr { enum { r = false }; }; template struct IsPtr { enum { r = true }; }; template struct IsPtr { enum { r = true }; }; template struct IsPtr { enum { r = true }; }; template struct IsPtr { enum { r = true }; }; template struct IsAry { enum { r = false, bound = 0 /* note: must be 0 */ }; }; template struct IsAry { enum { r = true, bound = n }; }; //======================= template struct DeConst { typedef T R; }; template struct DeConst { typedef T R; }; template struct IsVol { enum { r = false }; }; template struct IsVol { enum { r = true }; }; template struct DeVol { typedef T R; }; template struct DeVol { typedef T R; }; template struct IsQual { enum { r = IsConst::r || IsVol::r }; }; template struct DeQual { typedef typename DeVol::R>::R R; }; //======================= template struct Deary { // note: other code assumes OK to Deary a non-array, multiple times typedef T R; }; template struct Deary { typedef T R; }; template struct DearyN { typedef typename DearyN::R,n-1>::R R; }; template struct DearyN { typedef T R; }; template struct AddAryN { typedef typename AddAryN::R R[1]; }; template struct AddAryN { typedef T R; }; //======================= template struct DePtrAry { // note: other code assumes OK to Deary a non-array, multiple times typedef T R; }; template struct DePtrAry { typedef T R; }; template struct DePtrAryN { typedef typename DePtrAryN::R,n-1>::R R; }; template struct DePtrAryN { typedef T R; }; template struct AddPtrAryN { typedef typename AddPtrAryN::R (*R)[1]; }; template struct AddPtrAryN { typedef T R; }; template struct Int2Int { enum { value = v }; }; template MySmall hasValue_type( typename C::value_type const * ); template MyBig hasValue_type( ... ); #define has_value_type( C ) (sizeof(hasValue_type(0))==sizeof(MySmall)) // // Generate an integral encoding of the arguments // required to instantiate a template of unknown // argument requirements. // //XXX what about template template arguments? //XXX general problem with templates we don't have with typenames //XXX is that templates are highly combinatoric... // //XXX should use typeints here instead of hardcoded... typedef const unsigned long E; E e_t = 0x0001; // typename E e_tt = 0x0011; E e_ttt = 0x0111; E e_tttt = 0x1111; E e_i = 0x0002; // int E e_ii = 0x0022; E e_iii = 0x0222; E e_iiii = 0x2222; E e_itt = 0x0112; // int,typename,typename E e_b = 0x0003; // bool E e_btt = 0x0113; // bool,typename,typename E e_tT1t = 0x091; // typename, template class //XXX Need a way to define a function that can be instantiated with *any* template! template