Skip to content

Instantly share code, notes, and snippets.

@Fuyutsubaki
Created June 10, 2014 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fuyutsubaki/8bb1ce4866373efabcab to your computer and use it in GitHub Desktop.
Save Fuyutsubaki/8bb1ce4866373efabcab to your computer and use it in GitHub Desktop.
constexpr binary fold
#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