FastJet 3.0beta1
|
00001 //STARTHEADER 00002 // $Id: IsBase.hh 2191 2011-06-01 07:42:54Z soyez $ 00003 // 00004 // Copyright (c) 2005-2006, Matteo Cacciari and Gavin Salam 00005 // 00006 //---------------------------------------------------------------------- 00007 // This file is part of FastJet. 00008 // 00009 // FastJet is free software; you can redistribute it and/or modify 00010 // it under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation; either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // The algorithms that underlie FastJet have required considerable 00015 // development and are described in hep-ph/0512210. If you use 00016 // FastJet as part of work towards a scientific publication, please 00017 // include a citation to the FastJet paper. 00018 // 00019 // FastJet is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 // GNU General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with FastJet; if not, write to the Free Software 00026 // Foundation, Inc.: 00027 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00028 //---------------------------------------------------------------------- 00029 //ENDHEADER 00030 00031 #ifndef __FASTJET_INTERNAL_IS_BASE_HH__ 00032 #define __FASTJET_INTERNAL_IS_BASE_HH__ 00033 00034 #include "fastjet/internal/numconsts.hh" 00035 00036 FASTJET_BEGIN_NAMESPACE 00037 00038 //--------------------------------------------------- 00039 // define a true and a false 'type' 00040 // Note: 00041 // we could actually template the type and recover 00042 // the TR1 integral_constant type. This also 00043 // includes adding a typedef for the type and a 00044 // typedef for the struct in the struct below 00045 // 00046 // This is going to be helpful to "split" a given 00047 // call into 2 options based on a type constraint 00048 // at compilation-time (rather than doing an "if" 00049 // which would only be resolved at runtime and could 00050 // thus resutl in compilation errors. 00051 //--------------------------------------------------- 00052 00053 /// \if internal_doc 00054 /// \class integral type 00055 /// a generic construct that promotes a generic value of a generic type 00056 /// as a type 00057 /// 00058 /// this has 2 template parameters: T, the considered type, and _t, a 00059 /// value of type T 00060 /// This object is a basic construct in type traits 00061 /// \endif 00062 template<typename T, T _t> 00063 struct integral_type{ 00064 static const T value = _t; ///< the value (only member carrying info) 00065 typedef T value_type; ///< a typedef for the type T 00066 typedef integral_type<T,_t> type; ///< a typedef for the whole structure 00067 }; 00068 00069 // definition of the static member in integral_type 00070 template<typename T, T _t> 00071 const T integral_type<T, _t>::value; 00072 00073 // shortcuts 00074 typedef integral_type<bool, true> true_type; ///< the bool 'true' value promoted to a type 00075 typedef integral_type<bool, false> false_type; ///< the bool 'false' value promoted to a type 00076 00077 00078 //--------------------------------------------------- 00079 // define a yes and a no type (based on their size) 00080 //--------------------------------------------------- 00081 typedef char (&__yes_type)[1]; //< the yes type 00082 typedef char (&__no_type) [2]; //< the no type 00083 00084 00085 //--------------------------------------------------- 00086 // Now deal with inheritance checks 00087 // 00088 // We want to provide a IsBaseAndDerived<B,D> type 00089 // trait that contains a value that is true if D 00090 // is derived from B and false otherwise. 00091 // 00092 // For an explanation of how the code below works, 00093 // have a look at 00094 // http://groups.google.com/group/comp.lang.c++.moderated/msg/dd6c4e4d5160bd83 00095 // and the links therein 00096 // 00097 // WARNING: according to 'boost', this may have some 00098 // issues with MSVC7.1. See their code for a description 00099 // of the workaround used below 00100 //--------------------------------------------------- 00101 00102 /// \if internal_doc 00103 /// \class __inheritance_helper 00104 /// helper for IsBasedAndDerived<B,D> 00105 /// \endif 00106 template<typename B, typename D> 00107 struct __inheritance_helper{ 00108 #if !((_MSC_VER !=0 ) && (_MSC_VER == 1310)) // MSVC 7.1 00109 template <typename T> 00110 static __yes_type check_sig(D const volatile *, T); 00111 #else 00112 static __yes_type check_sig(D const volatile *, long); 00113 #endif 00114 static __no_type check_sig(B const volatile *, int); 00115 }; 00116 00117 /// \if internal_doc 00118 /// \class IsBaseAndDerived 00119 /// check if the second template argument is derived from the first one 00120 /// 00121 /// this class has 2 template dependencies: B and D. It contains a 00122 /// static boolean value that will be true if D is derived from B and 00123 /// false otherwise. 00124 /// 00125 /// Note: This construct may have a problem with MSVC7.1. See the 00126 /// boost implementation for a description and workaround 00127 /// \endif 00128 template<typename B, typename D> 00129 struct IsBaseAndDerived{ 00130 #if ((_MSC_FULL_VER != 0) && (_MSC_FULL_VER >= 140050000)) 00131 #pragma warning(push) 00132 #pragma warning(disable:6334) 00133 #endif 00134 00135 00136 /// \if internal_doc 00137 /// a helper structure that will pick between a casting to B*const 00138 /// or D. 00139 /// 00140 /// precisely how this structure works involves advanced C++ 00141 /// conversion rules 00142 /// \endif 00143 struct Host{ 00144 #if !((_MSC_VER !=0 ) && (_MSC_VER == 1310)) 00145 operator B const volatile *() const; 00146 #else 00147 operator B const volatile * const&() const; 00148 #endif 00149 operator D const volatile *(); 00150 }; 00151 00152 /// the boolean value being true if D is derived from B 00153 static const bool value = ((sizeof(B)!=0) && 00154 (sizeof(D)!=0) && 00155 (sizeof(__inheritance_helper<B,D>::check_sig(Host(), 0)) == sizeof(__yes_type))); 00156 00157 #if ((_MSC_FULL_VER != 0) && (_MSC_FULL_VER >= 140050000)) 00158 #pragma warning(pop) 00159 #endif 00160 }; 00161 00162 00163 /// a little helper that returns a pointer to d of type B* if D is 00164 /// derived from B and NULL otherwise 00165 template<class B, class D> 00166 B* cast_if_derived(D* d){ 00167 return IsBaseAndDerived<B,D>::value ? (B*)(d) : NULL; 00168 } 00169 00170 00171 FASTJET_END_NAMESPACE 00172 00173 00174 #endif // __IS_BASE_OF_HH__