lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean Meta (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_META_STRIP 00006 #define LEAN_META_STRIP 00007 00008 #include "../cpp0x.h" 00009 00010 namespace lean 00011 { 00012 namespace meta 00013 { 00014 00016 template <class Type> 00017 struct strip_reference 00018 { 00020 typedef Type type; 00022 static const bool stripped = false; 00023 00025 template <class Other> 00026 struct undo 00027 { 00029 typedef Other type; 00030 }; 00031 }; 00032 00033 #ifndef DOXYGEN_SKIP_THIS 00034 00035 template <class Type> 00036 struct strip_reference<Type&> 00037 { 00038 typedef Type type; 00039 static const bool stripped = true; 00040 template <class Other> 00041 struct undo { typedef Other& type; }; 00042 }; 00043 00044 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00045 template <class Type> 00046 struct strip_reference<Type&&> 00047 { 00048 typedef Type type; 00049 static const bool stripped = true; 00050 template <class Other> 00051 struct undo { typedef Other&& type; }; 00052 }; 00053 #endif 00054 00055 #endif 00056 00058 template <class Type> 00059 struct inh_strip_reference : public strip_reference<Type>::type { }; 00060 00062 template <class Type> 00063 struct strip_const 00064 { 00066 typedef Type type; 00068 static const bool stripped = false; 00069 00071 template <class Other> 00072 struct undo 00073 { 00075 typedef Other type; 00076 }; 00077 }; 00078 00079 #ifndef DOXYGEN_SKIP_THIS 00080 00081 template <class Type> 00082 struct strip_const<const Type> 00083 { 00084 typedef Type type; 00085 static const bool stripped = true; 00086 template <class Other> 00087 struct undo { typedef const Other type; }; 00088 }; 00089 00090 #endif 00091 00093 template <class Type> 00094 struct strip_volatile 00095 { 00097 typedef Type type; 00099 static const bool stripped = false; 00100 00102 template <class Other> 00103 struct undo 00104 { 00106 typedef Other type; 00107 }; 00108 }; 00109 00110 #ifndef DOXYGEN_SKIP_THIS 00111 00112 template <class Type> 00113 struct strip_volatile<volatile Type> 00114 { 00115 typedef Type type; 00116 static const bool stripped = true; 00117 template <class Other> 00118 struct undo { typedef volatile Other type; }; 00119 }; 00120 00121 #endif 00122 00124 template <class Type> 00125 struct strip_modifiers 00126 { 00128 typedef typename strip_volatile<typename strip_const<Type>::type>::type type; 00130 static const bool stripped = strip_volatile<Type>::stripped || strip_const<Type>::stripped; 00131 00133 template <class Other> 00134 struct undo 00135 { 00137 typedef typename strip_const<Type>::template undo<typename strip_volatile<Type>::template undo<Other>::type>::type type; 00138 }; 00139 }; 00140 00142 template <class Type> 00143 struct strip_modref 00144 { 00146 typedef typename strip_reference<Type>::type value_type; 00148 typedef typename strip_modifiers<value_type>::type type; 00150 static const bool stripped = strip_reference<Type>::stripped || strip_modifiers<value_type>::stripped; 00151 00153 template <class Other> 00154 struct undo 00155 { 00157 typedef typename strip_reference<Type>::template undo<typename strip_modifiers<value_type>::template undo<Other>::type>::type type; 00158 }; 00159 }; 00160 00162 template <class Type> 00163 struct inh_strip_modref : public strip_modref<Type>::type { }; 00164 00165 namespace impl 00166 { 00167 00168 template <class Type> 00169 struct do_strip_pointer 00170 { 00171 typedef Type type; 00172 static const bool stripped = false; 00173 template <class Other> 00174 struct undo { typedef Other type; }; 00175 }; 00176 00177 template <class Type> 00178 struct do_strip_pointer<Type*> 00179 { 00180 typedef Type type; 00181 static const bool stripped = true; 00182 template <class Other> 00183 struct undo { typedef Other* type; }; 00184 }; 00185 00186 } // namespace 00187 00189 template <class Type> 00190 struct strip_pointer 00191 { 00193 typedef typename strip_modifiers<Type>::type pointer; 00195 typedef typename impl::do_strip_pointer<pointer>::type type; 00197 static const bool stripped = impl::do_strip_pointer<pointer>::stripped; 00198 00200 template <class Other> 00201 struct undo 00202 { 00204 typedef typename impl::do_strip_pointer<pointer>::template undo<Other>::type pointer; 00206 typedef typename strip_modifiers<Type>::template undo<pointer>::type type; 00207 }; 00208 }; 00209 00211 template <class Type> 00212 struct inh_strip_pointer : public strip_pointer<Type>::type { }; 00213 00214 namespace impl 00215 { 00216 00217 template <class Type> 00218 struct do_strip_array 00219 { 00220 typedef Type type; 00221 static const bool stripped = false; 00222 template <class Other> 00223 struct undo { typedef Other type; }; 00224 }; 00225 00226 template <class Type> 00227 struct do_strip_array<Type[]> 00228 { 00229 typedef Type type; 00230 static const bool stripped = true; 00231 template <class Other> 00232 struct undo { typedef Other type[]; }; 00233 }; 00234 00235 template <class Type, size_t Size> 00236 struct do_strip_array<Type[Size]> 00237 { 00238 typedef Type type; 00239 static const bool stripped = true; 00240 template <class Other> 00241 struct undo { typedef Other type[Size]; }; 00242 }; 00243 00244 } // namespace 00245 00247 template <class Type> 00248 struct strip_array 00249 { 00251 typedef typename strip_modifiers<Type>::type array; 00253 typedef typename impl::do_strip_array<array>::type type; 00255 static const bool stripped = impl::do_strip_array<array>::stripped; 00256 00258 template <class Other> 00259 struct undo 00260 { 00262 typedef typename impl::do_strip_array<array>::template undo<Other>::type array; 00264 typedef typename strip_modifiers<Type>::template undo<array>::type type; 00265 }; 00266 }; 00267 00269 template <class Type> 00270 struct inh_strip_array : public strip_array<Type>::type { }; 00271 00272 namespace impl 00273 { 00274 00275 template <class Type, bool Continue = true> 00276 struct do_rec_strip_modifiers 00277 { 00278 typedef Type type; 00279 static const bool stripped = false; 00280 }; 00281 00282 template <class Type> 00283 struct do_rec_strip_modifiers<Type, true> 00284 { 00285 typedef strip_modref<Type> modref_stripper; 00286 typedef strip_array<typename modref_stripper::type> array_stripper; 00287 typedef strip_pointer<typename array_stripper::type> pointer_stripper; 00288 static const bool continue_stripping = array_stripper::stripped || pointer_stripper::stripped; 00289 00290 static const bool stripped = modref_stripper::stripped 00291 || do_rec_strip_modifiers<typename pointer_stripper::type, continue_stripping>::stripped; 00292 00293 typedef typename array_stripper::template undo< 00294 typename pointer_stripper::template undo< 00295 typename do_rec_strip_modifiers<typename pointer_stripper::type, continue_stripping>::type 00296 >::type 00297 >::type type; 00298 }; 00299 00300 } // namespace 00301 00303 template <class Type> 00304 struct rec_strip_modifiers 00305 { 00307 typedef typename impl::do_rec_strip_modifiers<Type>::type type; 00309 static const bool stripped = impl::do_rec_strip_modifiers<Type>::stripped; 00310 }; 00311 00313 template <class Type> 00314 struct identity 00315 { 00317 typedef Type type; 00318 }; 00319 00320 } // namespace 00321 00322 using meta::strip_array; 00323 using meta::strip_pointer; 00324 using meta::strip_reference; 00325 using meta::strip_const; 00326 using meta::strip_volatile; 00327 using meta::strip_modifiers; 00328 using meta::strip_modref; 00329 using meta::rec_strip_modifiers; 00330 using meta::identity; 00331 00332 using meta::inh_strip_pointer; 00333 using meta::inh_strip_array; 00334 using meta::inh_strip_reference; 00335 using meta::inh_strip_modref; 00336 00337 } // namespace 00338 00339 #endif