1/*=============================================================================
2 Copyright (c) 2014 Paul Fultz II
3 result.h
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6==============================================================================*/
7
8#ifndef BOOST_HOF_GUARD_RESULT_H
9#define BOOST_HOF_GUARD_RESULT_H
10
11/// result
12/// ======
13///
14/// Description
15/// -----------
16///
17/// The `result` function adaptor sets the return type for the function, which
18/// can be useful when dealing with multiple overloads. Since the return type
19/// is no longer dependent on the parameters passed to the function, the
20/// `result_adaptor` provides a nested `result_type` that is the return type
21/// of the function.
22///
23/// Synopsis
24/// --------
25///
26/// template<class Result, class F>
27/// constexpr result_adaptor<Result, F> result(F f);
28///
29/// Requirements
30/// ------------
31///
32/// F must be:
33///
34/// * [ConstInvocable](ConstInvocable)
35/// * MoveConstructible
36///
37/// Example
38/// -------
39///
40/// #include <boost/hof.hpp>
41/// #include <cassert>
42///
43/// struct id
44/// {
45/// template<class T>
46/// T operator()(T x) const
47/// {
48/// return x;
49/// }
50/// };
51///
52/// int main() {
53/// auto int_result = boost::hof::result<int>(id());
54/// static_assert(std::is_same<decltype(int_result(true)), int>::value, "Not the same type");
55/// }
56///
57
58#include <boost/hof/detail/callable_base.hpp>
59#include <boost/hof/is_invocable.hpp>
60#include <boost/hof/always.hpp>
61#include <boost/hof/reveal.hpp>
62
63namespace boost { namespace hof {
64
65template<class Result, class F>
66struct result_adaptor : detail::callable_base<F>
67{
68 BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
69
70 typedef Result result_type;
71
72 struct failure
73 : failure_for<detail::callable_base<F>>
74 {};
75
76 template<class... Ts>
77 constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
78 {
79 return boost::hof::always_ref(*this)(xs...);
80 }
81
82 template<class... Ts, class=typename std::enable_if<(boost::hof::is_invocable<F, Ts...>::value)>::type>
83 constexpr result_type operator()(Ts&&... xs) const
84 {
85 return this->base_function(xs...)(BOOST_HOF_FORWARD(Ts)(xs)...);
86 };
87};
88
89template<class F>
90struct result_adaptor<void, F> : detail::callable_base<F>
91{
92 BOOST_HOF_INHERIT_CONSTRUCTOR(result_adaptor, detail::callable_base<F>)
93
94 typedef void result_type;
95
96 template<class... Ts>
97 constexpr const detail::callable_base<F>& base_function(Ts&&... xs) const
98 {
99 return boost::hof::always_ref(*this)(xs...);
100 }
101
102 template<class... Ts, class=typename std::enable_if<(boost::hof::is_invocable<F, Ts...>::value)>::type>
103 constexpr typename detail::holder<Ts...>::type operator()(Ts&&... xs) const
104 {
105 return (typename detail::holder<Ts...>::type)this->base_function(xs...)(BOOST_HOF_FORWARD(Ts)(xs)...);
106 };
107};
108
109#if BOOST_HOF_HAS_VARIABLE_TEMPLATES
110namespace result_detail {
111template<class Result>
112struct result_f
113{
114 template<class F>
115 constexpr result_adaptor<Result, F> operator()(F f) const
116 {
117 return result_adaptor<Result, F>(boost::hof::move(f));
118 }
119};
120
121}
122
123template<class Result>
124static constexpr auto result = result_detail::result_f<Result>{};
125#else
126template<class Result, class F>
127constexpr result_adaptor<Result, F> result(F f)
128{
129 return result_adaptor<Result, F>(boost::hof::move(f));
130}
131#endif
132
133}} // namespace boost::hof
134
135#endif
136

source code of boost/libs/hof/include/boost/hof/result.hpp