1/*=============================================================================
2 Copyright (c) 2014 Paul Fultz II
3 always.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_FUNCTION_ALWAYS_H
9#define BOOST_HOF_GUARD_FUNCTION_ALWAYS_H
10
11#include <boost/hof/detail/delegate.hpp>
12#include <boost/hof/detail/unwrap.hpp>
13#include <boost/hof/detail/static_const_var.hpp>
14
15/// always
16/// ======
17///
18/// Description
19/// -----------
20///
21/// The `always` function returns a function object that will always return
22/// the value given to it, no matter what parameters are passed to the
23/// function object. The nullary version(i.e. `always(void)`) will return
24/// `void`. On compilers, that don't support constexpr functions returning
25/// `void`, a private empty type is returned instead. This return type is
26/// specified as `BOOST_HOF_ALWAYS_VOID_RETURN`.
27///
28/// Synopsis
29/// --------
30///
31/// template<class T>
32/// constexpr auto always(T value);
33///
34/// template<class T>
35/// constexpr auto always(void);
36///
37///
38/// Semantics
39/// ---------
40///
41/// assert(always(x)(xs...) == x);
42///
43/// Requirements
44/// ------------
45///
46/// T must be:
47///
48/// * CopyConstructible
49///
50/// Example
51/// -------
52///
53/// #include <boost/hof.hpp>
54/// #include <algorithm>
55/// #include <cassert>
56/// using namespace boost::hof;
57///
58/// int main() {
59/// int ten = 10;
60/// assert( always(ten)(1,2,3,4,5) == 10 );
61/// }
62///
63/// // Count all
64/// template<class Iterator, class T>
65/// auto count(Iterator first, Iterator last)
66/// {
67/// return std::count_if(first, last, always(true));
68/// }
69///
70
71
72#ifndef BOOST_HOF_NO_CONSTEXPR_VOID
73#if defined(__clang__) && BOOST_HOF_HAS_RELAXED_CONSTEXPR
74#define BOOST_HOF_NO_CONSTEXPR_VOID 0
75#else
76#define BOOST_HOF_NO_CONSTEXPR_VOID 1
77#endif
78#endif
79
80namespace boost { namespace hof { namespace always_detail {
81
82template<class T, class=void>
83struct always_base
84{
85 T x;
86
87 BOOST_HOF_DELEGATE_CONSTRUCTOR(always_base, T, x)
88
89 typedef typename detail::unwrap_reference<T>::type result_type;
90
91 template<class... As>
92 constexpr result_type
93 operator()(As&&...) const
94 noexcept(std::is_reference<result_type>::value || BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(result_type))
95 {
96 return this->x;
97 }
98};
99
100template<class T>
101struct always_base<T, typename std::enable_if<!BOOST_HOF_IS_EMPTY(T)>::type>
102{
103 T x;
104
105 constexpr always_base(T xp) noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
106 : x(xp)
107 {}
108
109 typedef typename detail::unwrap_reference<T>::type result_type;
110
111 template<class... As>
112 constexpr result_type
113 operator()(As&&...) const
114 noexcept(std::is_reference<result_type>::value || BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(result_type))
115 {
116 return this->x;
117 }
118};
119
120#if BOOST_HOF_NO_CONSTEXPR_VOID
121#define BOOST_HOF_ALWAYS_VOID_RETURN boost::hof::always_detail::always_base<void>::void_
122#else
123#define BOOST_HOF_ALWAYS_VOID_RETURN void
124#endif
125
126template<>
127struct always_base<void>
128{
129
130 constexpr always_base() noexcept
131 {}
132
133 struct void_ {};
134
135 template<class... As>
136 constexpr BOOST_HOF_ALWAYS_VOID_RETURN
137 operator()(As&&...) const noexcept
138 {
139#if BOOST_HOF_NO_CONSTEXPR_VOID
140 return void_();
141#endif
142 }
143};
144
145struct always_f
146{
147 template<class T>
148 constexpr always_detail::always_base<T> operator()(T x) const noexcept(BOOST_HOF_IS_NOTHROW_COPY_CONSTRUCTIBLE(T))
149 {
150 return always_detail::always_base<T>(x);
151 }
152
153 constexpr always_detail::always_base<void> operator()() const noexcept
154 {
155 return always_detail::always_base<void>();
156 }
157};
158
159struct always_ref_f
160{
161 template<class T>
162 constexpr always_detail::always_base<T&> operator()(T& x) const noexcept
163 {
164 return always_detail::always_base<T&>(x);
165 }
166};
167
168}
169BOOST_HOF_DECLARE_STATIC_VAR(always, always_detail::always_f);
170BOOST_HOF_DECLARE_STATIC_VAR(always_ref, always_detail::always_ref_f);
171
172}} // namespace boost::hof
173
174#endif
175

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