Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_META_PROG_FOR_EACH_1011291729_HPP 00011 #define MIRROR_META_PROG_FOR_EACH_1011291729_HPP 00012 00013 00014 #include <mirror/meta_prog/range.hpp> 00015 #include <mirror/meta_prog/traits.hpp> 00016 #include <mirror/meta_prog/iter_info.hpp> 00017 00018 MIRROR_NAMESPACE_BEGIN 00019 namespace mp { 00020 namespace aux { 00021 00022 // Implementation of for_each for empty ranges 00023 template < 00024 typename Functor, 00025 typename IsFirst, 00026 typename IsLast 00027 > 00028 void for_each( 00029 Functor& func, 00030 range<>, 00031 IsFirst is_first, 00032 IsLast is_last 00033 ) 00034 { } 00035 00036 // Implementation of for_each for single element ranges 00037 template < 00038 typename T, 00039 typename Functor, 00040 typename IsFirst, 00041 typename IsLast 00042 > 00043 void for_each( 00044 Functor& func, 00045 range<T>, 00046 IsFirst is_first, 00047 IsLast is_last 00048 ) 00049 { 00050 // call the functor on the last element 00051 func(iteration_info< 00052 T, 00053 IsFirst, 00054 std::true_type 00055 >()); 00056 } 00057 00058 // Implementation of for_each for multi element ranges 00059 template < 00060 typename T, 00061 typename ... P, 00062 typename Functor, 00063 typename IsFirst, 00064 typename IsLast 00065 > 00066 void for_each( 00067 Functor& func, 00068 range<T, P...>, 00069 IsFirst is_first, 00070 IsLast is_last 00071 ) 00072 { 00073 // call the functor on the front element 00074 func(iteration_info< 00075 T, 00076 IsFirst, 00077 IsLast 00078 >()); 00079 // move to the rest of the range 00080 for_each( 00081 func, 00082 range<P...>(), 00083 std::false_type(), 00084 is_last 00085 ); 00086 } 00087 00088 /* Implementation which tries to use the R type as 00089 * a range returning meta-function 00090 */ 00091 template < 00092 typename X, 00093 typename Functor, 00094 typename IsFirst, 00095 typename IsLast 00096 > 00097 void for_each( 00098 Functor& func, 00099 X, 00100 IsFirst is_first, 00101 IsLast is_last 00102 ) 00103 { 00104 MIRROR_ASSERT_RETURNS_RANGE(X); 00105 for_each(func, typename X::type(), is_first, is_last); 00106 } 00107 00108 template <class Functor> 00109 struct for_each_ii_remover 00110 { 00111 Functor& func; 00112 00113 inline for_each_ii_remover(Functor& f) 00114 : func(f) 00115 { } 00116 00117 template <class IterInfo> 00118 inline void operator()(IterInfo) const 00119 { 00120 func(typename IterInfo::type()); 00121 } 00122 }; 00123 00124 } // namespace aux 00125 00127 00137 template <typename Range, typename Functor> 00138 void for_each(Functor func) 00139 { 00140 aux::for_each_ii_remover<Functor> adapted_func(func); 00141 aux::for_each( 00142 adapted_func, 00143 Range(), 00144 std::true_type(), 00145 std::false_type() 00146 ); 00147 } 00148 00150 00169 template <typename Range, typename Functor> 00170 void for_each_ii(Functor func) 00171 { 00172 aux::for_each( 00173 func, 00174 Range(), 00175 std::true_type(), 00176 std::false_type() 00177 ); 00178 } 00179 00180 00181 } // namespace mp 00182 MIRROR_NAMESPACE_END 00183 00184 #endif //include guard 00185