Partial ports to MSVC 6 & 7
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@29 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
95824ec34f
commit
f9fa5fbbd9
11 changed files with 3091 additions and 0 deletions
789
MSVC/1200/TypeList.h
Normal file
789
MSVC/1200/TypeList.h
Normal file
|
@ -0,0 +1,789 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: August 22, 2001
|
||||||
|
|
||||||
|
#ifndef TYPELIST_INC_
|
||||||
|
#define TYPELIST_INC_
|
||||||
|
|
||||||
|
#include "NullType.h"
|
||||||
|
#include "TypeManip.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macros TYPELIST_1, TYPELIST_2, ... TYPELIST_50
|
||||||
|
// Each takes a number of arguments equal to its numeric suffix
|
||||||
|
// The arguments are type names. TYPELIST_NN generates a typelist containing
|
||||||
|
// all types passed as arguments, in that order.
|
||||||
|
// Example: TYPELIST_2(char, int) generates a type containing char and int.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
|
||||||
|
|
||||||
|
#define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, TYPELIST_1(T2) >
|
||||||
|
|
||||||
|
#define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, TYPELIST_2(T2, T3) >
|
||||||
|
|
||||||
|
#define TYPELIST_4(T1, T2, T3, T4) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_3(T2, T3, T4) >
|
||||||
|
|
||||||
|
#define TYPELIST_5(T1, T2, T3, T4, T5) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >
|
||||||
|
|
||||||
|
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
|
||||||
|
|
||||||
|
#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >
|
||||||
|
|
||||||
|
#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
|
||||||
|
|
||||||
|
#define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
|
||||||
|
|
||||||
|
#define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
|
||||||
|
|
||||||
|
#define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
|
||||||
|
|
||||||
|
#define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12) >
|
||||||
|
|
||||||
|
#define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13) >
|
||||||
|
|
||||||
|
#define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14) >
|
||||||
|
|
||||||
|
#define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15) >
|
||||||
|
|
||||||
|
#define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16) >
|
||||||
|
|
||||||
|
#define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17) >
|
||||||
|
|
||||||
|
#define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18) >
|
||||||
|
|
||||||
|
#define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19) >
|
||||||
|
|
||||||
|
#define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) >
|
||||||
|
|
||||||
|
#define TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) >
|
||||||
|
|
||||||
|
#define TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) >
|
||||||
|
|
||||||
|
#define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) >
|
||||||
|
|
||||||
|
#define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) >
|
||||||
|
|
||||||
|
#define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25) >
|
||||||
|
|
||||||
|
#define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26) >
|
||||||
|
|
||||||
|
#define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27) >
|
||||||
|
|
||||||
|
#define TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28) >
|
||||||
|
|
||||||
|
#define TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29) >
|
||||||
|
|
||||||
|
#define TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) >
|
||||||
|
|
||||||
|
#define TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) >
|
||||||
|
|
||||||
|
#define TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) >
|
||||||
|
|
||||||
|
#define TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) >
|
||||||
|
|
||||||
|
#define TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_33(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) >
|
||||||
|
|
||||||
|
#define TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35) >
|
||||||
|
|
||||||
|
#define TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36) >
|
||||||
|
|
||||||
|
#define TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37) >
|
||||||
|
|
||||||
|
#define TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38) >
|
||||||
|
|
||||||
|
#define TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39) >
|
||||||
|
|
||||||
|
#define TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) >
|
||||||
|
|
||||||
|
#define TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) >
|
||||||
|
|
||||||
|
#define TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) >
|
||||||
|
|
||||||
|
#define TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) >
|
||||||
|
|
||||||
|
#define TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) >
|
||||||
|
|
||||||
|
#define TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45) >
|
||||||
|
|
||||||
|
#define TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45) >
|
||||||
|
|
||||||
|
#define TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47) >
|
||||||
|
|
||||||
|
#define TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48) >
|
||||||
|
|
||||||
|
#define TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49) >
|
||||||
|
|
||||||
|
#define TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) >
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Typelist
|
||||||
|
// The building block of typelists of any length
|
||||||
|
// Use it through the TYPELIST_NN macros
|
||||||
|
// Defines nested types:
|
||||||
|
// Head (first element, a non-typelist type by convention)
|
||||||
|
// Tail (second element, can be another typelist)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
struct Typelist
|
||||||
|
{
|
||||||
|
typedef T Head;
|
||||||
|
typedef U Tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace TL
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Length
|
||||||
|
// Computes the length of a typelist
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// Length<TList>::value
|
||||||
|
// returns a compile-time constant containing the length of TList, not counting
|
||||||
|
// the end terminator (which by convention is NullType)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <class TList> struct Length;
|
||||||
|
template <> struct Length<NullType>
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class TList>
|
||||||
|
struct Length
|
||||||
|
{
|
||||||
|
enum { value = 1 + Length<typename TList::Tail>::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template TypeAt
|
||||||
|
// Finds the type at a given index in a typelist
|
||||||
|
// Invocation (TList is a typelist and index is a compile-time integral
|
||||||
|
// constant):
|
||||||
|
// TypeAt<TList, index>::Result
|
||||||
|
// returns the type in position 'index' in TList
|
||||||
|
// If you pass an out-of-bounds index, the result is a compile-time error
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace TypeAt_ {
|
||||||
|
|
||||||
|
template<unsigned int i>
|
||||||
|
struct Index {
|
||||||
|
template<class TList>
|
||||||
|
struct Which {
|
||||||
|
typedef typename Index<i - 1>::Which<typename TList::Tail>::Result Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Index<0> {
|
||||||
|
template<class TList>
|
||||||
|
struct Which {
|
||||||
|
typedef typename TList::Head Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TypeAt_
|
||||||
|
|
||||||
|
template<class TList, unsigned int i>
|
||||||
|
struct TypeAt {
|
||||||
|
typedef typename TypeAt_::Index<i>::Which<TList>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template TypeAtNonStrict
|
||||||
|
// Finds the type at a given index in a typelist
|
||||||
|
// Invocations (TList is a typelist and index is a compile-time integral
|
||||||
|
// constant):
|
||||||
|
// a) TypeAt<TList, index>::Result
|
||||||
|
// returns the type in position 'index' in TList, or NullType if index is
|
||||||
|
// out-of-bounds
|
||||||
|
// b) TypeAt<TList, index, D>::Result
|
||||||
|
// returns the type in position 'index' in TList, or D if index is out-of-bounds
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace TypeAtNonStrict_ {
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct ListType;
|
||||||
|
|
||||||
|
template<unsigned int index>
|
||||||
|
struct Index;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ListType<NullType> {
|
||||||
|
template<unsigned int index, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
typedef DefaultType Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Index<0> {
|
||||||
|
template<class TList, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
typedef typename TList::Head Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned int index>
|
||||||
|
struct Index {
|
||||||
|
template<class TList, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
enum { isSameType = Conversion<NullType, typename TList::Tail>::sameType };
|
||||||
|
typedef typename Select<isSameType, NullType, typename Index<index - 1>::Remainder<typename TList::Tail, DefaultType>::Result>::Result Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct ListType {
|
||||||
|
template<unsigned int index, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
typedef typename Index<index>::Remainder<TList, DefaultType>::Result Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TypeAtNonStrict_
|
||||||
|
|
||||||
|
template<class TList, unsigned int index, typename DefaultType = NullType>
|
||||||
|
struct TypeAtNonStrict {
|
||||||
|
typedef typename TypeAtNonStrict_::ListType<TList>::Remainder<index, DefaultType>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TL
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IndexOf
|
||||||
|
// Finds the index of a type in a typelist
|
||||||
|
// Invocation (TList is a typelist and T is a type):
|
||||||
|
// IndexOf<TList, T>::value
|
||||||
|
// returns the position of T in TList, or NullType if T is not found in TList
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
namespace IndexOf_ {
|
||||||
|
|
||||||
|
template<typename TList>
|
||||||
|
struct Head {
|
||||||
|
typedef typename TList::Head Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Head<NullType> {
|
||||||
|
typedef void Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IsNull {
|
||||||
|
enum { value = -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IsTHead {
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TList, typename T>
|
||||||
|
struct IsNotTHead {
|
||||||
|
typedef typename TList::Tail Tail;
|
||||||
|
typedef typename Select<is_same<Tail, NullType>::result,
|
||||||
|
IsNull,
|
||||||
|
typename Select<is_same<typename Head<Tail>::Result, T>::result,
|
||||||
|
IsTHead, IsNotTHead<Tail, T>
|
||||||
|
>::Result
|
||||||
|
>::Result chooser;
|
||||||
|
enum { temp = chooser::value };
|
||||||
|
enum { value = temp == -1 ? -1 : 1 + temp };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TList, typename T>
|
||||||
|
struct IsNotNull {
|
||||||
|
typedef typename Select<is_same<typename TList::Head, T>::result,
|
||||||
|
IsTHead,
|
||||||
|
IsNotTHead<TList, T>
|
||||||
|
>::Result chooser;
|
||||||
|
enum { value = chooser::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace IndexOf_
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
namespace TL {
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct IndexOf {
|
||||||
|
private:
|
||||||
|
typedef typename Select<Private::is_same<TList, NullType>::result,
|
||||||
|
Private::IndexOf_::IsNull,
|
||||||
|
Private::IndexOf_::IsNotNull<TList, T>
|
||||||
|
>::Result chooser;
|
||||||
|
public:
|
||||||
|
enum { value = chooser::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Append
|
||||||
|
// Appends a type or a typelist to another
|
||||||
|
// Invocation (TList is a typelist and T is either a type or a typelist):
|
||||||
|
// Append<TList, T>::Result
|
||||||
|
// returns a typelist that is TList followed by T and NullType-terminated
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Append_ {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct Helper {
|
||||||
|
struct big { char i[2]; };
|
||||||
|
template<class Head, class Tail>
|
||||||
|
static char Test(const Typelist<Head, Tail>&);
|
||||||
|
static big Test(...);
|
||||||
|
static T makeT();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Append_
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct Append;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Append<NullType, NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct Append {
|
||||||
|
private:
|
||||||
|
enum { T_is_list = sizeof(Append_::Helper<T>::Test(Append_::Helper<T>::MakeT())) == sizeof(char) };
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
typedef typename Select<TList_is_null & T_is_list, T, NullType>::Result Result1;
|
||||||
|
typedef typename Select<TList_is_null & !T_is_list, Typelist<T, NullType>, Result1>::Result Result2;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !T_is_list, Typelist<typename TList::Head, typename Append<typename TList::Tail, T>::Result>, Result2>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Erase
|
||||||
|
// Erases the first occurence, if any, of a type in a typelist
|
||||||
|
// Invocation (TList is a typelist and T is a type):
|
||||||
|
// Erase<TList, T>::Result
|
||||||
|
// returns a typelist that is TList without the first occurence of T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct Erase {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, typename TList::Tail, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename Erase<typename TList::Tail, T>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template EraseAll
|
||||||
|
// Erases all first occurences, if any, of a type in a typelist
|
||||||
|
// Invocation (TList is a typelist and T is a type):
|
||||||
|
// EraseAll<TList, T>::Result
|
||||||
|
// returns a typelist that is TList without any occurence of T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct EraseAll {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, typename EraseAll<typename TList::Tail, T>::Result, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename EraseAll<typename TList::Tail, T>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template NoDuplicates
|
||||||
|
// Removes all duplicate types in a typelist
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// NoDuplicates<TList, T>::Result
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct NoDuplicates;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct NoDuplicates<NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct NoDuplicates {
|
||||||
|
private:
|
||||||
|
typedef typename NoDuplicates<typename TList::Tail>::Result L1;
|
||||||
|
typedef typename Erase<L1, typename TList::Head>::Result L2;
|
||||||
|
public:
|
||||||
|
typedef Typelist<typename TList::Head, L2> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Replace
|
||||||
|
// Replaces the first occurence of a type in a typelist, with another type
|
||||||
|
// Invocation (TList is a typelist, T, U are types):
|
||||||
|
// Replace<TList, T, U>::Result
|
||||||
|
// returns a typelist in which the first occurence of T is replaced with U
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T, class U>
|
||||||
|
struct Replace {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, Typelist<U, typename TList::Tail>, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename Replace<typename TList::Tail, T, U>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template ReplaceAll
|
||||||
|
// Replaces all occurences of a type in a typelist, with another type
|
||||||
|
// Invocation (TList is a typelist, T, U are types):
|
||||||
|
// Replace<TList, T, U>::Result
|
||||||
|
// returns a typelist in which all occurences of T is replaced with U
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T, class U>
|
||||||
|
struct ReplaceAll {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, Typelist<U, typename ReplaceAll<typename TList::Tail, T, U>::Result>, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename ReplaceAll<typename TList::Tail, T, U>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Reverse
|
||||||
|
// Reverses a typelist
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// Reverse<TList>::Result
|
||||||
|
// returns a typelist that is TList reversed
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct Reverse {
|
||||||
|
private:
|
||||||
|
enum { list_of_one = Conversion<typename TList::Tail, NullType>::sameType };
|
||||||
|
public:
|
||||||
|
typedef typename Select<list_of_one,
|
||||||
|
TList,
|
||||||
|
typename Append<typename Reverse<typename TList::Tail>::Result,
|
||||||
|
typename TList::Head
|
||||||
|
>::Result
|
||||||
|
>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template MostDerived
|
||||||
|
// Finds the type in a typelist that is the most derived from a given type
|
||||||
|
// Invocation (TList is a typelist, T is a type):
|
||||||
|
// Replace<TList, T>::Result
|
||||||
|
// returns the type in TList that's the most derived from T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct MostDerived {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
typedef typename Select<TList_is_null, T, typename MostDerived<typename TList::Tail, T>::Result>::Result Candidate;
|
||||||
|
public:
|
||||||
|
typedef typename Select<TList_is_null, T,
|
||||||
|
typename Select<SUPERSUBCLASS(Candidate, typename TList::Head),
|
||||||
|
typename TList::Head, Candidate
|
||||||
|
>::Result
|
||||||
|
>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template DerivedToFront
|
||||||
|
// Arranges the types in a typelist so that the most derived types appear first
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// DerivedToFront<TList>::Result
|
||||||
|
// returns the reordered TList
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace DerivedToFront_ {
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct ListType {
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ListType<NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace DerivedToFront_
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct DerivedToFront;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct DerivedToFront<NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct DerivedToFront {
|
||||||
|
private:
|
||||||
|
typedef typename MostDerived<typename TList::Tail,
|
||||||
|
typename TList::Head>::Result TheMostDerived;
|
||||||
|
typedef typename Replace<typename TList::Tail, TheMostDerived,
|
||||||
|
typename TList::Head>::Result L;
|
||||||
|
public:
|
||||||
|
typedef Typelist<TheMostDerived, L> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TL
|
||||||
|
|
||||||
|
} // namespace Loki
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27
|
||||||
|
// (credit due to Dave Taylor)
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
// August 22, 2001: ported by Jonathan H Lundquist to MSVC
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPELIST_INC_
|
||||||
|
|
268
MSVC/1200/TypeManip.h
Normal file
268
MSVC/1200/TypeManip.h
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: August 22, 2001
|
||||||
|
|
||||||
|
#ifndef TYPEMANIP_INC_
|
||||||
|
#define TYPEMANIP_INC_
|
||||||
|
|
||||||
|
namespace Loki {
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
struct big { char c[2]; };
|
||||||
|
|
||||||
|
struct any {
|
||||||
|
template<typename T>
|
||||||
|
any(const T&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Int2Type
|
||||||
|
// Converts each integral constant into a unique type
|
||||||
|
// Invocation: Int2Type<v> where v is a compile-time constant integral
|
||||||
|
// Defines 'value', an enum that evaluates to v
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <int v>
|
||||||
|
struct Int2Type
|
||||||
|
{
|
||||||
|
enum { value = v };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Type2Type
|
||||||
|
// Converts each type into a unique, insipid type
|
||||||
|
// Invocation Type2Type<T> where T is a type
|
||||||
|
// Defines the type OriginalType which maps back to T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Type2Type
|
||||||
|
{
|
||||||
|
typedef T OriginalType;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Select
|
||||||
|
// Selects one of two types based upon a boolean constant
|
||||||
|
// Invocation: Select<flag, T, U>::Result
|
||||||
|
// where:
|
||||||
|
// flag is a compile-time boolean constant
|
||||||
|
// T and U are types
|
||||||
|
// Result evaluates to T if flag is true, and to U otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
namespace Select_ {
|
||||||
|
|
||||||
|
struct ChooseT {
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Choose {
|
||||||
|
typedef T Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChooseU {
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Choose {
|
||||||
|
typedef U Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool flag>
|
||||||
|
struct Selector {
|
||||||
|
typedef ChooseT Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Selector<false> {
|
||||||
|
typedef ChooseU Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Select_
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
template<bool flag, typename T, typename U>
|
||||||
|
struct Select {
|
||||||
|
private:
|
||||||
|
typedef typename Private::Select_::Selector<flag>::Result selector;
|
||||||
|
public:
|
||||||
|
typedef typename selector::Choose<T, U>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_void {
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct is_void<void> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace is_same_ {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
char test_same(T*, T*);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
big test_same(T*, any);
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct is_same_imp {
|
||||||
|
static T t;
|
||||||
|
static U u;
|
||||||
|
enum { result = sizeof(test_same(&t, &u)) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace is_same_
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct is_same {
|
||||||
|
enum { voidT = is_void<T>::value };
|
||||||
|
enum { voidU = is_void<U>::value };
|
||||||
|
struct BothVoid {
|
||||||
|
enum { result = 1 };
|
||||||
|
};
|
||||||
|
struct OneVoid {
|
||||||
|
enum { result = 0 };
|
||||||
|
};
|
||||||
|
typedef typename Select<voidT & voidU,
|
||||||
|
BothVoid,
|
||||||
|
typename Select<voidT | voidU,
|
||||||
|
OneVoid,
|
||||||
|
is_same_::is_same_imp<T, U>
|
||||||
|
>::Result
|
||||||
|
>::Result tester;
|
||||||
|
enum { result = tester::result };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Conversion
|
||||||
|
// Figures out the conversion relationships between two types
|
||||||
|
// Invocations (T and U are types):
|
||||||
|
// a) Conversion<T, U>::exists
|
||||||
|
// returns (at compile time) true if there is an implicit conversion from T
|
||||||
|
// to U (example: Derived to Base)
|
||||||
|
// b) Conversion<T, U>::exists2Way
|
||||||
|
// returns (at compile time) true if there are both conversions from T
|
||||||
|
// to U and from U to T (example: int to char and back)
|
||||||
|
// c) Conversion<T, U>::sameType
|
||||||
|
// returns (at compile time) true if T and U represent the same type
|
||||||
|
//
|
||||||
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
namespace Conversion_ {
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4181)
|
||||||
|
#pragma warning(disable:4800)
|
||||||
|
#pragma warning(disable:4244)
|
||||||
|
#endif
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Determine {
|
||||||
|
template<typename X, typename Y>
|
||||||
|
struct tester {
|
||||||
|
static char test(X, Y);
|
||||||
|
static big test(any, any);
|
||||||
|
};
|
||||||
|
static T t;
|
||||||
|
static U u;
|
||||||
|
enum { exists = sizeof(tester<T, U>::test(t, t)) == sizeof(char) };
|
||||||
|
enum { exists2Way = exists & (sizeof(tester<U, T>::test(u, u)) == sizeof(char)) };
|
||||||
|
enum { sameType = exists2Way & is_same<T, U>::result };
|
||||||
|
};
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace Conversion_
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Conversion {
|
||||||
|
private:
|
||||||
|
enum { voidT = Private::is_void<T>::value };
|
||||||
|
enum { voidU = Private::is_void<U>::value };
|
||||||
|
|
||||||
|
struct both_void {
|
||||||
|
enum { exists = 1, exists2Way = 1, sameType = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct one_void {
|
||||||
|
enum { exists = 1, exists2Way = 0, sameType = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef typename Select<voidT & voidU,
|
||||||
|
both_void,
|
||||||
|
typename Select<voidT | voidU,
|
||||||
|
one_void,
|
||||||
|
Private::Conversion_::Determine<T, U>
|
||||||
|
>::Result
|
||||||
|
>::Result Chooser;
|
||||||
|
public:
|
||||||
|
enum { exists = Chooser::exists };
|
||||||
|
enum { exists2Way = Chooser::exists2Way };
|
||||||
|
enum { sameType = Chooser::sameType };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Loki
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macro SUPERSUBCLASS
|
||||||
|
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
||||||
|
// Returns true if B is a public base of D, or if B and D are aliases of the
|
||||||
|
// same type.
|
||||||
|
//
|
||||||
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define SUPERSUBCLASS(T, U) \
|
||||||
|
(::Loki::Conversion<const U*, const T*>::exists && \
|
||||||
|
!::Loki::Conversion<const T*, const void*>::sameType)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macro SUPERSUBCLASS
|
||||||
|
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
||||||
|
// Returns true if B is a public base of D.
|
||||||
|
//
|
||||||
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define SUPERSUBCLASS_STRICT(T, U) \
|
||||||
|
(SUPERSUBCLASS(T, U) && \
|
||||||
|
!::Loki::Conversion<const T, const U>::sameType)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
// August 22, 2001: ported by Jonathan H Lundquist to MSVC
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPEMANIP_INC_
|
374
MSVC/1200/TypeTraits.h
Normal file
374
MSVC/1200/TypeTraits.h
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
#ifndef TYPETRAITS_INC_
|
||||||
|
#define TYPETRAITS_INC_
|
||||||
|
|
||||||
|
#include "Typelist.h"
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IsCustomUnsignedInt
|
||||||
|
// Offers a means to integrate nonstandard built-in unsigned integral types
|
||||||
|
// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
|
||||||
|
// class template defined below.
|
||||||
|
// Invocation: IsCustomUnsignedInt<T> where T is any type
|
||||||
|
// Defines 'value', an enum that is 1 iff T is a custom built-in unsigned
|
||||||
|
// integral type
|
||||||
|
// Specialize this class template for nonstandard unsigned integral types
|
||||||
|
// and define value = 1 in those specializations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsCustomUnsignedInt
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
template<>
|
||||||
|
struct IsCustomUnsignedInt<unsigned __int64> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IsCustomSignedInt
|
||||||
|
// Offers a means to integrate nonstandard built-in unsigned integral types
|
||||||
|
// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
|
||||||
|
// class template defined below.
|
||||||
|
// Invocation: IsCustomSignedInt<T> where T is any type
|
||||||
|
// Defines 'value', an enum that is 1 iff T is a custom built-in signed
|
||||||
|
// integral type
|
||||||
|
// Specialize this class template for nonstandard unsigned integral types
|
||||||
|
// and define value = 1 in those specializations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsCustomSignedInt
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
template<>
|
||||||
|
struct IsCustomSignedInt<__int64> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IsCustomFloat
|
||||||
|
// Offers a means to integrate nonstandard floating point types with the
|
||||||
|
// TypeTraits class template defined below.
|
||||||
|
// Invocation: IsCustomFloat<T> where T is any type
|
||||||
|
// Defines 'value', an enum that is 1 iff T is a custom built-in
|
||||||
|
// floating point type
|
||||||
|
// Specialize this class template for nonstandard unsigned integral types
|
||||||
|
// and define value = 1 in those specializations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsCustomFloat
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper types for class template TypeTraits defined below
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
typedef TYPELIST_4(unsigned char, unsigned short int,
|
||||||
|
unsigned int, unsigned long int) StdUnsignedInts;
|
||||||
|
typedef TYPELIST_4(signed char, short int,
|
||||||
|
int, long int) StdSignedInts;
|
||||||
|
typedef TYPELIST_3(bool, char, wchar_t) StdOtherInts;
|
||||||
|
typedef TYPELIST_3(float, double, long double) StdFloats;
|
||||||
|
|
||||||
|
char test_ptr(const volatile void*, const volatile void*);
|
||||||
|
big test_ptr(any, any);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* unrefptr(T&);
|
||||||
|
|
||||||
|
char test_const(const volatile void*);
|
||||||
|
big test_const(volatile void*);
|
||||||
|
char test_volatile(const volatile void*);
|
||||||
|
big test_volatile(const void*);
|
||||||
|
|
||||||
|
template<typename V, typename X>
|
||||||
|
char test_mptr(V X::*, any);
|
||||||
|
|
||||||
|
big test_mptr(any, any);
|
||||||
|
|
||||||
|
template<bool isReference>
|
||||||
|
struct AddReferenceImp {
|
||||||
|
template<typename T>
|
||||||
|
struct Imp {
|
||||||
|
typedef T Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AddReferenceImp<false> {
|
||||||
|
template<typename T>
|
||||||
|
struct Imp {
|
||||||
|
typedef T& Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct PointerTraits
|
||||||
|
{
|
||||||
|
enum { result = false };
|
||||||
|
typedef NullType PointeeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct PointerTraits<U*>
|
||||||
|
{
|
||||||
|
enum { result = true };
|
||||||
|
typedef U PointeeType;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct PointerTraits {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
typedef void PointeeType; // unable to determine correctly
|
||||||
|
enum { result = sizeof(Private::test_ptr(&u, u)) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct PointerTraits<void> {
|
||||||
|
typedef void PointeeType;
|
||||||
|
enum { result = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct ReferenceTraits
|
||||||
|
{
|
||||||
|
enum { result = false };
|
||||||
|
typedef U ReferredType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct ReferenceTraits<U&>
|
||||||
|
{
|
||||||
|
enum { result = true };
|
||||||
|
typedef U ReferredType;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4181)
|
||||||
|
template<typename U>
|
||||||
|
struct ReferenceTraits {
|
||||||
|
typedef U const volatile cv_u;
|
||||||
|
static cv_u u;
|
||||||
|
public:
|
||||||
|
enum { result = (sizeof(Private::test_const(&u)) != sizeof(char))
|
||||||
|
| (sizeof(Private::test_volatile(&u)) != sizeof(char)) };
|
||||||
|
typedef void ReferredType; // unable to determine correctly
|
||||||
|
};
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ReferenceTraits<void> {
|
||||||
|
enum { result = 0 };
|
||||||
|
typedef void ReferredType;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct PToMTraits
|
||||||
|
{
|
||||||
|
enum { result = false };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U, class V>
|
||||||
|
struct PToMTraits<U V::*>
|
||||||
|
{
|
||||||
|
enum { result = true };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct PToMTraits {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
enum { result = sizeof(Private::test_mptr(u, &u)) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct PToMTraits<void> {
|
||||||
|
enum { result = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct UnConst
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isConst = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct UnConst<const U>
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isConst = 1 };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct UnConst {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
typedef void Result; // unable to determine correctly
|
||||||
|
enum { isConst = sizeof(Private::test_const(Private::unrefptr(u))) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct UnConst<void> {
|
||||||
|
typedef void Result;
|
||||||
|
enum { isConst = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct UnVolatile
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isVolatile = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct UnVolatile<volatile U>
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isVolatile = 1 };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct UnVolatile {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
typedef void Result; // unable to determine correctly
|
||||||
|
enum { isVolatile = sizeof(Private::test_volatile(Private::unrefptr(u))) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct UnVolatile<void> {
|
||||||
|
typedef void Result;
|
||||||
|
enum { isVolatile = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
template<typename U, bool isReference>
|
||||||
|
struct AddReference {
|
||||||
|
typedef typename Private::AddReferenceImp<isReference>::template Imp<U>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AddReference<void, false> {
|
||||||
|
typedef void Result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template TypeTraits
|
||||||
|
// Figures out various properties of any given type
|
||||||
|
// Invocations (T is a type):
|
||||||
|
// a) TypeTraits<T>::isPointer
|
||||||
|
// returns (at compile time) true if T is a pointer type
|
||||||
|
// b) TypeTraits<T>::PointeeType
|
||||||
|
// returns the type to which T points is T is a pointer type, NullType otherwise
|
||||||
|
// a) TypeTraits<T>::isReference
|
||||||
|
// returns (at compile time) true if T is a reference type
|
||||||
|
// b) TypeTraits<T>::ReferredType
|
||||||
|
// returns the type to which T refers is T is a reference type, NullType
|
||||||
|
// otherwise
|
||||||
|
// c) TypeTraits<T>::isMemberPointer
|
||||||
|
// returns (at compile time) true if T is a pointer to member type
|
||||||
|
// d) TypeTraits<T>::isStdUnsignedInt
|
||||||
|
// returns (at compile time) true if T is a standard unsigned integral type
|
||||||
|
// e) TypeTraits<T>::isStdSignedInt
|
||||||
|
// returns (at compile time) true if T is a standard signed integral type
|
||||||
|
// f) TypeTraits<T>::isStdIntegral
|
||||||
|
// returns (at compile time) true if T is a standard integral type
|
||||||
|
// g) TypeTraits<T>::isStdFloat
|
||||||
|
// returns (at compile time) true if T is a standard floating-point type
|
||||||
|
// h) TypeTraits<T>::isStdArith
|
||||||
|
// returns (at compile time) true if T is a standard arithmetic type
|
||||||
|
// i) TypeTraits<T>::isStdFundamental
|
||||||
|
// returns (at compile time) true if T is a standard fundamental type
|
||||||
|
// j) TypeTraits<T>::isUnsignedInt
|
||||||
|
// returns (at compile time) true if T is a unsigned integral type
|
||||||
|
// k) TypeTraits<T>::isSignedInt
|
||||||
|
// returns (at compile time) true if T is a signed integral type
|
||||||
|
// l) TypeTraits<T>::isIntegral
|
||||||
|
// returns (at compile time) true if T is a integral type
|
||||||
|
// m) TypeTraits<T>::isFloat
|
||||||
|
// returns (at compile time) true if T is a floating-point type
|
||||||
|
// n) TypeTraits<T>::isArith
|
||||||
|
// returns (at compile time) true if T is a arithmetic type
|
||||||
|
// o) TypeTraits<T>::isFundamental
|
||||||
|
// returns (at compile time) true if T is a fundamental type
|
||||||
|
// p) TypeTraits<T>::ParameterType
|
||||||
|
// returns the optimal type to be used as a parameter for functions that take Ts
|
||||||
|
// q) TypeTraits<T>::isConst
|
||||||
|
// returns (at compile time) true if T is a const-qualified type
|
||||||
|
// r) TypeTraits<T>::NonConstType
|
||||||
|
// removes the 'const' qualifier from T, if any
|
||||||
|
// s) TypeTraits<T>::isVolatile
|
||||||
|
// returns (at compile time) true if T is a volatile-qualified type
|
||||||
|
// t) TypeTraits<T>::NonVolatileType
|
||||||
|
// removes the 'volatile' qualifier from T, if any
|
||||||
|
// u) TypeTraits<T>::UnqualifiedType
|
||||||
|
// removes both the 'const' and 'volatile' qualifiers from T, if any
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TypeTraits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { isPointer = Private::PointerTraits<T>::result };
|
||||||
|
typedef typename Private::PointerTraits<T>::PointeeType PointeeType;
|
||||||
|
|
||||||
|
enum { isReference = Private::ReferenceTraits<T>::result };
|
||||||
|
typedef typename Private::ReferenceTraits<T>::ReferredType ReferredType;
|
||||||
|
|
||||||
|
enum { isMemberPointer = Private::PToMTraits<T>::result };
|
||||||
|
|
||||||
|
enum { isStdUnsignedInt =
|
||||||
|
TL::IndexOf<Private::StdUnsignedInts, T>::value >= 0 };
|
||||||
|
enum { isStdSignedInt =
|
||||||
|
TL::IndexOf<Private::StdSignedInts, T>::value >= 0 };
|
||||||
|
enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
|
||||||
|
TL::IndexOf<Private::StdOtherInts, T>::value >= 0 };
|
||||||
|
enum { isStdFloat = TL::IndexOf<Private::StdFloats, T>::value >= 0 };
|
||||||
|
enum { isStdArith = isStdIntegral || isStdFloat };
|
||||||
|
enum { isStdFundamental = isStdArith || isStdFloat ||
|
||||||
|
Conversion<T, void>::sameType };
|
||||||
|
|
||||||
|
enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<T>::value };
|
||||||
|
enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<T>::value };
|
||||||
|
enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
|
||||||
|
enum { isFloat = isStdFloat || IsCustomFloat<T>::value };
|
||||||
|
enum { isArith = isIntegral || isFloat };
|
||||||
|
enum { isFundamental = isStdFundamental || isArith || isFloat };
|
||||||
|
|
||||||
|
typedef typename Select<isStdArith || isPointer || isMemberPointer, T,
|
||||||
|
typename Private::AddReference<T, isReference>::Result
|
||||||
|
>::Result ParameterType;
|
||||||
|
|
||||||
|
enum { isConst = Private::UnConst<T>::isConst };
|
||||||
|
typedef typename Private::UnConst<T>::Result NonConstType;
|
||||||
|
enum { isVolatile = Private::UnVolatile<T>::isVolatile };
|
||||||
|
typedef typename Private::UnVolatile<T>::Result NonVolatileType;
|
||||||
|
typedef typename Private::UnVolatile<typename Private::UnConst<T>::Result>::Result
|
||||||
|
UnqualifiedType;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
// August 22, 2001: ported by Jonathan H Lundquist to MSVC
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPETRAITS_INC_
|
2
MSVC/1200/portby.txt
Normal file
2
MSVC/1200/portby.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
MSVC6
|
||||||
|
Jonathan H. Lundquist
|
37
MSVC/1300/NullType.h
Normal file
37
MSVC/1300/NullType.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: June 20, 2001
|
||||||
|
|
||||||
|
#ifndef NULLTYPE_INC_
|
||||||
|
#define NULLTYPE_INC_
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class NullType
|
||||||
|
// Used as a placeholder for "no type here"
|
||||||
|
// Useful as an end marker in typelists
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class NullType {};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // NULLTYPE_INC_
|
119
MSVC/1300/TypeInfo.h
Normal file
119
MSVC/1300/TypeInfo.h
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: June 20, 2001
|
||||||
|
|
||||||
|
// MKH
|
||||||
|
// Copy of TypeInfo.h made to that #include "Typelist.h" gets the local
|
||||||
|
// flavor instead of the reference implementation
|
||||||
|
// Added a couple of #pramga warning(disable:4800) becase we just don't care.
|
||||||
|
|
||||||
|
#ifndef TYPEINFO_INC_
|
||||||
|
#define TYPEINFO_INC_
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <cassert>
|
||||||
|
#include "Typelist.h"
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class TypeInfo
|
||||||
|
// Purpose: offer a first-class, comparable wrapper over std::type_info
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TypeInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
TypeInfo(); // needed for containers
|
||||||
|
TypeInfo(const std::type_info&); // non-explicit
|
||||||
|
|
||||||
|
// Access for the wrapped std::type_info
|
||||||
|
const std::type_info& Get() const;
|
||||||
|
// Compatibility functions
|
||||||
|
bool before(const TypeInfo& rhs) const;
|
||||||
|
const char* name() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::type_info* pInfo_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
inline TypeInfo::TypeInfo()
|
||||||
|
{
|
||||||
|
class Nil {};
|
||||||
|
pInfo_ = &typeid(Nil);
|
||||||
|
assert(pInfo_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TypeInfo::TypeInfo(const std::type_info& ti)
|
||||||
|
: pInfo_(&ti)
|
||||||
|
{ assert(pInfo_); }
|
||||||
|
|
||||||
|
inline bool TypeInfo::before(const TypeInfo& rhs) const
|
||||||
|
{
|
||||||
|
assert(pInfo_);
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4800)
|
||||||
|
return pInfo_->before(*rhs.pInfo_);
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::type_info& TypeInfo::Get() const
|
||||||
|
{
|
||||||
|
assert(pInfo_);
|
||||||
|
return *pInfo_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* TypeInfo::name() const
|
||||||
|
{
|
||||||
|
assert(pInfo_);
|
||||||
|
return pInfo_->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison operators
|
||||||
|
|
||||||
|
inline bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
|
||||||
|
{
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4800)
|
||||||
|
return lhs.Get() == rhs.Get();
|
||||||
|
#pragma warning(pop)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const TypeInfo& lhs, const TypeInfo& rhs)
|
||||||
|
{ return lhs.before(rhs); }
|
||||||
|
|
||||||
|
inline bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
|
||||||
|
{ return !(lhs == rhs); }
|
||||||
|
|
||||||
|
inline bool operator>(const TypeInfo& lhs, const TypeInfo& rhs)
|
||||||
|
{ return rhs < lhs; }
|
||||||
|
|
||||||
|
inline bool operator<=(const TypeInfo& lhs, const TypeInfo& rhs)
|
||||||
|
{ return !(lhs > rhs); }
|
||||||
|
|
||||||
|
inline bool operator>=(const TypeInfo& lhs, const TypeInfo& rhs)
|
||||||
|
{ return !(lhs < rhs); }
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPEINFO_INC_
|
806
MSVC/1300/TypeList.h
Normal file
806
MSVC/1300/TypeList.h
Normal file
|
@ -0,0 +1,806 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: August 22, 2001
|
||||||
|
|
||||||
|
#ifndef TYPELIST_INC_
|
||||||
|
#define TYPELIST_INC_
|
||||||
|
|
||||||
|
#include "NullType.h"
|
||||||
|
#include "TypeManip.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macros TYPELIST_1, TYPELIST_2, ... TYPELIST_50
|
||||||
|
// Each takes a number of arguments equal to its numeric suffix
|
||||||
|
// The arguments are type names. TYPELIST_NN generates a typelist containing
|
||||||
|
// all types passed as arguments, in that order.
|
||||||
|
// Example: TYPELIST_2(char, int) generates a type containing char and int.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
|
||||||
|
|
||||||
|
#define TYPELIST_2(T1, T2) ::Loki::Typelist<T1, TYPELIST_1(T2) >
|
||||||
|
|
||||||
|
#define TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, TYPELIST_2(T2, T3) >
|
||||||
|
|
||||||
|
#define TYPELIST_4(T1, T2, T3, T4) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_3(T2, T3, T4) >
|
||||||
|
|
||||||
|
#define TYPELIST_5(T1, T2, T3, T4, T5) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_4(T2, T3, T4, T5) >
|
||||||
|
|
||||||
|
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
|
||||||
|
|
||||||
|
#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >
|
||||||
|
|
||||||
|
#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
|
||||||
|
|
||||||
|
#define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
|
||||||
|
|
||||||
|
#define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
|
||||||
|
|
||||||
|
#define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
|
||||||
|
|
||||||
|
#define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12) >
|
||||||
|
|
||||||
|
#define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13) >
|
||||||
|
|
||||||
|
#define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14) >
|
||||||
|
|
||||||
|
#define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15) >
|
||||||
|
|
||||||
|
#define TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16) >
|
||||||
|
|
||||||
|
#define TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17) >
|
||||||
|
|
||||||
|
#define TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18) >
|
||||||
|
|
||||||
|
#define TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19) >
|
||||||
|
|
||||||
|
#define TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) >
|
||||||
|
|
||||||
|
#define TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) >
|
||||||
|
|
||||||
|
#define TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) >
|
||||||
|
|
||||||
|
#define TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) >
|
||||||
|
|
||||||
|
#define TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) >
|
||||||
|
|
||||||
|
#define TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25) >
|
||||||
|
|
||||||
|
#define TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26) >
|
||||||
|
|
||||||
|
#define TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27) >
|
||||||
|
|
||||||
|
#define TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28) >
|
||||||
|
|
||||||
|
#define TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29) >
|
||||||
|
|
||||||
|
#define TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) >
|
||||||
|
|
||||||
|
#define TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) >
|
||||||
|
|
||||||
|
#define TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) >
|
||||||
|
|
||||||
|
#define TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) >
|
||||||
|
|
||||||
|
#define TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_33(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) >
|
||||||
|
|
||||||
|
#define TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35) >
|
||||||
|
|
||||||
|
#define TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36) >
|
||||||
|
|
||||||
|
#define TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37) >
|
||||||
|
|
||||||
|
#define TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38) >
|
||||||
|
|
||||||
|
#define TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39) >
|
||||||
|
|
||||||
|
#define TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) >
|
||||||
|
|
||||||
|
#define TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) >
|
||||||
|
|
||||||
|
#define TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) >
|
||||||
|
|
||||||
|
#define TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) >
|
||||||
|
|
||||||
|
#define TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) >
|
||||||
|
|
||||||
|
#define TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45) >
|
||||||
|
|
||||||
|
#define TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45) >
|
||||||
|
|
||||||
|
#define TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47) >
|
||||||
|
|
||||||
|
#define TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48) >
|
||||||
|
|
||||||
|
#define TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49) >
|
||||||
|
|
||||||
|
#define TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \
|
||||||
|
::Loki::Typelist<T1, TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
|
||||||
|
T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
|
||||||
|
T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
|
||||||
|
T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
|
||||||
|
T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) >
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Typelist
|
||||||
|
// The building block of typelists of any length
|
||||||
|
// Use it through the TYPELIST_NN macros
|
||||||
|
// Defines nested types:
|
||||||
|
// Head (first element, a non-typelist type by convention)
|
||||||
|
// Tail (second element, can be another typelist)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
struct Typelist
|
||||||
|
{
|
||||||
|
typedef T Head;
|
||||||
|
typedef U Tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace TL
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Length
|
||||||
|
// Computes the length of a typelist
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// Length<TList>::value
|
||||||
|
// returns a compile-time constant containing the length of TList, not counting
|
||||||
|
// the end terminator (which by convention is NullType)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//*
|
||||||
|
namespace Length_
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct HeadLength
|
||||||
|
{
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct HeadLength<NullType>
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
}//ns TL::Length_
|
||||||
|
//*/
|
||||||
|
template <class TList> struct Length;
|
||||||
|
template <> struct Length<NullType>
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class TList>
|
||||||
|
struct Length
|
||||||
|
{
|
||||||
|
enum { value = (Length_::HeadLength<typename TList::Head>::value
|
||||||
|
+
|
||||||
|
Length<typename TList::Tail>::value) };
|
||||||
|
};
|
||||||
|
//*/
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template TypeAt
|
||||||
|
// Finds the type at a given index in a typelist
|
||||||
|
// Invocation (TList is a typelist and index is a compile-time integral
|
||||||
|
// constant):
|
||||||
|
// TypeAt<TList, index>::Result
|
||||||
|
// returns the type in position 'index' in TList
|
||||||
|
// If you pass an out-of-bounds index, the result is a compile-time error
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace TypeAt_ {
|
||||||
|
|
||||||
|
template<unsigned int i>
|
||||||
|
struct Index {
|
||||||
|
template<class TList>
|
||||||
|
struct Which {
|
||||||
|
typedef typename Index<i - 1>::Which<typename TList::Tail>::Result Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Index<0> {
|
||||||
|
template<class TList>
|
||||||
|
struct Which {
|
||||||
|
typedef typename TList::Head Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TypeAt_
|
||||||
|
|
||||||
|
template<class TList, unsigned int i>
|
||||||
|
struct TypeAt {
|
||||||
|
typedef typename TypeAt_::Index<i>::Which<TList>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template TypeAtNonStrict
|
||||||
|
// Finds the type at a given index in a typelist
|
||||||
|
// Invocations (TList is a typelist and index is a compile-time integral
|
||||||
|
// constant):
|
||||||
|
// a) TypeAt<TList, index>::Result
|
||||||
|
// returns the type in position 'index' in TList, or NullType if index is
|
||||||
|
// out-of-bounds
|
||||||
|
// b) TypeAt<TList, index, D>::Result
|
||||||
|
// returns the type in position 'index' in TList, or D if index is out-of-bounds
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace TypeAtNonStrict_ {
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct ListType;
|
||||||
|
|
||||||
|
template<unsigned int index>
|
||||||
|
struct Index;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ListType<NullType> {
|
||||||
|
template<unsigned int index, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
typedef DefaultType Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Index<0> {
|
||||||
|
template<class TList, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
typedef typename TList::Head Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<unsigned int index>
|
||||||
|
struct Index {
|
||||||
|
template<class TList, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
enum { isSameType = Conversion<NullType, typename TList::Tail>::sameType };
|
||||||
|
typedef typename Select<isSameType, NullType, typename Index<index - 1>::Remainder<typename TList::Tail, DefaultType>::Result>::Result Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct ListType {
|
||||||
|
template<unsigned int index, typename DefaultType>
|
||||||
|
struct Remainder {
|
||||||
|
typedef typename Index<index>::Remainder<TList, DefaultType>::Result Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TypeAtNonStrict_
|
||||||
|
|
||||||
|
template<class TList, unsigned int index, typename DefaultType = NullType>
|
||||||
|
struct TypeAtNonStrict {
|
||||||
|
typedef typename TypeAtNonStrict_::ListType<TList>::Remainder<index, DefaultType>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TL
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IndexOf
|
||||||
|
// Finds the index of a type in a typelist
|
||||||
|
// Invocation (TList is a typelist and T is a type):
|
||||||
|
// IndexOf<TList, T>::value
|
||||||
|
// returns the position of T in TList, or NullType if T is not found in TList
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
namespace IndexOf_ {
|
||||||
|
|
||||||
|
template<typename TList>
|
||||||
|
struct Head {
|
||||||
|
typedef typename TList::Head Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Head<NullType> {
|
||||||
|
typedef void Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IsNull {
|
||||||
|
enum { value = -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IsTHead {
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TList, typename T>
|
||||||
|
struct IsNotTHead {
|
||||||
|
typedef typename TList::Tail Tail;
|
||||||
|
typedef typename Select<is_same<Tail, NullType>::result,
|
||||||
|
IsNull,
|
||||||
|
typename Select<is_same<typename Head<Tail>::Result, T>::result,
|
||||||
|
IsTHead, IsNotTHead<Tail, T>
|
||||||
|
>::Result
|
||||||
|
>::Result chooser;
|
||||||
|
enum { temp = chooser::value };
|
||||||
|
enum { value = temp == -1 ? -1 : 1 + temp };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TList, typename T>
|
||||||
|
struct IsNotNull {
|
||||||
|
typedef typename Select<is_same<typename TList::Head, T>::result,
|
||||||
|
IsTHead,
|
||||||
|
IsNotTHead<TList, T>
|
||||||
|
>::Result chooser;
|
||||||
|
enum { value = chooser::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace IndexOf_
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
namespace TL {
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct IndexOf {
|
||||||
|
private:
|
||||||
|
typedef typename Select<Private::is_same<TList, NullType>::result,
|
||||||
|
Private::IndexOf_::IsNull,
|
||||||
|
Private::IndexOf_::IsNotNull<TList, T>
|
||||||
|
>::Result chooser;
|
||||||
|
public:
|
||||||
|
enum { value = chooser::value };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Append
|
||||||
|
// Appends a type or a typelist to another
|
||||||
|
// Invocation (TList is a typelist and T is either a type or a typelist):
|
||||||
|
// Append<TList, T>::Result
|
||||||
|
// returns a typelist that is TList followed by T and NullType-terminated
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Append_ {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct Helper {
|
||||||
|
struct big { char i[2]; };
|
||||||
|
template<class Head, class Tail>
|
||||||
|
static char Test(const Typelist<Head, Tail>&);
|
||||||
|
static big Test(...);
|
||||||
|
static T makeT();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Append_
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct Append;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Append<NullType, NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct Append {
|
||||||
|
private:
|
||||||
|
enum { T_is_list = sizeof(Append_::Helper<T>::Test(Append_::Helper<T>::MakeT())) == sizeof(char) };
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
typedef typename Select<TList_is_null & T_is_list, T, NullType>::Result Result1;
|
||||||
|
typedef typename Select<TList_is_null & !T_is_list, Typelist<T, NullType>, Result1>::Result Result2;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !T_is_list, Typelist<typename TList::Head, typename Append<typename TList::Tail, T>::Result>, Result2>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Erase
|
||||||
|
// Erases the first occurence, if any, of a type in a typelist
|
||||||
|
// Invocation (TList is a typelist and T is a type):
|
||||||
|
// Erase<TList, T>::Result
|
||||||
|
// returns a typelist that is TList without the first occurence of T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct Erase {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, typename TList::Tail, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename Erase<typename TList::Tail, T>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template EraseAll
|
||||||
|
// Erases all first occurences, if any, of a type in a typelist
|
||||||
|
// Invocation (TList is a typelist and T is a type):
|
||||||
|
// EraseAll<TList, T>::Result
|
||||||
|
// returns a typelist that is TList without any occurence of T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct EraseAll {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, typename EraseAll<typename TList::Tail, T>::Result, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename EraseAll<typename TList::Tail, T>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template NoDuplicates
|
||||||
|
// Removes all duplicate types in a typelist
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// NoDuplicates<TList, T>::Result
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct NoDuplicates;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct NoDuplicates<NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct NoDuplicates {
|
||||||
|
private:
|
||||||
|
typedef typename NoDuplicates<typename TList::Tail>::Result L1;
|
||||||
|
typedef typename Erase<L1, typename TList::Head>::Result L2;
|
||||||
|
public:
|
||||||
|
typedef Typelist<typename TList::Head, L2> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Replace
|
||||||
|
// Replaces the first occurence of a type in a typelist, with another type
|
||||||
|
// Invocation (TList is a typelist, T, U are types):
|
||||||
|
// Replace<TList, T, U>::Result
|
||||||
|
// returns a typelist in which the first occurence of T is replaced with U
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T, class U>
|
||||||
|
struct Replace {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, Typelist<U, typename TList::Tail>, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename Replace<typename TList::Tail, T, U>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template ReplaceAll
|
||||||
|
// Replaces all occurences of a type in a typelist, with another type
|
||||||
|
// Invocation (TList is a typelist, T, U are types):
|
||||||
|
// Replace<TList, T, U>::Result
|
||||||
|
// returns a typelist in which all occurences of T is replaced with U
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T, class U>
|
||||||
|
struct ReplaceAll {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
enum { Head_is_T = Conversion<typename TList::Head, T>::sameType };
|
||||||
|
typedef typename Select<!TList_is_null & Head_is_T, Typelist<U, typename ReplaceAll<typename TList::Tail, T, U>::Result>, NullType>::Result Result1;
|
||||||
|
public:
|
||||||
|
typedef typename Select<!TList_is_null & !Head_is_T, Typelist<typename TList::Head, typename ReplaceAll<typename TList::Tail, T, U>::Result>, Result1>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Reverse
|
||||||
|
// Reverses a typelist
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// Reverse<TList>::Result
|
||||||
|
// returns a typelist that is TList reversed
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct Reverse {
|
||||||
|
private:
|
||||||
|
enum { list_of_one = Conversion<typename TList::Tail, NullType>::sameType };
|
||||||
|
public:
|
||||||
|
typedef typename Select<list_of_one,
|
||||||
|
TList,
|
||||||
|
typename Append<typename Reverse<typename TList::Tail>::Result,
|
||||||
|
typename TList::Head
|
||||||
|
>::Result
|
||||||
|
>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template MostDerived
|
||||||
|
// Finds the type in a typelist that is the most derived from a given type
|
||||||
|
// Invocation (TList is a typelist, T is a type):
|
||||||
|
// Replace<TList, T>::Result
|
||||||
|
// returns the type in TList that's the most derived from T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class TList, class T>
|
||||||
|
struct MostDerived {
|
||||||
|
private:
|
||||||
|
enum { TList_is_null = Conversion<TList, NullType>::sameType };
|
||||||
|
typedef typename Select<TList_is_null, T, typename MostDerived<typename TList::Tail, T>::Result>::Result Candidate;
|
||||||
|
public:
|
||||||
|
typedef typename Select<TList_is_null, T,
|
||||||
|
typename Select<SUPERSUBCLASS(Candidate, typename TList::Head),
|
||||||
|
typename TList::Head, Candidate
|
||||||
|
>::Result
|
||||||
|
>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template DerivedToFront
|
||||||
|
// Arranges the types in a typelist so that the most derived types appear first
|
||||||
|
// Invocation (TList is a typelist):
|
||||||
|
// DerivedToFront<TList>::Result
|
||||||
|
// returns the reordered TList
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace DerivedToFront_ {
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct ListType {
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ListType<NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace DerivedToFront_
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct DerivedToFront;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct DerivedToFront<NullType> {
|
||||||
|
typedef NullType Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class TList>
|
||||||
|
struct DerivedToFront {
|
||||||
|
private:
|
||||||
|
typedef typename MostDerived<typename TList::Tail,
|
||||||
|
typename TList::Head>::Result TheMostDerived;
|
||||||
|
typedef typename Replace<typename TList::Tail, TheMostDerived,
|
||||||
|
typename TList::Head>::Result L;
|
||||||
|
public:
|
||||||
|
typedef Typelist<TheMostDerived, L> Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace TL
|
||||||
|
|
||||||
|
} // namespace Loki
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 09, 2001: Fix bug in parameter list of macros TYPELIST_23 to TYPELIST_27
|
||||||
|
// (credit due to Dave Taylor)
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
// August 22, 2001: ported by Jonathan H Lundquist to MSVC
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPELIST_INC_
|
||||||
|
|
268
MSVC/1300/TypeManip.h
Normal file
268
MSVC/1300/TypeManip.h
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: August 22, 2001
|
||||||
|
|
||||||
|
#ifndef TYPEMANIP_INC_
|
||||||
|
#define TYPEMANIP_INC_
|
||||||
|
|
||||||
|
namespace Loki {
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
struct big { char c[2]; };
|
||||||
|
|
||||||
|
struct any {
|
||||||
|
template<typename T>
|
||||||
|
any(const T&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Int2Type
|
||||||
|
// Converts each integral constant into a unique type
|
||||||
|
// Invocation: Int2Type<v> where v is a compile-time constant integral
|
||||||
|
// Defines 'value', an enum that evaluates to v
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <int v>
|
||||||
|
struct Int2Type
|
||||||
|
{
|
||||||
|
enum { value = v };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Type2Type
|
||||||
|
// Converts each type into a unique, insipid type
|
||||||
|
// Invocation Type2Type<T> where T is a type
|
||||||
|
// Defines the type OriginalType which maps back to T
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Type2Type
|
||||||
|
{
|
||||||
|
typedef T OriginalType;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Select
|
||||||
|
// Selects one of two types based upon a boolean constant
|
||||||
|
// Invocation: Select<flag, T, U>::Result
|
||||||
|
// where:
|
||||||
|
// flag is a compile-time boolean constant
|
||||||
|
// T and U are types
|
||||||
|
// Result evaluates to T if flag is true, and to U otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
namespace Select_ {
|
||||||
|
|
||||||
|
struct ChooseT {
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Choose {
|
||||||
|
typedef T Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChooseU {
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Choose {
|
||||||
|
typedef U Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool flag>
|
||||||
|
struct Selector {
|
||||||
|
typedef ChooseT Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Selector<false> {
|
||||||
|
typedef ChooseU Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Select_
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
template<bool flag, typename T, typename U>
|
||||||
|
struct Select {
|
||||||
|
private:
|
||||||
|
typedef typename Private::Select_::Selector<flag>::Result selector;
|
||||||
|
public:
|
||||||
|
typedef typename selector::Choose<T, U>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_void {
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct is_void<void> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace is_same_ {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
char test_same(T*, T*);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
big test_same(T*, any);
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct is_same_imp {
|
||||||
|
static T t;
|
||||||
|
static U u;
|
||||||
|
enum { result = sizeof(test_same(&t, &u)) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace is_same_
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct is_same {
|
||||||
|
enum { voidT = is_void<T>::value };
|
||||||
|
enum { voidU = is_void<U>::value };
|
||||||
|
struct BothVoid {
|
||||||
|
enum { result = 1 };
|
||||||
|
};
|
||||||
|
struct OneVoid {
|
||||||
|
enum { result = 0 };
|
||||||
|
};
|
||||||
|
typedef typename Select<voidT & voidU,
|
||||||
|
BothVoid,
|
||||||
|
typename Select<voidT | voidU,
|
||||||
|
OneVoid,
|
||||||
|
is_same_::is_same_imp<T, U>
|
||||||
|
>::Result
|
||||||
|
>::Result tester;
|
||||||
|
enum { result = tester::result };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template Conversion
|
||||||
|
// Figures out the conversion relationships between two types
|
||||||
|
// Invocations (T and U are types):
|
||||||
|
// a) Conversion<T, U>::exists
|
||||||
|
// returns (at compile time) true if there is an implicit conversion from T
|
||||||
|
// to U (example: Derived to Base)
|
||||||
|
// b) Conversion<T, U>::exists2Way
|
||||||
|
// returns (at compile time) true if there are both conversions from T
|
||||||
|
// to U and from U to T (example: int to char and back)
|
||||||
|
// c) Conversion<T, U>::sameType
|
||||||
|
// returns (at compile time) true if T and U represent the same type
|
||||||
|
//
|
||||||
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private {
|
||||||
|
|
||||||
|
namespace Conversion_ {
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4181)
|
||||||
|
#pragma warning(disable:4800)
|
||||||
|
#pragma warning(disable:4244)
|
||||||
|
#endif
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Determine {
|
||||||
|
template<typename X, typename Y>
|
||||||
|
struct tester {
|
||||||
|
static char test(X, Y);
|
||||||
|
static big test(any, any);
|
||||||
|
};
|
||||||
|
static T t;
|
||||||
|
static U u;
|
||||||
|
enum { exists = sizeof(tester<T, U>::test(t, t)) == sizeof(char) };
|
||||||
|
enum { exists2Way = exists & (sizeof(tester<U, T>::test(u, u)) == sizeof(char)) };
|
||||||
|
enum { sameType = exists2Way & is_same<T, U>::result };
|
||||||
|
};
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace Conversion_
|
||||||
|
|
||||||
|
} // namespace Private
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
struct Conversion {
|
||||||
|
private:
|
||||||
|
enum { voidT = Private::is_void<T>::value };
|
||||||
|
enum { voidU = Private::is_void<U>::value };
|
||||||
|
|
||||||
|
struct both_void {
|
||||||
|
enum { exists = 1, exists2Way = 1, sameType = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct one_void {
|
||||||
|
enum { exists = 1, exists2Way = 0, sameType = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef typename Select<voidT & voidU,
|
||||||
|
both_void,
|
||||||
|
typename Select<voidT | voidU,
|
||||||
|
one_void,
|
||||||
|
Private::Conversion_::Determine<T, U>
|
||||||
|
>::Result
|
||||||
|
>::Result Chooser;
|
||||||
|
public:
|
||||||
|
enum { exists = Chooser::exists };
|
||||||
|
enum { exists2Way = Chooser::exists2Way };
|
||||||
|
enum { sameType = Chooser::sameType };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Loki
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macro SUPERSUBCLASS
|
||||||
|
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
||||||
|
// Returns true if B is a public base of D, or if B and D are aliases of the
|
||||||
|
// same type.
|
||||||
|
//
|
||||||
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define SUPERSUBCLASS(T, U) \
|
||||||
|
(::Loki::Conversion<const U*, const T*>::exists && \
|
||||||
|
!::Loki::Conversion<const T*, const void*>::sameType)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macro SUPERSUBCLASS
|
||||||
|
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
|
||||||
|
// Returns true if B is a public base of D.
|
||||||
|
//
|
||||||
|
// Caveat: might not work if T and U are in a private inheritance hierarchy.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define SUPERSUBCLASS_STRICT(T, U) \
|
||||||
|
(SUPERSUBCLASS(T, U) && \
|
||||||
|
!::Loki::Conversion<const T, const U>::sameType)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
// August 22, 2001: ported by Jonathan H Lundquist to MSVC6
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPEMANIP_INC_
|
374
MSVC/1300/TypeTraits.h
Normal file
374
MSVC/1300/TypeTraits.h
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
#ifndef TYPETRAITS_INC_
|
||||||
|
#define TYPETRAITS_INC_
|
||||||
|
|
||||||
|
#include "Typelist.h"
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IsCustomUnsignedInt
|
||||||
|
// Offers a means to integrate nonstandard built-in unsigned integral types
|
||||||
|
// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
|
||||||
|
// class template defined below.
|
||||||
|
// Invocation: IsCustomUnsignedInt<T> where T is any type
|
||||||
|
// Defines 'value', an enum that is 1 iff T is a custom built-in unsigned
|
||||||
|
// integral type
|
||||||
|
// Specialize this class template for nonstandard unsigned integral types
|
||||||
|
// and define value = 1 in those specializations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsCustomUnsignedInt
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
template<>
|
||||||
|
struct IsCustomUnsignedInt<unsigned __int64> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IsCustomSignedInt
|
||||||
|
// Offers a means to integrate nonstandard built-in unsigned integral types
|
||||||
|
// (such as unsigned __int64 or unsigned long long int) with the TypeTraits
|
||||||
|
// class template defined below.
|
||||||
|
// Invocation: IsCustomSignedInt<T> where T is any type
|
||||||
|
// Defines 'value', an enum that is 1 iff T is a custom built-in signed
|
||||||
|
// integral type
|
||||||
|
// Specialize this class template for nonstandard unsigned integral types
|
||||||
|
// and define value = 1 in those specializations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsCustomSignedInt
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
template<>
|
||||||
|
struct IsCustomSignedInt<__int64> {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template IsCustomFloat
|
||||||
|
// Offers a means to integrate nonstandard floating point types with the
|
||||||
|
// TypeTraits class template defined below.
|
||||||
|
// Invocation: IsCustomFloat<T> where T is any type
|
||||||
|
// Defines 'value', an enum that is 1 iff T is a custom built-in
|
||||||
|
// floating point type
|
||||||
|
// Specialize this class template for nonstandard unsigned integral types
|
||||||
|
// and define value = 1 in those specializations
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsCustomFloat
|
||||||
|
{
|
||||||
|
enum { value = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper types for class template TypeTraits defined below
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
typedef TYPELIST_4(unsigned char, unsigned short int,
|
||||||
|
unsigned int, unsigned long int) StdUnsignedInts;
|
||||||
|
typedef TYPELIST_4(signed char, short int,
|
||||||
|
int, long int) StdSignedInts;
|
||||||
|
typedef TYPELIST_3(bool, char, wchar_t) StdOtherInts;
|
||||||
|
typedef TYPELIST_3(float, double, long double) StdFloats;
|
||||||
|
|
||||||
|
char test_ptr(const volatile void*, const volatile void*);
|
||||||
|
big test_ptr(any, any);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* unrefptr(T&);
|
||||||
|
|
||||||
|
char test_const(const volatile void*);
|
||||||
|
big test_const(volatile void*);
|
||||||
|
char test_volatile(const volatile void*);
|
||||||
|
big test_volatile(const void*);
|
||||||
|
|
||||||
|
template<typename V, typename X>
|
||||||
|
char test_mptr(V X::*, any);
|
||||||
|
|
||||||
|
big test_mptr(any, any);
|
||||||
|
|
||||||
|
template<bool isReference>
|
||||||
|
struct AddReferenceImp {
|
||||||
|
template<typename T>
|
||||||
|
struct Imp {
|
||||||
|
typedef T Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AddReferenceImp<false> {
|
||||||
|
template<typename T>
|
||||||
|
struct Imp {
|
||||||
|
typedef T& Result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct PointerTraits
|
||||||
|
{
|
||||||
|
enum { result = false };
|
||||||
|
typedef NullType PointeeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct PointerTraits<U*>
|
||||||
|
{
|
||||||
|
enum { result = true };
|
||||||
|
typedef U PointeeType;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct PointerTraits {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
typedef void PointeeType; // unable to determine correctly
|
||||||
|
enum { result = sizeof(Private::test_ptr(&u, u)) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct PointerTraits<void> {
|
||||||
|
typedef void PointeeType;
|
||||||
|
enum { result = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct ReferenceTraits
|
||||||
|
{
|
||||||
|
enum { result = false };
|
||||||
|
typedef U ReferredType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct ReferenceTraits<U&>
|
||||||
|
{
|
||||||
|
enum { result = true };
|
||||||
|
typedef U ReferredType;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4181)
|
||||||
|
template<typename U>
|
||||||
|
struct ReferenceTraits {
|
||||||
|
typedef U const volatile cv_u;
|
||||||
|
static cv_u u;
|
||||||
|
public:
|
||||||
|
enum { result = (sizeof(Private::test_const(&u)) != sizeof(char))
|
||||||
|
| (sizeof(Private::test_volatile(&u)) != sizeof(char)) };
|
||||||
|
typedef void ReferredType; // unable to determine correctly
|
||||||
|
};
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ReferenceTraits<void> {
|
||||||
|
enum { result = 0 };
|
||||||
|
typedef void ReferredType;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct PToMTraits
|
||||||
|
{
|
||||||
|
enum { result = false };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U, class V>
|
||||||
|
struct PToMTraits<U V::*>
|
||||||
|
{
|
||||||
|
enum { result = true };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct PToMTraits {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
enum { result = sizeof(Private::test_mptr(u, &u)) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct PToMTraits<void> {
|
||||||
|
enum { result = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct UnConst
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isConst = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct UnConst<const U>
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isConst = 1 };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct UnConst {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
typedef void Result; // unable to determine correctly
|
||||||
|
enum { isConst = sizeof(Private::test_const(Private::unrefptr(u))) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct UnConst<void> {
|
||||||
|
typedef void Result;
|
||||||
|
enum { isConst = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
template <class U> struct UnVolatile
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isVolatile = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class U> struct UnVolatile<volatile U>
|
||||||
|
{
|
||||||
|
typedef U Result;
|
||||||
|
enum { isVolatile = 1 };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
template<typename U>
|
||||||
|
struct UnVolatile {
|
||||||
|
private:
|
||||||
|
static U u;
|
||||||
|
public:
|
||||||
|
typedef void Result; // unable to determine correctly
|
||||||
|
enum { isVolatile = sizeof(Private::test_volatile(Private::unrefptr(u))) == sizeof(char) };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct UnVolatile<void> {
|
||||||
|
typedef void Result;
|
||||||
|
enum { isVolatile = 0 };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
template<typename U, bool isReference>
|
||||||
|
struct AddReference {
|
||||||
|
typedef typename Private::AddReferenceImp<isReference>::template Imp<U>::Result Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AddReference<void, false> {
|
||||||
|
typedef void Result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// class template TypeTraits
|
||||||
|
// Figures out various properties of any given type
|
||||||
|
// Invocations (T is a type):
|
||||||
|
// a) TypeTraits<T>::isPointer
|
||||||
|
// returns (at compile time) true if T is a pointer type
|
||||||
|
// b) TypeTraits<T>::PointeeType
|
||||||
|
// returns the type to which T points is T is a pointer type, NullType otherwise
|
||||||
|
// a) TypeTraits<T>::isReference
|
||||||
|
// returns (at compile time) true if T is a reference type
|
||||||
|
// b) TypeTraits<T>::ReferredType
|
||||||
|
// returns the type to which T refers is T is a reference type, NullType
|
||||||
|
// otherwise
|
||||||
|
// c) TypeTraits<T>::isMemberPointer
|
||||||
|
// returns (at compile time) true if T is a pointer to member type
|
||||||
|
// d) TypeTraits<T>::isStdUnsignedInt
|
||||||
|
// returns (at compile time) true if T is a standard unsigned integral type
|
||||||
|
// e) TypeTraits<T>::isStdSignedInt
|
||||||
|
// returns (at compile time) true if T is a standard signed integral type
|
||||||
|
// f) TypeTraits<T>::isStdIntegral
|
||||||
|
// returns (at compile time) true if T is a standard integral type
|
||||||
|
// g) TypeTraits<T>::isStdFloat
|
||||||
|
// returns (at compile time) true if T is a standard floating-point type
|
||||||
|
// h) TypeTraits<T>::isStdArith
|
||||||
|
// returns (at compile time) true if T is a standard arithmetic type
|
||||||
|
// i) TypeTraits<T>::isStdFundamental
|
||||||
|
// returns (at compile time) true if T is a standard fundamental type
|
||||||
|
// j) TypeTraits<T>::isUnsignedInt
|
||||||
|
// returns (at compile time) true if T is a unsigned integral type
|
||||||
|
// k) TypeTraits<T>::isSignedInt
|
||||||
|
// returns (at compile time) true if T is a signed integral type
|
||||||
|
// l) TypeTraits<T>::isIntegral
|
||||||
|
// returns (at compile time) true if T is a integral type
|
||||||
|
// m) TypeTraits<T>::isFloat
|
||||||
|
// returns (at compile time) true if T is a floating-point type
|
||||||
|
// n) TypeTraits<T>::isArith
|
||||||
|
// returns (at compile time) true if T is a arithmetic type
|
||||||
|
// o) TypeTraits<T>::isFundamental
|
||||||
|
// returns (at compile time) true if T is a fundamental type
|
||||||
|
// p) TypeTraits<T>::ParameterType
|
||||||
|
// returns the optimal type to be used as a parameter for functions that take Ts
|
||||||
|
// q) TypeTraits<T>::isConst
|
||||||
|
// returns (at compile time) true if T is a const-qualified type
|
||||||
|
// r) TypeTraits<T>::NonConstType
|
||||||
|
// removes the 'const' qualifier from T, if any
|
||||||
|
// s) TypeTraits<T>::isVolatile
|
||||||
|
// returns (at compile time) true if T is a volatile-qualified type
|
||||||
|
// t) TypeTraits<T>::NonVolatileType
|
||||||
|
// removes the 'volatile' qualifier from T, if any
|
||||||
|
// u) TypeTraits<T>::UnqualifiedType
|
||||||
|
// removes both the 'const' and 'volatile' qualifiers from T, if any
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TypeTraits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const isPointer = Private::PointerTraits<T>::result;
|
||||||
|
//enum { isPointer = Private::PointerTraits<T>::result };
|
||||||
|
typedef typename Private::PointerTraits<T>::PointeeType PointeeType;
|
||||||
|
static const isReference = Private::ReferenceTraits<T>::result;
|
||||||
|
typedef typename Private::ReferenceTraits<T>::ReferredType ReferredType;
|
||||||
|
|
||||||
|
static const isMemberPointer = Private::PToMTraits<T>::result;
|
||||||
|
|
||||||
|
static const isStdUnsignedInt =
|
||||||
|
TL::IndexOf<Private::StdUnsignedInts, T>::value >= 0;
|
||||||
|
static const isStdSignedInt =
|
||||||
|
TL::IndexOf<Private::StdSignedInts, T>::value >= 0;
|
||||||
|
static const isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
|
||||||
|
TL::IndexOf<Private::StdOtherInts, T>::value >= 0;
|
||||||
|
static const isStdFloat = TL::IndexOf<Private::StdFloats, T>::value >= 0;
|
||||||
|
static const isStdArith = isStdIntegral || isStdFloat;
|
||||||
|
static const isStdFundamental = isStdArith || isStdFloat ||
|
||||||
|
Conversion<T, void>::sameType;
|
||||||
|
|
||||||
|
static const isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<T>::value;
|
||||||
|
static const isSignedInt = isStdSignedInt || IsCustomSignedInt<T>::value;
|
||||||
|
static const isIntegral = isStdIntegral || isUnsignedInt || isSignedInt;
|
||||||
|
static const isFloat = isStdFloat || IsCustomFloat<T>::value;
|
||||||
|
static const isArith = isIntegral || isFloat;
|
||||||
|
static const isFundamental = isStdFundamental || isArith || isFloat;
|
||||||
|
|
||||||
|
typedef typename Select<isStdArith || isPointer || isMemberPointer, T,
|
||||||
|
typename Private::AddReference<T, isReference>::Result
|
||||||
|
>::Result ParameterType;
|
||||||
|
|
||||||
|
static const isConst = Private::UnConst<T>::isConst;
|
||||||
|
typedef typename Private::UnConst<T>::Result NonConstType;
|
||||||
|
static const isVolatile = Private::UnVolatile<T>::isVolatile;
|
||||||
|
typedef typename Private::UnVolatile<T>::Result NonVolatileType;
|
||||||
|
typedef typename Private::UnVolatile<typename Private::UnConst<T>::Result>::Result
|
||||||
|
UnqualifiedType;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
// August 22, 2001: ported by Jonathan H Lundquist to MSVC
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // TYPETRAITS_INC_
|
3
MSVC/1300/portby.txt
Normal file
3
MSVC/1300/portby.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
MSVC7
|
||||||
|
Jonathan H. Lundquist
|
||||||
|
Shannon G. Barber (aka Magmai Kai Holmlor)
|
51
MSVC/1300/static_check.h
Normal file
51
MSVC/1300/static_check.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Last update: June 20, 2001
|
||||||
|
|
||||||
|
#ifndef STATIC_CHECK_INC_
|
||||||
|
#define STATIC_CHECK_INC_
|
||||||
|
|
||||||
|
namespace Loki
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Helper structure for the STATIC_CHECK macro
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<int> struct CompileTimeError;
|
||||||
|
template<> struct CompileTimeError<true> {};
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// macro STATIC_CHECK
|
||||||
|
// Invocation: STATIC_CHECK(expr, id)
|
||||||
|
// where:
|
||||||
|
// expr is a compile-time integral or pointer expression
|
||||||
|
// id is a C++ identifier that does not need to be defined
|
||||||
|
// If expr is zero, id will appear in a compile-time error message.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define STATIC_CHECK(expr, msg) \
|
||||||
|
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Change log:
|
||||||
|
// March 20, 2001: add extra parens to STATIC_CHECK - it looked like a fun
|
||||||
|
// definition
|
||||||
|
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // STATIC_CHECK_INC_
|
Loading…
Add table
Add a link
Reference in a new issue