00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef INSTIGATE_SCRIPTING_GENERIC_TYPELIST_HPP
00017 #define INSTIGATE_SCRIPTING_GENERIC_TYPELIST_HPP
00018
00019 namespace instigate {
00020
00021 namespace scripting {
00022
00023 namespace generic {
00024
00025 struct nulltype
00026 {};
00027
00028 template <typename H, typename T>
00029 struct typelist
00030 {
00031 typedef H head;
00032 typedef T tail;
00033 };
00034
00035 #define typelist_1(T1) typelist<T1, nulltype>
00036 #define typelist_2(T1, T2) typelist<T1, typelist_1(T2)>
00037 #define typelist_3(T1, T2, T3) typelist<T1, typelist_2(T2, T3)>
00038 #define typelist_4(T1, T2, T3, T4) typelist<T1, typelist_3(T2, T3, T4)>
00039 #define typelist_5(T1, T2, T3, T4, T5) typelist<T1, typelist_4(T2, T3, T4, T5)>
00040
00041 template <typename T>
00042 struct length;
00043
00044 template <>
00045 struct length<nulltype>
00046 {
00047 static const int value = 0;
00048 };
00049
00050 template <typename H, typename T>
00051 struct length< typelist<H, T> >
00052 {
00053 static const int value = 1 + length<T>::value;
00054 };
00055
00057
00058 template <typename T, unsigned int index>
00059 struct type_at;
00060
00061 template <typename H, typename T>
00062 struct type_at<typelist<H, T>, 0>
00063 {
00064 typedef H result_type;
00065 };
00066
00067 template <typename H, typename T, unsigned int index>
00068 struct type_at<typelist<H, T>, index>
00069 {
00070 typedef typename type_at<T, index - 1>::result_type result_type;
00071 };
00072
00074
00075 template <typename T, typename V>
00076 struct index_of;
00077
00078 template <typename V>
00079 struct index_of<nulltype, V>
00080 {
00081 static const int value = -1;
00082 };
00083
00084 template <typename H, typename T>
00085 struct index_of<typelist<H, T>, H>
00086 {
00087 static const int value = 0;
00088 };
00089
00090 template <typename H, typename T, typename V>
00091 struct index_of<typelist<H, T>, V>
00092 {
00093 private:
00094 static const int temp = index_of<T, V>::value;
00095 public:
00096 static const int value = temp == -1 ? -1 : temp + 1;
00097 };
00098
00100
00101 template <typename T, typename V>
00102 struct append;
00103
00104 template <>
00105 struct append<nulltype, nulltype>
00106 {
00107 typedef nulltype result_type;
00108 };
00109
00110 template <typename V>
00111 struct append<nulltype, V>
00112 {
00113 typedef typelist_1(V) result_type;
00114 };
00115
00116 template <typename H, typename T>
00117 struct append<nulltype, typelist<H, T> >
00118 {
00119 typedef typelist<H, T> result_type;
00120 };
00121
00122 template <typename H, typename T, typename V>
00123 struct append<typelist<H, T>, V>
00124 {
00125 typedef typelist<H, typename append<T, V>::result_type> result_type;
00126 };
00127
00129
00130 template <typename T, typename V>
00131 struct erase;
00132
00133 template <typename V>
00134 struct erase<nulltype, V>
00135 {
00136 typedef nulltype result_type;
00137 };
00138
00139 template <typename H, typename T>
00140 struct erase<typelist<H, T>, H>
00141 {
00142 typedef T result_type;
00143 };
00144
00145 template <typename H, typename T, typename V>
00146 struct erase<typelist<H, T>, V>
00147 {
00148 typedef typelist<H, typename erase<T, V>::result_type> result_type;
00149 };
00150
00152
00153 template <typename T, typename V>
00154 struct erase_all;
00155
00156 template <typename V>
00157 struct erase_all<nulltype, V>
00158 {
00159 typedef nulltype result_type;
00160 };
00161
00162 template <typename H, typename T>
00163 struct erase_all<typelist<H, T>, H>
00164 {
00165 typedef typename erase_all<T, H>::result_type result_type;
00166 };
00167
00168 template <typename H, typename T, typename V>
00169 struct erase_all<typelist<H, T>, V>
00170 {
00171 typedef typelist<H, typename erase_all<T, V>::result_type> result_type;
00172 };
00173
00174
00176
00177 template <typename T>
00178 struct no_duplicates;
00179
00180 template <>
00181 struct no_duplicates<nulltype>
00182 {
00183 typedef nulltype result_type;
00184 };
00185
00186 template <typename H, typename T>
00187 struct no_duplicates< typelist<H, T> >
00188 {
00189 private:
00190 typedef typename no_duplicates<T>::result_type T1;
00191 typedef typename erase<T1, H>::result_type T2;
00192 public:
00193 typedef typelist<H, T2> result_type;
00194 };
00195
00197
00198 template <typename T, typename A, typename B>
00199 struct replace;
00200
00201 template <typename A, typename B>
00202 struct replace<nulltype, A, B>
00203 {
00204 typedef nulltype result_type;
00205 };
00206
00207 template <typename H, typename T, typename B>
00208 struct replace<typelist<H, T>, H, B>
00209 {
00210 typedef typelist<B, T> result_type;
00211 };
00212
00213 template <typename H, typename T, typename A, typename B>
00214 struct replace<typelist<H, T>, A, B>
00215 {
00216 typedef typelist<H, typename replace<T, A, B>::result_type> result_type;
00217 };
00218
00219 }
00220
00221 }
00222
00223 }
00224
00225 #endif // INSTIGATE_SCRIPTING_GENERIC_TYPELIST_HPP