diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
commit | b8cf34c691623e4ec329053cbbf68522a855882d (patch) | |
tree | 34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/hof/indirect.hpp | |
parent | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff) | |
download | boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2 boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip |
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/hof/indirect.hpp')
-rw-r--r-- | boost/hof/indirect.hpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/boost/hof/indirect.hpp b/boost/hof/indirect.hpp new file mode 100644 index 0000000000..975f113fb9 --- /dev/null +++ b/boost/hof/indirect.hpp @@ -0,0 +1,133 @@ +/*============================================================================= + Copyright (c) 2014 Paul Fultz II + indirect.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_FUNCTION_INDIRECT_H +#define BOOST_HOF_GUARD_FUNCTION_INDIRECT_H + +/// indirect +/// ======== +/// +/// Description +/// ----------- +/// +/// The `indirect` function adaptor dereferences the object before calling it. +/// +/// Synopsis +/// -------- +/// +/// template<class F> +/// constexpr indirect_adaptor<F> indirect(F f); +/// +/// Semantics +/// --------- +/// +/// assert(indirect(f)(xs...) == (*f)(xs...)); +/// +/// Requirements +/// ------------ +/// +/// F must be: +/// +/// * MoveConstructible +/// * Dereferenceable +/// +/// Example +/// ------- +/// +/// #include <boost/hof.hpp> +/// #include <cassert> +/// #include <memory> +/// using namespace boost::hof; +/// +/// struct sum +/// { +/// template<class T, class U> +/// T operator()(T x, U y) const +/// { +/// return x+y; +/// } +/// }; +/// +/// int main() { +/// int r = indirect(std::make_unique<sum>())(3,2); +/// assert(r == 5); +/// } +/// + +#include <boost/hof/detail/delegate.hpp> +#include <boost/hof/detail/result_of.hpp> +#include <boost/hof/reveal.hpp> +#include <boost/hof/always.hpp> +#include <boost/hof/detail/move.hpp> +#include <boost/hof/detail/make.hpp> +#include <boost/hof/detail/static_const_var.hpp> + +namespace boost { namespace hof { +// TODO: Support non-classes as well +template<class F> +struct indirect_adaptor : F +{ + typedef indirect_adaptor fit_rewritable1_tag; + BOOST_HOF_INHERIT_CONSTRUCTOR(indirect_adaptor, F); + + template<class... Ts> + constexpr const F& base_function(Ts&&... xs) const noexcept + { + return boost::hof::always_ref(*this)(xs...); + } + + struct failure + : failure_for<decltype(*std::declval<F>())> + {}; + + BOOST_HOF_RETURNS_CLASS(indirect_adaptor); + + template<class... Ts> + constexpr BOOST_HOF_SFINAE_RESULT(decltype(*std::declval<F>()), id_<Ts>...) + operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS + ( + (*BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...) + ); +}; + +template<class F> +struct indirect_adaptor<F*> +{ + typedef indirect_adaptor fit_rewritable1_tag; + F* f; + constexpr indirect_adaptor() noexcept + {} + + constexpr indirect_adaptor(F* x) noexcept + : f(x) + {} + + template<class... Ts> + constexpr F& base_function(Ts&&...) const noexcept + { + return *f; + } + + struct failure + : failure_for<F> + {}; + + BOOST_HOF_RETURNS_CLASS(indirect_adaptor); + + template<class... Ts> + constexpr BOOST_HOF_SFINAE_RESULT(F, id_<Ts>...) + operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS + ( + (BOOST_HOF_MANGLE_CAST(F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...) + ); +}; + +BOOST_HOF_DECLARE_STATIC_VAR(indirect, detail::make<indirect_adaptor>); + +}} // namespace boost::hof + +#endif |