diff options
Diffstat (limited to 'boost/hof/flip.hpp')
-rw-r--r-- | boost/hof/flip.hpp | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/boost/hof/flip.hpp b/boost/hof/flip.hpp new file mode 100644 index 0000000000..cd7a1f9174 --- /dev/null +++ b/boost/hof/flip.hpp @@ -0,0 +1,107 @@ +/*============================================================================= + Copyright (c) 2015 Paul Fultz II + flip.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_FLIP_H +#define BOOST_HOF_GUARD_FLIP_H + +/// flip +/// ==== +/// +/// Description +/// ----------- +/// +/// The `flip` function adaptor swaps the first two parameters. +/// +/// Synopsis +/// -------- +/// +/// template<class F> +/// flip_adaptor<F> flip(F f); +/// +/// Semantics +/// --------- +/// +/// assert(flip(f)(x, y, xs...) == f(y, x, xs...)); +/// +/// Requirements +/// ------------ +/// +/// F must be at least: +/// +/// * [BinaryInvocable](BinaryInvocable) +/// +/// Or: +/// +/// * [Invocable](Invocable) with more than two argurments +/// +/// And: +/// +/// * MoveConstructible +/// +/// Example +/// ------- +/// +/// #include <boost/hof.hpp> +/// #include <cassert> +/// +/// int main() { +/// int r = boost::hof::flip(boost::hof::_ - boost::hof::_)(2, 5); +/// assert(r == 3); +/// } +/// + +#include <boost/hof/detail/callable_base.hpp> +#include <boost/hof/reveal.hpp> +#include <boost/hof/detail/make.hpp> +#include <boost/hof/detail/static_const_var.hpp> + +namespace boost { namespace hof { + +template<class F> +struct flip_adaptor : detail::callable_base<F> +{ + typedef flip_adaptor fit_rewritable1_tag; + BOOST_HOF_INHERIT_CONSTRUCTOR(flip_adaptor, detail::callable_base<F>); + + template<class... Ts> + constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const + { + return boost::hof::always_ref(*this)(xs...); + } + + struct flip_failure + { + template<class Failure> + struct apply + { + template<class T, class U, class... Ts> + struct of + : Failure::template of<U, T, Ts...> + {}; + }; + }; + + struct failure + : failure_map<flip_failure, detail::callable_base<F>> + {}; + + BOOST_HOF_RETURNS_CLASS(flip_adaptor); + + template<class T, class U, class... Ts> + constexpr BOOST_HOF_SFINAE_RESULT(const detail::callable_base<F>&, id_<U>, id_<T>, id_<Ts>...) + operator()(T&& x, U&& y, Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS + ( + (BOOST_HOF_MANGLE_CAST(const detail::callable_base<F>&)(BOOST_HOF_CONST_THIS->base_function(xs...))) + (BOOST_HOF_FORWARD(U)(y), BOOST_HOF_FORWARD(T)(x), BOOST_HOF_FORWARD(Ts)(xs)...) + ); +}; + +BOOST_HOF_DECLARE_STATIC_VAR(flip, detail::make<flip_adaptor>); + +}} // namespace boost::hof + +#endif |