/*============================================================================= Copyright (c) 2015 Paul Fultz II repeat.h Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #ifndef FIT_GUARD_REPEAT_H #define FIT_GUARD_REPEAT_H /// repeat /// ====== /// /// Description /// ----------- /// /// The `repeat` function decorator will repeatedly apply a function a given /// number of times. /// /// /// Synopsis /// -------- /// /// template /// constexpr repeat_adaptor repeat(Integral); /// /// Requirements /// ------------ /// /// Integral must be: /// /// * Integral /// /// Or: /// /// * IntegralConstant /// /// Example /// ------- /// /// struct increment /// { /// template /// constexpr T operator()(T x) const /// { /// return x + 1; /// } /// }; /// /// auto increment_by_5 = fit::repeat(std::integral_constant())(increment()); /// assert(increment_by_5(1) == 6); /// #include #include #include #include #include #include #include #include #include namespace fit { namespace detail { template struct repeater { template constexpr FIT_SFINAE_RESULT(repeater, id_, result_of...>) operator()(const F& f, Ts&&... xs) const FIT_SFINAE_RETURNS ( repeater()(f, f(FIT_FORWARD(Ts)(xs)...)) ); }; template<> struct repeater<0> { template constexpr T operator()(const F&, T&& x) const { return x; } }; struct repeat_constant_decorator { template constexpr auto operator()(Integral, const F& f, Ts&&... xs) const FIT_RETURNS ( detail::repeater() ( f, FIT_FORWARD(Ts)(xs)... ) ); }; template struct repeat_integral_decorator { template> constexpr auto operator()(Integral n, const F& f, T&& x, Ts&&... xs) const FIT_RETURNS ( (n) ? Self()(n-1, f, f(FIT_FORWARD(T)(x), FIT_FORWARD(Ts)(xs)...)) : FIT_FORWARD(T)(x) ); }; template<> struct repeat_integral_decorator<0> { template> auto operator()(Integral n, const F& f, T&& x) const -> decltype(f(FIT_FORWARD(T)(x))) { return (n) ? Self()(n-1, f, f(FIT_FORWARD(T)(x))) : FIT_FORWARD(T)(x); } }; } FIT_DECLARE_STATIC_VAR(repeat, decorate_adaptor< fit::conditional_adaptor< detail::repeat_constant_decorator, detail::repeat_integral_decorator >>); } // namespace fit #endif