Mirror reflection library 0.5.13
|
00001 00011 #ifndef MIRROR_META_PROG_APPLY_ON_SEQ_PACK_1011291729_HPP 00012 #define MIRROR_META_PROG_APPLY_ON_SEQ_PACK_1011291729_HPP 00013 00014 00015 #include <mirror/meta_prog/range.hpp> 00016 00017 MIRROR_NAMESPACE_BEGIN 00018 namespace mp { 00019 namespace aux { 00020 00021 // Helper which calls the apply meta-function and "returns" its type 00022 /* This template takes the pack of integral constant types with 00023 * values forming a sequence 0, 1, 2, ..., N-1 and defines a do_apply 00024 * template that takes a meta-function class. 00025 */ 00026 template <int N, class ... I> 00027 struct seq_pack_applier 00028 { 00029 template <class MetaFunctionClass> 00030 struct do_apply 00031 { 00032 typedef typename MetaFunctionClass:: 00033 template apply< 00034 (N - I::value - 1)... 00035 >::type type; 00036 }; 00037 }; 00038 00039 // Forward declaration the seq_pack helper class 00040 /* This template class is used for expanding 00041 * the parameter pack containing the sequence 00042 * of integral constant types from 0 to the 00043 * value specified as the first template parameter. 00044 * When the parameter pack is fully expanded 00045 * the seq_packr_applier template is used to instantiate 00046 * the apply meta-function of the custom meta function 00047 * class. 00048 */ 00049 template <class N, class ...I> 00050 struct seq_pack_helper; 00051 00052 /* Specialization of the seq_pack_helper for single 00053 * element packs. 00054 */ 00055 template <> 00056 struct seq_pack_helper< 00057 std::integral_constant<int, 1>, 00058 std::integral_constant<int, 0> 00059 > : seq_pack_applier< 00060 1, 00061 std::integral_constant<int, 0> 00062 > 00063 { }; 00064 00065 /* Specialization of the seq_pack_helper with fully 00066 * assembled integral constant type pack. This 00067 * version derives from the seq_pack_applier providing 00068 * the do_apply meta-function 00069 */ 00070 template < 00071 int N, 00072 class ...I 00073 > struct seq_pack_helper< 00074 std::integral_constant<int, N>, 00075 std::integral_constant<int, N>, 00076 I... 00077 > : seq_pack_applier<N, I...> 00078 { }; 00079 00080 /* This specialization of the seq_pack_helper which 00081 * adds one item to the integral constant type pack 00082 * which is not yet fully assembled. 00083 */ 00084 template < 00085 int N, 00086 int I_plus_1, 00087 class ... I 00088 > struct seq_pack_helper< 00089 std::integral_constant<int, N>, 00090 std::integral_constant<int, I_plus_1>, 00091 I... 00092 > : seq_pack_helper< 00093 std::integral_constant<int, N>, 00094 std::integral_constant<int, I_plus_1 + 1>, 00095 std::integral_constant<int, I_plus_1>, 00096 I... 00097 > 00098 { }; 00099 00100 } // namespace aux 00101 00102 #ifdef MIRROR_DOCUMENTATION_ONLY 00103 00104 00117 template <typename MetaFunctionClass, int N> 00118 struct apply_on_seq_pack_c 00119 { 00121 00128 typedef unspecified_type type; 00129 }; 00130 #else 00131 template <typename MetaFunctionClass, int Count> 00132 struct apply_on_seq_pack_c 00133 { 00134 typedef typename aux::seq_pack_helper< 00135 std::integral_constant<int, Count>, 00136 std::integral_constant<int, 0> 00137 >::template do_apply<MetaFunctionClass>::type type; 00138 }; 00139 00140 template <typename MetaFunctionClass> 00141 struct apply_on_seq_pack_c<MetaFunctionClass, 0> 00142 { 00143 typedef typename MetaFunctionClass:: 00144 template apply< >::type type; 00145 }; 00146 00147 template <typename MetaFunctionClass> 00148 struct apply_on_seq_pack_c<MetaFunctionClass, 1> 00149 { 00150 typedef typename MetaFunctionClass:: 00151 template apply<0>::type type; 00152 }; 00153 00154 template <typename MetaFunctionClass> 00155 struct apply_on_seq_pack_c<MetaFunctionClass, 2> 00156 { 00157 typedef typename MetaFunctionClass:: 00158 template apply<0, 1>::type type; 00159 }; 00160 00161 template <typename MetaFunctionClass> 00162 struct apply_on_seq_pack_c<MetaFunctionClass, 3> 00163 { 00164 typedef typename MetaFunctionClass:: 00165 template apply<0, 1, 2>::type type; 00166 }; 00167 00168 template <typename MetaFunctionClass> 00169 struct apply_on_seq_pack_c<MetaFunctionClass, 4> 00170 { 00171 typedef typename MetaFunctionClass:: 00172 template apply<0, 1, 2, 3>::type type; 00173 }; 00174 00175 template <typename MetaFunctionClass> 00176 struct apply_on_seq_pack_c<MetaFunctionClass, 5> 00177 { 00178 typedef typename MetaFunctionClass:: 00179 template apply<0, 1, 2, 3, 4>::type type; 00180 }; 00181 00182 template <typename MetaFunctionClass> 00183 struct apply_on_seq_pack_c<MetaFunctionClass, 6> 00184 { 00185 typedef typename MetaFunctionClass:: 00186 template apply<0, 1, 2, 3, 4, 5>::type type; 00187 }; 00188 00189 template <typename MetaFunctionClass> 00190 struct apply_on_seq_pack_c<MetaFunctionClass, 7> 00191 { 00192 typedef typename MetaFunctionClass:: 00193 template apply<0, 1, 2, 3, 4, 5, 6>::type type; 00194 }; 00195 00196 template <typename MetaFunctionClass> 00197 struct apply_on_seq_pack_c<MetaFunctionClass, 8> 00198 { 00199 typedef typename MetaFunctionClass:: 00200 template apply<0, 1, 2, 3, 4, 5, 6, 7>::type type; 00201 }; 00202 00203 template <typename MetaFunctionClass> 00204 struct apply_on_seq_pack_c<MetaFunctionClass, 9> 00205 { 00206 typedef typename MetaFunctionClass:: 00207 template apply<0, 1, 2, 3, 4, 5, 6, 7, 8>::type type; 00208 }; 00209 00210 template <typename MetaFunctionClass> 00211 struct apply_on_seq_pack_c<MetaFunctionClass, 10> 00212 { 00213 typedef typename MetaFunctionClass:: 00214 template apply<0, 1, 2, 3, 4, 5, 6, 7, 8, 9>::type type; 00215 }; 00216 00217 template <typename MetaFunctionClass> 00218 struct apply_on_seq_pack_c<MetaFunctionClass, 11> 00219 { 00220 typedef typename MetaFunctionClass:: 00221 template apply<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10>::type type; 00222 }; 00223 00224 template <typename MetaFunctionClass> 00225 struct apply_on_seq_pack_c<MetaFunctionClass, 12> 00226 { 00227 typedef typename MetaFunctionClass:: 00228 template apply<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11>::type type; 00229 }; 00230 00231 template <typename MetaFunctionClass> 00232 struct apply_on_seq_pack_c<MetaFunctionClass, 13> 00233 { 00234 typedef typename MetaFunctionClass:: 00235 template apply<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12>::type type; 00236 }; 00237 00238 template <typename MetaFunctionClass> 00239 struct apply_on_seq_pack_c<MetaFunctionClass, 14> 00240 { 00241 typedef typename MetaFunctionClass:: 00242 template apply<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13>::type type; 00243 }; 00244 00245 #endif 00246 00247 00248 #ifdef MIRROR_DOCUMENTATION_ONLY 00249 00250 00264 template <typename MetaFunctionClass, class N> 00265 struct apply_on_seq_pack 00266 { 00268 00275 typedef unspecified_type type; 00276 }; 00277 #else 00278 template <typename MetaFunctionClass, class Count> 00279 struct apply_on_seq_pack 00280 : public apply_on_seq_pack_c<MetaFunctionClass, Count::value> 00281 { }; 00282 #endif 00283 00284 } // namespace mp 00285 MIRROR_NAMESPACE_END 00286 00287 #endif //include guard 00288