Mirror reflection library 0.5.13
|
00001 00010 #ifndef MIRROR_META_PROG_ACCUMULATE_1103161408_HPP 00011 #define MIRROR_META_PROG_ACCUMULATE_1103161408_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 accumulate for empty ranges 00023 template < 00024 typename ResultType, 00025 typename Functor, 00026 typename ValueType, 00027 typename IsFirst, 00028 typename IsLast 00029 > 00030 ResultType accumulate( 00031 Functor func, 00032 ValueType final, 00033 range<>, 00034 IsFirst is_first, 00035 IsLast is_last 00036 ) 00037 { 00038 return final; 00039 } 00040 00041 // Implementation of accumulate for single element ranges 00042 template < 00043 typename ResultType, 00044 typename T, 00045 typename Functor, 00046 typename ValueType, 00047 typename IsFirst, 00048 typename IsLast 00049 > 00050 ResultType accumulate( 00051 Functor func, 00052 ValueType value, 00053 range<T>, 00054 IsFirst is_first, 00055 IsLast is_last 00056 ) 00057 { 00058 // call the functor on the last element 00059 return func(value, iteration_info<T, IsFirst, std::true_type>()); 00060 } 00061 00062 // Implementation of accumulate for multi element ranges 00063 template < 00064 typename ResultType, 00065 typename T, 00066 typename ... P, 00067 typename Functor, 00068 typename ValueType, 00069 typename IsFirst, 00070 typename IsLast 00071 > 00072 ResultType accumulate( 00073 Functor func, 00074 ValueType value, 00075 range<T, P...>, 00076 IsFirst is_first, 00077 IsLast is_last 00078 ) 00079 { 00080 return accumulate<ResultType>( 00081 func, 00082 func(value, iteration_info<T, IsFirst, IsLast>()), 00083 range<P...>(), 00084 std::false_type(), 00085 is_last 00086 ); 00087 } 00088 00089 /* Implementation which tries to use the R type as 00090 * a range returning meta-function 00091 */ 00092 template < 00093 typename ResultType, 00094 typename X, 00095 typename Functor, 00096 typename ValueType, 00097 typename IsFirst, 00098 typename IsLast 00099 > 00100 ResultType accumulate( 00101 Functor func, 00102 ValueType value, 00103 X, 00104 IsFirst is_first, 00105 IsLast is_last 00106 ) 00107 { 00108 MIRROR_ASSERT_RETURNS_RANGE(X); 00109 return accumulate<ResultType>( 00110 func, 00111 value, 00112 typename X::type(), 00113 is_first, 00114 is_last 00115 ); 00116 } 00117 00118 template <class ResultType, class Functor> 00119 struct accumulate_ii_remover 00120 { 00121 Functor func; 00122 00123 inline accumulate_ii_remover(Functor f) 00124 : func(f) 00125 { } 00126 00127 template <typename ValueType, class IterInfo> 00128 inline ResultType operator()(ValueType value, IterInfo) const 00129 { 00130 return func(value, typename IterInfo::type()); 00131 } 00132 }; 00133 00134 } // namespace aux 00135 00137 00147 template < 00148 typename Range, 00149 typename ResultType, 00150 typename Functor, 00151 typename ValueType 00152 > ResultType accumulate(Functor func, ValueType initial) 00153 { 00154 return aux::accumulate<ResultType>( 00155 aux::accumulate_ii_remover<ResultType, Functor>(func), 00156 initial, 00157 Range(), 00158 std::true_type(), 00159 std::false_type() 00160 ); 00161 } 00162 00164 00183 template < 00184 typename Range, 00185 typename ResultType, 00186 typename Functor, 00187 typename ValueType 00188 > ResultType accumulate_ii(Functor func, ValueType initial) 00189 { 00190 return aux::accumulate<ResultType>( 00191 func, 00192 initial, 00193 Range(), 00194 std::true_type(), 00195 std::false_type() 00196 ); 00197 } 00198 00199 } // namespace mp 00200 MIRROR_NAMESPACE_END 00201 00202 #endif //include guard 00203