Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:43:50

0001 /*=============================================================================
0002     Copyright (c) 2014 Paul Fultz II
0003     indirect.h
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 ==============================================================================*/
0007 
0008 #ifndef BOOST_HOF_GUARD_FUNCTION_INDIRECT_H
0009 #define BOOST_HOF_GUARD_FUNCTION_INDIRECT_H
0010 
0011 /// indirect
0012 /// ========
0013 /// 
0014 /// Description
0015 /// -----------
0016 /// 
0017 /// The `indirect` function adaptor dereferences the object before calling it.
0018 /// 
0019 /// Synopsis
0020 /// --------
0021 /// 
0022 ///     template<class F>
0023 ///     constexpr indirect_adaptor<F> indirect(F f);
0024 /// 
0025 /// Semantics
0026 /// ---------
0027 /// 
0028 ///     assert(indirect(f)(xs...) == (*f)(xs...));
0029 /// 
0030 /// Requirements
0031 /// ------------
0032 /// 
0033 /// F must be:
0034 /// 
0035 /// * MoveConstructible
0036 /// * Dereferenceable
0037 /// 
0038 /// Example
0039 /// -------
0040 /// 
0041 ///     #include <boost/hof.hpp>
0042 ///     #include <cassert>
0043 ///     #include <memory>
0044 ///     using namespace boost::hof;
0045 /// 
0046 ///     struct sum
0047 ///     {
0048 ///         template<class T, class U>
0049 ///         T operator()(T x, U y) const
0050 ///         {
0051 ///             return x+y;
0052 ///         }
0053 ///     };
0054 /// 
0055 ///     int main() {
0056 ///         int r = indirect(std::make_unique<sum>())(3,2);
0057 ///         assert(r == 5);
0058 ///     }
0059 /// 
0060 
0061 #include <boost/hof/detail/delegate.hpp>
0062 #include <boost/hof/detail/result_of.hpp>
0063 #include <boost/hof/reveal.hpp>
0064 #include <boost/hof/always.hpp>
0065 #include <boost/hof/detail/move.hpp>
0066 #include <boost/hof/detail/make.hpp>
0067 #include <boost/hof/detail/static_const_var.hpp>
0068 
0069 namespace boost { namespace hof {
0070 // TODO: Support non-classes as well
0071 template<class F>
0072 struct indirect_adaptor : F
0073 {
0074     typedef indirect_adaptor fit_rewritable1_tag;
0075     BOOST_HOF_INHERIT_CONSTRUCTOR(indirect_adaptor, F);
0076 
0077     template<class... Ts>
0078     constexpr const F& base_function(Ts&&... xs) const noexcept
0079     {
0080         return boost::hof::always_ref(*this)(xs...);
0081     }
0082 
0083     struct failure
0084     : failure_for<decltype(*std::declval<F>())>
0085     {};
0086 
0087     BOOST_HOF_RETURNS_CLASS(indirect_adaptor);
0088 
0089     template<class... Ts>
0090     constexpr BOOST_HOF_SFINAE_RESULT(decltype(*std::declval<F>()), id_<Ts>...) 
0091     operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
0092     (
0093         (*BOOST_HOF_MANGLE_CAST(const F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...)
0094     );
0095 };
0096 
0097 template<class F>
0098 struct indirect_adaptor<F*>
0099 {
0100     typedef indirect_adaptor fit_rewritable1_tag;
0101     F* f;
0102     constexpr indirect_adaptor() noexcept
0103     {}
0104 
0105     constexpr indirect_adaptor(F* x) noexcept
0106     : f(x)
0107     {}
0108 
0109     template<class... Ts>
0110     constexpr F& base_function(Ts&&...) const noexcept
0111     {
0112         return *f;
0113     }
0114 
0115     struct failure
0116     : failure_for<F>
0117     {};
0118 
0119     BOOST_HOF_RETURNS_CLASS(indirect_adaptor);
0120 
0121     template<class... Ts>
0122     constexpr BOOST_HOF_SFINAE_RESULT(F, id_<Ts>...) 
0123     operator()(Ts&&... xs) const BOOST_HOF_SFINAE_RETURNS
0124     (
0125         (BOOST_HOF_MANGLE_CAST(F&)(BOOST_HOF_CONST_THIS->base_function(xs...)))(BOOST_HOF_FORWARD(Ts)(xs)...)
0126     );
0127 };
0128 
0129 BOOST_HOF_DECLARE_STATIC_VAR(indirect, detail::make<indirect_adaptor>);
0130 
0131 }} // namespace boost::hof
0132 
0133 #endif