Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_META_PROG_RANGE_1011291729_HPP 00011 #define MIRROR_META_PROG_RANGE_1011291729_HPP 00012 00013 #include <mirror/meta_prog/forward_decl.hpp> 00014 #include <mirror/meta_prog/traits.hpp> 00015 00016 MIRROR_NAMESPACE_BEGIN 00017 namespace mp { 00018 00020 00030 template <typename ... P> 00031 struct range 00032 { 00033 typedef range type; 00034 }; 00035 00037 typedef range<> empty_range; 00038 00039 #ifdef MIRROR_DOCUMENTATION_ONLY 00040 00041 00047 template <typename Range> 00048 struct empty { }; 00049 #else 00050 // The default implementation of the empty meta-function 00051 template <typename X> 00052 struct empty : empty<typename X::type>::type 00053 { 00054 MIRROR_ASSERT_RETURNS_RANGE(X); 00055 }; 00056 #endif 00057 00058 template <> 00059 struct empty<range<> > 00060 : std::true_type 00061 { }; 00062 00063 template <typename ... P> 00064 struct empty<range<P...> > 00065 : std::false_type 00066 { }; 00067 00068 #ifdef MIRROR_DOCUMENTATION_ONLY 00069 00070 00076 template <typename Range> 00077 struct size { }; 00078 #else 00079 template <typename X> 00080 struct size : size<typename X::type>::type 00081 { 00082 MIRROR_ASSERT_RETURNS_RANGE(X); 00083 }; 00084 #endif 00085 00086 template <> 00087 struct size<range<> > 00088 : std::integral_constant<int, 0> 00089 { }; 00090 00091 template <typename T> 00092 struct size<range<T> > 00093 : std::integral_constant<int, 1> 00094 { }; 00095 00096 template <typename T, typename ... P> 00097 struct size<range<T, P...> > 00098 : std::integral_constant<int, 1 + size<range<P...> >::value> 00099 { }; 00100 00101 #ifdef MIRROR_DOCUMENTATION_ONLY 00102 00103 00112 template <typename Range> 00113 struct front 00114 { 00116 typedef unspecified_type type; 00117 }; 00118 #else 00119 template <typename X> 00120 struct front 00121 { 00122 MIRROR_ASSERT_RETURNS_RANGE(X); 00123 typedef typename front<typename X::type>::type type; 00124 }; 00125 #endif 00126 00127 template <typename T, typename ... P> 00128 struct front<range<T, P...> > 00129 { 00130 typedef T type; 00131 }; 00132 00133 #ifdef MIRROR_DOCUMENTATION_ONLY 00134 00135 00144 template <typename BiDiRange> 00145 struct back 00146 { 00148 typedef unspecified_type type; 00149 }; 00150 #else 00151 template <typename X> 00152 struct back 00153 { 00154 MIRROR_ASSERT_RETURNS_RANGE(X); 00155 typedef typename back<typename X::type>::type type; 00156 }; 00157 #endif 00158 00159 template <typename ... P, typename T> 00160 struct back<range<P..., T> > 00161 { 00162 typedef T type; 00163 }; 00164 00165 #ifdef MIRROR_DOCUMENTATION_ONLY 00166 00167 00180 template <typename Range, int Index> 00181 struct at_c 00182 { 00184 typedef unspecified_type type; 00185 }; 00186 #else 00187 template <typename X, int Index> 00188 struct at_c 00189 { 00190 MIRROR_ASSERT_RETURNS_RANGE(X); 00191 typedef typename at_c<typename X::type, Index>::type type; 00192 }; 00193 #endif 00194 00195 template <typename T, typename ... P> 00196 struct at_c<range<T, P...>, 0> 00197 { 00198 typedef T type; 00199 }; 00200 00201 template <typename T, typename ... P, int Index> 00202 struct at_c<range<T, P...>, Index> 00203 { 00204 typedef typename at_c<range<P...>, Index-1>::type type; 00205 }; 00206 00207 #ifdef MIRROR_DOCUMENTATION_ONLY 00208 00209 00222 template <typename Range, class Index> 00223 struct at 00224 { 00226 typedef unspecified_type type; 00227 }; 00228 #else 00229 template <typename Range, class Index> 00230 struct at : at_c<Range, Index::value> 00231 { }; 00232 #endif 00233 00234 #ifdef MIRROR_DOCUMENTATION_ONLY 00235 00236 00248 template <typename Range> 00249 struct step_front 00250 { 00252 typedef unspecified_type type; 00253 }; 00254 #else 00255 template <typename X> 00256 struct step_front 00257 { 00258 MIRROR_ASSERT_RETURNS_RANGE(X); 00259 typedef typename step_front< 00260 typename X::type 00261 >::type type; 00262 }; 00263 #endif 00264 00265 template <typename T, typename ... P> 00266 struct step_front<range<T, P...> > 00267 { 00268 typedef range<P...> type; 00269 }; 00270 00271 #ifdef MIRROR_DOCUMENTATION_ONLY 00272 00273 00277 template <typename Range, typename Item> 00278 struct push_back 00279 { 00281 typedef Range type; 00282 }; 00283 #else 00284 template <typename X, typename Item> 00285 struct push_back 00286 { 00287 MIRROR_ASSERT_RETURNS_RANGE(X); 00288 typedef typename push_back< 00289 typename X::type, 00290 Item 00291 >::type type; 00292 }; 00293 #endif 00294 00295 template <typename ... P, typename Item> 00296 struct push_back<range<P...>, Item> 00297 { 00298 typedef range<P..., Item> type; 00299 }; 00300 00301 namespace aux { 00302 00303 template <typename Expr, typename IsRange> 00304 struct as_range; 00305 00306 template <typename Range> 00307 struct as_range<Range, std::true_type> 00308 { 00309 typedef Range type; 00310 }; 00311 00312 template <typename Expr> 00313 struct as_range<Expr, std::false_type> 00314 { 00315 MIRROR_ASSERT_RETURNS_RANGE(Expr); 00316 typedef typename Expr::type type; 00317 }; 00318 00319 } // namespace aux 00320 00321 template <typename Expr> 00322 struct as_range : public aux::as_range< 00323 Expr, 00324 typename is_range<Expr>::type 00325 >{ }; 00326 00327 00328 } // namespace mp 00329 MIRROR_NAMESPACE_END 00330 00331 #endif //include guard 00332