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