00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MORE_GEN_META_H
00033 #define MORE_GEN_META_H
00034
00035 namespace more {
00036
00037
00038 struct nulltype {
00039 typedef nulltype first_type;
00040 typedef nulltype second_type;
00041 operator bool() { return false; }
00042 operator int() { return 0; }
00043 };
00044 struct truetype {
00045 operator bool() { return true; }
00046 operator int() { return 1; }
00047 };
00048
00049 template <class T, class U>
00050 struct typepair {
00051 typedef T first_type;
00052 typedef U second_type;
00053 };
00054
00055 template<typename T> struct typepair_traits {
00056 static const int atomic = 1;
00057 static const int linear = 0;
00058 static const int arity = 0;
00059 };
00060 template<> struct typepair_traits<nulltype> {
00061 static const int atomic = 1;
00062 static const int linear = 1;
00063 static const int arity = 0;
00064 };
00065
00066 template<typename T, typename U>
00067 struct typepair_traits< typepair<T, U> > {
00068 static const int atomic = 0;
00069 static const int linear =
00070 typepair_traits<T>::atomic && typepair_traits<U>::linear;
00071 static const int arity =
00072 typepair_traits<U>::arity + 1;
00073 };
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 template <class Cond, class Positive, class Negative = nulltype>
00084 struct if_ { typedef Positive eval; };
00085
00086 template <class Positive, class Negative>
00087 struct if_<nulltype, Positive, Negative> { typedef Negative eval; };
00088
00089 template <class T> struct not_ { typedef nulltype eval; };
00090 template <> struct not_<nulltype> { typedef truetype eval; };
00091
00092 template <class T, class U> struct equals_ { typedef nulltype eval; };
00093 template <class T> struct equals_<T, T> { typedef T eval; };
00094 template <> struct equals_<nulltype, nulltype> { typedef truetype eval; };
00095
00096 template <class T, class U> struct equiv_ { typedef truetype eval; };
00097 template <class T> struct equiv_<T, nulltype> { typedef nulltype eval; };
00098 template <class U> struct equiv_<nulltype, U> { typedef nulltype eval; };
00099 template <> struct equiv_<nulltype, nulltype> { typedef truetype eval; };
00100
00101 template <class T1 = nulltype, class T2 = nulltype, class T3 = nulltype,
00102 class T4 = nulltype, class T5 = nulltype, class T6 = nulltype>
00103 struct or_ { typedef T1 eval; };
00104 template <class T2, class T3, class T4, class T5, class T6>
00105 struct or_<nulltype, T2, T3, T4, T5, T6> { typedef T2 eval; };
00106 template <class T3, class T4, class T5, class T6>
00107 struct or_<nulltype, nulltype, T3, T4, T5, T6> { typedef T3 eval; };
00108 template <class T4, class T5, class T6>
00109 struct or_<nulltype, nulltype, nulltype, T4, T5, T6> { typedef T4 eval; };
00110 template <class T5, class T6>
00111 struct or_<nulltype, nulltype, nulltype, nulltype, T5, T6>
00112 { typedef T5 eval; };
00113 template <class T6>
00114 struct or_<nulltype, nulltype, nulltype, nulltype, nulltype, T6>
00115 { typedef T6 eval; };
00116
00117 #if 0
00118 template <class T1 = truetype, class T2 = T1, class T3 = T2,
00119 class T4 = T3, class T5 = T4, class T6 = T5>
00120 struct and_ { typedef T6 eval; };
00121 template <class T2, class T3, class T4, class T5, class T6>
00122 struct and_<nulltype, T2, T3, T4, T5, T6> { typedef nulltype eval; };
00123 template <class T1, class T3, class T4, class T5, class T6>
00124 struct and_<T1, nulltype, T3, T4, T5, T6> { typedef nulltype eval; };
00125 template <class T1, class T2, class T4, class T5, class T6>
00126 struct and_<T1, T2, nulltype, T4, T5, T6> { typedef nulltype eval; };
00127 template <class T1, class T2, class T3, class T5, class T6>
00128 struct and_<T1, T2, T3, nulltype, T5, T6> { typedef nulltype eval; };
00129 template <class T1, class T2, class T3, class T4, class T6>
00130 struct and_<T1, T2, T3, T4, nulltype, T6> { typedef nulltype eval; };
00131 template <class T1, class T2, class T3, class T4, class T5>
00132 struct and_<T1, T2, T3, T4, T5, nulltype> { typedef nulltype eval; };
00133 #else
00134 template <class T1 = truetype, class T2 = T1, class T3 = T2,
00135 class T4 = T3, class T5 = T4, class T6 = T5>
00136 struct and_ : public and_<T2, T3, T4, T5, T6, truetype> {};
00137 template <class T2, class T3, class T4, class T5, class T6>
00138 struct and_<nulltype, T2, T3, T4, T5, T6> { typedef nulltype eval; };
00139 template <class T>
00140 struct and_<T, truetype, truetype, truetype, truetype, truetype>
00141 { typedef T eval; };
00142 #endif
00143
00144 template <class T, class U> struct xor_ { typedef nulltype eval; };
00145 template <class T> struct xor_<T, nulltype> { typedef T eval; };
00146 template <class U> struct xor_<nulltype, U> { typedef U eval; };
00147
00148
00149
00150
00151
00152
00153
00154 template <class List, class Value>
00155 struct append_ { typedef typename List::is_not_a_list eval; };
00156
00157 template <class V>
00158 struct append_<nulltype, V> { typedef typepair<V, nulltype> eval; };
00159
00160 template <class E, class Tail, class V>
00161 struct append_<typepair<E, Tail>, V>
00162 { typedef typepair<E, typename append_<Tail, V>::eval> eval; };
00163
00164
00165
00166
00167
00168
00169 template <class List, class List1>
00170 struct concat_ { typedef typename List::is_not_a_list eval; };
00171
00172 template <class List1>
00173 struct concat_<nulltype, List1> { typedef List1 eval; };
00174
00175 template <class E, class Tail, class List1>
00176 struct concat_<typepair<E, Tail>, List1>
00177 { typedef typepair<E, typename concat_<Tail, List1>::eval> eval; };
00178
00179
00180
00181
00182
00183
00184 template <class List>
00185 struct tree_to_list_ { typedef typepair<List, nulltype> eval; };
00186
00187 template <class List, class List1>
00188 struct tree_to_list_< typepair<List, List1> > {
00189 typedef typename concat_
00190 < typename tree_to_list_<List>::eval,
00191 typename tree_to_list_<List1>::eval
00192 >::eval eval;
00193 };
00194
00195
00196
00197
00198 template <class T, class List>
00199 struct is_in_ { typedef typename List::is_not_a_list eval; };
00200
00201 template <class T, class U, class Tail>
00202 struct is_in_< T, typepair<U, Tail> >
00203 { typedef typename is_in_<T, Tail>::eval eval; };
00204
00205 template <class T, class Tail>
00206 struct is_in_< T, typepair<T, Tail> > { typedef truetype eval; };
00207
00208 template <class T>
00209 struct is_in_<T, nulltype> { typedef nulltype eval; };
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 template <class T>
00221 struct typeassert_ {
00222 typedef typename if_
00223 < typename not_< typename T::eval >::eval,
00224 typename T::ASSERTION_FAILED,
00225 T >::eval eval;
00226 };
00227
00228
00229
00230
00231
00232
00233
00234
00235 template <class T1 = nulltype, class T2 = nulltype, class T3 = nulltype,
00236 class T4 = nulltype, class T5 = nulltype, class T6 = nulltype,
00237 class T7 = nulltype, class T8 = nulltype, class T9 = nulltype,
00238 class T10= nulltype, class T11= nulltype, class T12= nulltype>
00239 struct list_ {
00240 typedef typepair
00241 < T1, typepair< T2, typepair< T3, typepair
00242 < T4, typepair< T5, typepair< T6, typepair
00243 < T7, typepair< T8, typepair< T9, typepair
00244 <T10, typepair<T11, typepair<T12, nulltype > > > > > > > > > > > >
00245 eval;
00246 };
00247
00248 template <class T1, class T2, class T3, class T4, class T5, class T6,
00249 class T7, class T8, class T9, class T10, class T11>
00250 struct list_<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> {
00251 typedef typepair
00252 < T1, typepair< T2, typepair< T3, typepair
00253 < T4, typepair< T5, typepair< T6, typepair
00254 < T7, typepair< T8, typepair< T9, typepair
00255 <T10, typepair<T11, nulltype > > > > > > > > > > >
00256 eval;
00257 };
00258
00259 template <class T1, class T2, class T3, class T4, class T5, class T6,
00260 class T7, class T8, class T9, class T10>
00261 struct list_<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> {
00262 typedef typepair
00263 < T1, typepair< T2, typepair< T3, typepair
00264 < T4, typepair< T5, typepair< T6, typepair
00265 < T7, typepair< T8, typepair< T9, typepair
00266 <T10, nulltype > > > > > > > > > >
00267 eval;
00268 };
00269
00270 template <class T1, class T2, class T3, class T4, class T5, class T6,
00271 class T7, class T8, class T9>
00272 struct list_<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
00273 typedef typepair
00274 < T1, typepair< T2, typepair< T3, typepair
00275 < T4, typepair< T5, typepair< T6, typepair
00276 < T7, typepair< T8, typepair< T9, nulltype > > > > > > > > >
00277 eval;
00278 };
00279
00280 template <class T1, class T2, class T3, class T4, class T5, class T6,
00281 class T7, class T8>
00282 struct list_<T1, T2, T3, T4, T5, T6, T7, T8> {
00283 typedef typepair
00284 < T1, typepair< T2, typepair< T3, typepair
00285 < T4, typepair< T5, typepair< T6, typepair
00286 < T7, typepair< T8, nulltype > > > > > > > >
00287 eval;
00288 };
00289
00290 template <class T1, class T2, class T3, class T4, class T5, class T6,
00291 class T7>
00292 struct list_<T1, T2, T3, T4, T5, T6, T7> {
00293 typedef typepair
00294 < T1, typepair< T2, typepair< T3, typepair
00295 < T4, typepair< T5, typepair< T6, typepair
00296 < T7, nulltype > > > > > > >
00297 eval;
00298 };
00299
00300 template <class T1, class T2, class T3, class T4, class T5, class T6>
00301 struct list_<T1, T2, T3, T4, T5, T6> {
00302 typedef typepair
00303 < T1, typepair< T2, typepair< T3, typepair
00304 < T4, typepair< T5, typepair< T6, nulltype > > > > > > eval;
00305 };
00306
00307 template <class T1, class T2, class T3, class T4, class T5>
00308 struct list_<T1, T2, T3, T4, T5> {
00309 typedef typepair
00310 < T1, typepair< T2, typepair< T3, typepair
00311 < T4, typepair< T5, nulltype > > > > > eval;
00312 };
00313
00314 template <class T1, class T2, class T3, class T4>
00315 struct list_<T1, T2, T3, T4> {
00316 typedef typepair
00317 < T1, typepair< T2, typepair< T3, typepair< T4, nulltype > > > >
00318 eval;
00319 };
00320
00321 template <class T1, class T2, class T3> struct list_<T1, T2, T3>
00322 { typedef typepair< T1, typepair< T2, typepair< T3, nulltype > > > eval; };
00323
00324 template <class T1, class T2> struct list_<T1, T2>
00325 { typedef typepair< T1, typepair< T2, nulltype > > eval; };
00326
00327 template <class T1> struct list_<T1>
00328 { typedef typepair< T1, nulltype > eval; };
00329
00330 template <> struct list_<> { typedef nulltype eval; };
00331
00332
00333
00334
00335
00336 template <class T1, class T2, class Ordering>
00337 class order_ { typedef typename Ordering::is_not_a_list eval; };
00338 template <class T1, class T2, class T3, class Tail>
00339 struct order_< T1, T2, typepair<T3, Tail> >
00340 { typedef typename order_<T1, T2, Tail>::eval eval; };
00341 template <class T1, class T2, class Tail>
00342 struct order_< T1, T2, typepair<T1, Tail> >
00343 { typedef typepair<T1, T2> eval; };
00344 template <class T1, class T2, class Tail>
00345 struct order_< T1, T2, typepair<T2, Tail> >
00346 { typedef typepair<T2, T1> eval; };
00347 template <class T, class Tail>
00348 struct order_< T, T, typepair<T, Tail> >
00349 { typedef typepair<T, T> eval; };
00350 template <class T1, class T2>
00351 struct order_< T1, T2, nulltype >
00352 { typedef nulltype eval; };
00353
00354
00355
00356
00357
00358 #if 0
00359 typedef list_< char, short, int, long, float, double, long double >::eval
00360 balanced_type_order;
00361
00362 template <class T1, class T2>
00363 class commutative_balanced_type_ { typedef nulltype eval; };
00364
00365 template <class T1, class T2>
00366 class balanced_type_ {
00367 typedef typename order_<T1, T2, balanced_type_order>::eval order;
00368 public:
00369 typedef typename or_
00370 < typename commutative_balanced_type_<T1, T2>::eval,
00371 typename commutative_balanced_type_<T2, T1>::eval,
00372 typename order::second_type,
00373 typename if_
00374 < typename is_in_<T1, balanced_type_order>::eval, T2
00375 > ::eval,
00376 typename if_
00377 < typename is_in_<T2, balanced_type_order>::eval, T1
00378 > ::eval
00379 > ::eval eval;
00380 };
00381
00382 template <class T1, class T2>
00383 struct commutative_plus_type_ { typedef nulltype eval; };
00384
00385 template <class T1, class T2>
00386 struct plus_type_ {
00387 typedef typename or_
00388 < typename commutative_plus_type_<T1, T2>::eval,
00389 typename commutative_plus_type_<T2, T1>::eval,
00390 typename balanced_type_<T1, T2>::eval >::eval eval;
00391 };
00392
00393 template <class T1, class T2>
00394 struct commutative_minus_type_ { typedef nulltype eval; };
00395
00396 template <class T1, class T2>
00397 struct minus_type_ {
00398 typedef typename or_
00399 < typename commutative_minus_type_<T1, T2>::eval,
00400 typename commutative_minus_type_<T2, T1>::eval,
00401 typename balanced_type_<T1, T2>::eval >::eval eval;
00402 };
00403
00404 template <class T1, class T2>
00405 struct commutative_times_type_ { typedef nulltype eval; };
00406
00407 template <class T1, class T2>
00408 struct times_type_ {
00409 typedef typename or_
00410 < typename commutative_times_type_<T1, T2>::eval,
00411 typename commutative_times_type_<T2, T1>::eval,
00412 typename balanced_type_<T1, T2>::eval >::eval eval;
00413 };
00414
00415 template <class T1, class T2>
00416 struct commutative_divides_type_ { typedef nulltype eval; };
00417
00418 template <class T1, class T2>
00419 struct divides_type_ {
00420 typedef typename or_
00421 < typename commutative_divides_type_<T1, T2>::eval,
00422 typename commutative_divides_type_<T2, T1>::eval,
00423 typename balanced_type_<T1, T2>::eval >::eval eval;
00424 };
00425
00426 template <class T1, class T2>
00427 struct commutative_remainder_type_ { typedef nulltype eval; };
00428
00429 template <class T1, class T2>
00430 struct remainder_type_ {
00431 typedef typename or_
00432 < typename commutative_remainder_type_<T1, T2>::eval,
00433 typename commutative_remainder_type_<T2, T1>::eval,
00434 typename balanced_type_<T1, T2>::eval >::eval eval;
00435 };
00436 #endif
00437
00438
00439
00440
00441 template<typename T> inline char _meta_is_a_1(const void*, const T*) {}
00442 template<typename T> inline long _meta_is_a_1(const T*, const T*) {}
00443
00444 template <int N> struct _longsize {};
00445 template <> struct _longsize<sizeof(char)> { typedef nulltype eval; };
00446 template <> struct _longsize<sizeof(long)> { typedef truetype eval; };
00447
00448 #if 0
00449 template <class T, class U> class is_a_ {
00450 private:
00451 enum { size = sizeof(_meta_is_a_1(static_cast<T*>(0),
00452 static_cast<U*>(0))) };
00453 public:
00454 typedef typename _longsize<size>::eval eval;
00455 };
00456 #endif
00457
00458
00459
00460
00461 template <class T> struct is_pointer_ { typedef nulltype eval; };
00462 template <class T> struct is_pointer_<T*> { typedef truetype eval; };
00463
00464
00465
00466
00467 template <class T> struct is_class_ { typedef truetype eval; };
00468 template <class T> struct is_class_<T*> { typedef nulltype eval; };
00469 template <> struct is_class_<bool> { typedef nulltype eval; };
00470 template <> struct is_class_<char> { typedef nulltype eval; };
00471 template <> struct is_class_<signed char> { typedef nulltype eval; };
00472 template <> struct is_class_<unsigned char> { typedef nulltype eval; };
00473 template <> struct is_class_<short> { typedef nulltype eval; };
00474 template <> struct is_class_<unsigned short> { typedef nulltype eval; };
00475 template <> struct is_class_<int> { typedef nulltype eval; };
00476 template <> struct is_class_<unsigned int> { typedef nulltype eval; };
00477 template <> struct is_class_<long> { typedef nulltype eval; };
00478 template <> struct is_class_<unsigned long> { typedef nulltype eval; };
00479 template <> struct is_class_<float> { typedef nulltype eval; };
00480 template <> struct is_class_<double> { typedef nulltype eval; };
00481 template <> struct is_class_<long double> { typedef nulltype eval; };
00482
00483 template <class T> struct is_etype_
00484 { typedef typename not_<typename is_class_<T>::eval>::eval eval; };
00485
00486
00487
00488
00489 template <bool Cond> struct is_true_ { typedef nulltype eval; };
00490 template <> struct is_true_<true> { typedef truetype eval; };
00491
00492
00493
00494
00495 template<typename T> struct is_const_ { typedef nulltype eval; };
00496 template<typename T> struct is_const_<const T> { typedef truetype eval; };
00497
00498
00499
00500 template <class T, class U> struct bigger_type_ {
00501 typedef typename if_
00502 < typename is_true_< (sizeof(T) >= sizeof(U)) >::eval,
00503 T, U >::eval eval;
00504 };
00505
00506
00507
00508 template<typename T> struct to_unsigned_ { typedef T eval; };
00509 template<> struct to_unsigned_<char> { typedef unsigned char eval; };
00510 template<> struct to_unsigned_<signed char> { typedef unsigned char eval; };
00511 template<> struct to_unsigned_<short> { typedef unsigned short eval; };
00512 template<> struct to_unsigned_<int> { typedef unsigned int eval; };
00513 template<> struct to_unsigned_<long> { typedef unsigned long eval; };
00514 #ifdef MORE_HAVE_LONG_LONG
00515 template<> struct to_unsigned_<long long> { typedef unsigned long long eval; };
00516 #endif
00517
00518
00519
00520 template<typename T> struct to_signed_ { typedef T eval; };
00521 template<> struct to_signed_<char> { typedef signed char eval; };
00522 template<> struct to_signed_<unsigned char> { typedef signed char eval; };
00523 template<> struct to_signed_<unsigned short> { typedef short eval; };
00524 template<> struct to_signed_<unsigned int> { typedef int eval; };
00525 template<> struct to_signed_<unsigned long> { typedef long eval; };
00526 #ifdef MORE_HAVE_LONG_LONG
00527 template<> struct to_signed_<unsigned long long> { typedef long long eval; };
00528 #endif
00529
00530
00531 }
00532
00533 #endif