]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/poly_collection/detail/functional.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / poly_collection / detail / functional.hpp
1 /* Copyright 2016-2017 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/poly_collection for library home page.
7 */
8
9 #ifndef BOOST_POLY_COLLECTION_DETAIL_FUNCTIONAL_HPP
10 #define BOOST_POLY_COLLECTION_DETAIL_FUNCTIONAL_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/config.hpp>
17 #include <boost/detail/workaround.hpp>
18 #include <boost/poly_collection/detail/integer_sequence.hpp>
19 #include <boost/poly_collection/detail/workaround_dr1467.hpp>
20 #include <tuple>
21 #include <utility>
22
23 /* Assorted functional utilities. Much of this would be almost trivial with
24 * C++14 generic lambdas.
25 */
26
27 #if BOOST_WORKAROUND(BOOST_MSVC,>=1910)
28 /* https://lists.boost.org/Archives/boost/2017/06/235687.php */
29
30 #define BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(name,f) \
31 struct name \
32 { \
33 template<typename... Args> \
34 auto operator()(Args&&... args)const \
35 { \
36 return f(std::forward<Args>(args)...); \
37 } \
38 };
39 #else
40 #define BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(name,f) \
41 struct name \
42 { \
43 BOOST_POLY_COLLECTION_WORKAROUND_DR1467(name) \
44 \
45 template<typename... Args> \
46 auto operator()(Args&&... args)const-> \
47 decltype(f(std::forward<Args>(args)...)) \
48 { \
49 return f(std::forward<Args>(args)...); \
50 } \
51 };
52 #endif
53
54 namespace boost{
55
56 namespace poly_collection{
57
58 namespace detail{
59
60 template<typename F,typename... TailArgs>
61 struct tail_closure_class
62 {
63 tail_closure_class(const F& f,std::tuple<TailArgs...> t):f(f),t(t){}
64
65 template<typename... Args>
66 using return_type=decltype(
67 std::declval<F>()(std::declval<Args>()...,std::declval<TailArgs>()...));
68
69 template<typename... Args,std::size_t... I>
70 return_type<Args&&...> call(index_sequence<I...>,Args&&... args)
71 {
72 return f(std::forward<Args>(args)...,std::get<I>(t)...);
73 }
74
75 template<typename... Args>
76 return_type<Args&&...> operator()(Args&&... args)
77 {
78 return call(
79 make_index_sequence<sizeof...(TailArgs)>{},std::forward<Args>(args)...);
80 }
81
82 F f;
83 std::tuple<TailArgs...> t;
84 };
85
86 template<typename F,typename... Args>
87 tail_closure_class<F,Args&&...> tail_closure(const F& f,Args&&... args)
88 {
89 return {f,std::forward_as_tuple(std::forward<Args>(args)...)};
90 }
91
92 template<typename F,typename... HeadArgs>
93 struct head_closure_class
94 {
95 head_closure_class(const F& f,std::tuple<HeadArgs...> t):f(f),t(t){}
96
97 template<typename... Args>
98 using return_type=decltype(
99 std::declval<F>()(std::declval<HeadArgs>()...,std::declval<Args>()...));
100
101 template<typename... Args,std::size_t... I>
102 return_type<Args&&...> call(index_sequence<I...>,Args&&... args)
103 {
104 return f(std::get<I>(t)...,std::forward<Args>(args)...);
105 }
106
107 template<typename... Args>
108 return_type<Args&&...> operator()(Args&&... args)
109 {
110 return call(
111 make_index_sequence<sizeof...(HeadArgs)>{},std::forward<Args>(args)...);
112 }
113
114 F f;
115 std::tuple<HeadArgs...> t;
116 };
117
118 template<typename F,typename... Args>
119 head_closure_class<F,Args&&...> head_closure(const F& f,Args&&... args)
120 {
121 return {f,std::forward_as_tuple(std::forward<Args>(args)...)};
122 }
123
124 template<typename ReturnType,typename F>
125 struct cast_return_class
126 {
127 cast_return_class(const F& f):f(f){}
128
129 template<typename... Args>
130 ReturnType operator()(Args&&... args)const
131 {
132 return static_cast<ReturnType>(f(std::forward<Args>(args)...));
133 }
134
135 F f;
136 };
137
138 template<typename ReturnType,typename F>
139 cast_return_class<ReturnType,F> cast_return(const F& f)
140 {
141 return {f};
142 }
143
144 template<typename F>
145 struct deref_to_class
146 {
147 deref_to_class(const F& f):f(f){}
148
149 template<typename... Args>
150 auto operator()(Args&&... args)->decltype(std::declval<F>()(*args...))
151 {
152 return f(*args...);
153 }
154
155 F f;
156 };
157
158 template<typename F>
159 deref_to_class<F> deref_to(const F& f)
160 {
161 return {f};
162 }
163
164 template<typename F>
165 struct deref_1st_to_class
166 {
167 deref_1st_to_class(const F& f):f(f){}
168
169 template<typename Arg,typename... Args>
170 auto operator()(Arg&& arg,Args&&... args)
171 ->decltype(std::declval<F>()(*arg,std::forward<Args>(args)...))
172 {
173 return f(*arg,std::forward<Args>(args)...);
174 }
175
176 F f;
177 };
178
179 template<typename F>
180 deref_1st_to_class<F> deref_1st_to(const F& f)
181 {
182 return {f};
183 }
184
185 struct transparent_equal_to
186 {
187 BOOST_POLY_COLLECTION_WORKAROUND_DR1467(transparent_equal_to)
188
189 template<typename T,typename U>
190 auto operator()(T&& x,U&& y)const
191 noexcept(noexcept(std::forward<T>(x)==std::forward<U>(y)))
192 ->decltype(std::forward<T>(x)==std::forward<U>(y))
193 {
194 return std::forward<T>(x)==std::forward<U>(y);
195 }
196 };
197
198 } /* namespace poly_collection::detail */
199
200 } /* namespace poly_collection */
201
202 } /* namespace boost */
203
204 #endif