Mirror reflection library 0.5.13

mirror/meta_prog/accumulate.hpp

Go to the documentation of this file.
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 

Copyright © 2006-2011 Matus Chochlik, University of Zilina, Zilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Fri Dec 16 2011 by Doxygen (version 1.7.3).
Important note: Although the 'boostified' version of Mirror uses the Boost C++ libraries Coding Guidelines and is implemented inside of the boost namespace, it IS NOT an officially reviewed and accepted Boost library. Mirror is being developed with the intention to be submitted for review for inclusion to the Boost C++ libraries.