Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:16

0001 /*=============================================================================
0002     Copyright (c) 2014 Paul Fultz II
0003     result.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_RESULT_H
0009 #define BOOST_HOF_GUARD_RESULT_H
0010 
0011 /// result
0012 /// ======
0013 /// 
0014 /// Description
0015 /// -----------
0016 /// 
0017 /// The `result` function adaptor sets the return type for the function, which
0018 /// can be useful when dealing with multiple overloads. Since the return type
0019 /// is no longer dependent on the parameters passed to the function, the
0020 /// `result_adaptor` provides a nested `result_type` that is the return type
0021 /// of the function.
0022 /// 
0023 /// Synopsis
0024 /// --------
0025 /// 
0026 ///     template<class Result, class F>
0027 ///     constexpr result_adaptor<Result, F> result(F f);
0028 /// 
0029 /// Requirements
0030 /// ------------
0031 /// 
0032 /// F must be:
0033 /// 
0034 /// * [ConstInvocable](ConstInvocable)
0035 /// * MoveConstructible
0036 /// 
0037 /// Example
0038 /// -------
0039 /// 
0040 ///     #include <boost/hof.hpp>
0041 ///     #include <cassert>
0042 /// 
0043 ///     struct id
0044 ///     {
0045 ///         template<class T>
0046 ///         T operator()(T x) const
0047 ///         {
0048 ///             return x;
0049 ///         }
0050 ///     };
0051 /// 
0052 ///     int main() {
0053 ///         auto int_result = boost::hof::result<int>(id());
0054 ///         static_assert(std::is_same<decltype(int_result(true)), int>::value, "Not the same type");
0055 ///     }
0056 /// 
0057 
0058 #include <boost/hof/detail/callable_base.hpp>
0059 #include <boost/hof/is_invocable.hpp>
0060 #include <boost/hof/always.hpp>
0061 #include <boost/hof/reveal.hpp>
0062 
0063 namespace boost { namespace hof {
0064 
0065 template<class Result, class F>
0066 struct result_adaptor : detail::callable_base<F>
0067 {
0068     BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
0069 
0070     typedef Result result_type;
0071 
0072     struct failure
0073     : failure_for<detail::callable_base<F>>
0074     {};
0075 
0076     template<class... Ts>
0077     constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
0078     {
0079         return boost::hof::always_ref(*this)(xs...);
0080     }
0081 
0082     template<class... Ts, class=typename std::enable_if<(boost::hof::is_invocable<F, Ts...>::value)>::type>
0083     constexpr result_type operator()(Ts&&... xs) const
0084     {
0085         return this->base_function(xs...)(BOOST_HOF_FORWARD(Ts)(xs)...);
0086     };
0087 };
0088 
0089 template<class F>
0090 struct result_adaptor<void, F> : detail::callable_base<F>
0091 {
0092     BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
0093 
0094     typedef void result_type;
0095 
0096     template<class... Ts>
0097     constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
0098     {
0099         return boost::hof::always_ref(*this)(xs...);
0100     }
0101 
0102     template<class... Ts, class=typename std::enable_if<(boost::hof::is_invocable<F, Ts...>::value)>::type>
0103     constexpr typename detail::holder<Ts...>::type operator()(Ts&&... xs) const
0104     {
0105         return (typename detail::holder<Ts...>::type)this->base_function(xs...)(BOOST_HOF_FORWARD(Ts)(xs)...);
0106     };
0107 };
0108 
0109 #if BOOST_HOF_HAS_VARIABLE_TEMPLATES
0110 namespace result_detail {
0111 template<class Result>
0112 struct result_f
0113 {
0114     template<class F>
0115     constexpr result_adaptor<Result, F> operator()(F f) const
0116     {
0117         return result_adaptor<Result, F>(boost::hof::move(f));
0118     }
0119 };
0120 
0121 }
0122 
0123 template<class Result>
0124 static constexpr auto result = result_detail::result_f<Result>{};
0125 #else
0126 template<class Result, class F>
0127 constexpr result_adaptor<Result, F> result(F f)
0128 {
0129     return result_adaptor<Result, F>(boost::hof::move(f));
0130 }
0131 #endif
0132 
0133 }} // namespace boost::hof
0134 
0135 #endif