Edit: /usr/include/boost/hof/apply_eval.hpp (4428B)
/*=============================================================================
Copyright (c) 2015 Paul Fultz II
apply_eval.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 BOOST_HOF_GUARD_APPLY_EVAL_H
#define BOOST_HOF_GUARD_APPLY_EVAL_H
/// apply_eval
/// ==========
///
/// Description
/// -----------
///
/// The `apply_eval` function work like [`apply`](/include/boost/hof/apply), except it calls
/// [`eval`](/include/boost/hof/eval) on each of its arguments. Each [`eval`](/include/boost/hof/eval) call is
/// always ordered from left-to-right.
///
/// Synopsis
/// --------
///
/// template
/// constexpr auto apply_eval(F&& f, Ts&&... xs);
///
/// Semantics
/// ---------
///
/// assert(apply_eval(f)(xs...) == f(eval(xs)...));
///
/// Requirements
/// ------------
///
/// F must be:
///
/// * [ConstInvocable](ConstInvocable)
///
/// Ts must be:
///
/// * [EvaluatableFunctionObject](EvaluatableFunctionObject)
///
/// Example
/// -------
///
/// #include
/// #include
///
/// struct sum_f
/// {
/// template
/// T operator()(T x, U y) const
/// {
/// return x+y;
/// }
/// };
///
/// int main() {
/// assert(boost::hof::apply_eval(sum_f(), []{ return 1; }, []{ return 2; }) == 3);
/// }
///
#include
#include
#include
#include
#include
#include
#if BOOST_HOF_NO_ORDERED_BRACE_INIT
#include
#include
#endif
namespace boost { namespace hof {
namespace detail {
#if BOOST_HOF_NO_ORDERED_BRACE_INIT
template
constexpr R eval_ordered(const F& f, Pack&& p)
{
return p(f);
}
template
constexpr R eval_ordered(const F& f, Pack&& p, T&& x, Ts&&... xs)
{
return boost::hof::detail::eval_ordered(f, boost::hof::pack_join(BOOST_HOF_FORWARD(Pack)(p), boost::hof::pack_forward(boost::hof::eval(x))), BOOST_HOF_FORWARD(Ts)(xs)...);
}
#else
template
struct eval_helper
{
R result;
template
constexpr eval_helper(const F& f, Ts&&... xs) : result(boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...))
{}
};
template<>
struct eval_helper
{
int x;
template
constexpr eval_helper(const F& f, Ts&&... xs) : x((boost::hof::apply(f, BOOST_HOF_FORWARD(Ts)(xs)...), 0))
{}
};
#endif
struct apply_eval_f
{
template(), boost::hof::eval(std::declval())...)
),
class=typename std::enable_if<(!std::is_void::value)>::type
>
constexpr R operator()(const F& f, Ts&&... xs) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(boost::hof::apply(f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...))
{
return
#if BOOST_HOF_NO_ORDERED_BRACE_INIT
boost::hof::detail::eval_ordered
(f, boost::hof::pack(), BOOST_HOF_FORWARD(Ts)(xs)...);
#else
boost::hof::detail::eval_helper
{f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...}.result;
#endif
}
template(), boost::hof::eval(std::declval())...)
),
class=typename std::enable_if<(std::is_void::value)>::type
>
constexpr typename detail::holder::type
operator()(const F& f, Ts&&... xs) const BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(boost::hof::apply(f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...))
{
return (typename detail::holder::type)
#if BOOST_HOF_NO_ORDERED_BRACE_INIT
boost::hof::detail::eval_ordered
(f, boost::hof::pack(), BOOST_HOF_FORWARD(Ts)(xs)...);
#else
boost::hof::detail::eval_helper
{f, boost::hof::eval(BOOST_HOF_FORWARD(Ts)(xs))...};
#endif
}
};
}
BOOST_HOF_DECLARE_STATIC_VAR(apply_eval, detail::apply_eval_f);
}} // namespace boost::hof
#endif