Created
June 10, 2014 15:20
-
-
Save Fuyutsubaki/8bb1ce4866373efabcab to your computer and use it in GitHub Desktop.
constexpr binary fold
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<utility> | |
#include<sprout/functional.hpp> | |
#include <sprout/utility.hpp> | |
namespace deteil | |
{ | |
template<std::size_t begin, std::size_t length> | |
struct binary_fold_impl | |
{ | |
using lhs = binary_fold_impl<begin, length / 2>; | |
using rhs = binary_fold_impl<begin + length / 2, length - length / 2>; | |
template<class Func, class...T> | |
constexpr static auto fold(Func func, T&&...args) | |
{ | |
return func | |
( | |
lhs::fold(func, sprout::forward<T>(args)...) | |
, rhs::fold(func, sprout::forward<T>(args)...) | |
); | |
} | |
}; | |
template<class List> | |
struct at_Impl{}; | |
template<std::size_t...N> | |
struct at_Impl<std::index_sequence<N...>> | |
{ | |
template<std::size_t > | |
struct Ignore | |
{ | |
template<class T> | |
constexpr Ignore(T&&){} | |
}; | |
template<class T, class ...R> | |
constexpr static T&& get(Ignore<N>..., T&&x, R&&...) | |
{ | |
return sprout::forward<T>(x); | |
} | |
}; | |
template<std::size_t begin> | |
struct binary_fold_impl<begin, 1> | |
{ | |
using at = at_Impl<std::make_index_sequence<begin>>; | |
template<class Func, class...T> | |
constexpr static auto fold(Func, T&&...args) | |
{ | |
return at::get(sprout::forward<T>(args)...); | |
} | |
}; | |
} | |
template<class Func,class...R> | |
constexpr auto binary_fold(Func func, R&&...args) | |
{ | |
return deteil::binary_fold_impl<0, sizeof...(R)>::fold(func, sprout::forward<R>(args)...); | |
} | |
int main() | |
{ | |
static_assert(binary_fold(sprout::plus<>{},1,2,3,4)==10,""); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment