]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/require_concept.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / require_concept.hpp
CommitLineData
20effc67
TL
1//
2// require_concept.hpp
3// ~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_REQUIRE_CONCEPT_HPP
12#define BOOST_ASIO_REQUIRE_CONCEPT_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19#include <boost/asio/detail/type_traits.hpp>
20#include <boost/asio/is_applicable_property.hpp>
21#include <boost/asio/traits/require_concept_member.hpp>
22#include <boost/asio/traits/require_concept_free.hpp>
23#include <boost/asio/traits/static_require_concept.hpp>
24
25#include <boost/asio/detail/push_options.hpp>
26
27#if defined(GENERATING_DOCUMENTATION)
28
29namespace boost {
30namespace asio {
31
32/// A customisation point that applies a concept-enforcing property to an
33/// object.
34/**
35 * The name <tt>require_concept</tt> denotes a customization point object. The
36 * expression <tt>boost::asio::require_concept(E, P)</tt> for some
37 * subexpressions <tt>E</tt> and <tt>P</tt> (with types <tt>T =
38 * decay_t<decltype(E)></tt> and <tt>Prop = decay_t<decltype(P)></tt>) is
39 * expression-equivalent to:
40 *
41 * @li If <tt>is_applicable_property_v<T, Prop> &&
42 * Prop::is_requirable_concept</tt> is not a well-formed constant expression
43 * with value <tt>true</tt>, <tt>boost::asio::require_concept(E, P)</tt> is
44 * ill-formed.
45 *
46 * @li Otherwise, <tt>E</tt> if the expression <tt>Prop::template
47 * static_query_v<T> == Prop::value()</tt> is a well-formed constant
48 * expression with value <tt>true</tt>.
49 *
50 * @li Otherwise, <tt>(E).require_concept(P)</tt> if the expression
51 * <tt>(E).require_concept(P)</tt> is well-formed.
52 *
53 * @li Otherwise, <tt>require_concept(E, P)</tt> if the expression
54 * <tt>require_concept(E, P)</tt> is a valid expression with overload
55 * resolution performed in a context that does not include the declaration
56 * of the <tt>require_concept</tt> customization point object.
57 *
58 * @li Otherwise, <tt>boost::asio::require_concept(E, P)</tt> is ill-formed.
59 */
60inline constexpr unspecified require_concept = unspecified;
61
62/// A type trait that determines whether a @c require_concept expression is
63/// well-formed.
64/**
65 * Class template @c can_require_concept is a trait that is derived from
66 * @c true_type if the expression
67 * <tt>boost::asio::require_concept(std::declval<T>(),
68 * std::declval<Property>())</tt> is well formed; otherwise @c false_type.
69 */
70template <typename T, typename Property>
71struct can_require_concept :
72 integral_constant<bool, automatically_determined>
73{
74};
75
76/// A type trait that determines whether a @c require_concept expression will
77/// not throw.
78/**
79 * Class template @c is_nothrow_require_concept is a trait that is derived from
80 * @c true_type if the expression
81 * <tt>boost::asio::require_concept(std::declval<T>(),
82 * std::declval<Property>())</tt> is @c noexcept; otherwise @c false_type.
83 */
84template <typename T, typename Property>
85struct is_nothrow_require_concept :
86 integral_constant<bool, automatically_determined>
87{
88};
89
90/// A type trait that determines the result type of a @c require_concept
91/// expression.
92/**
93 * Class template @c require_concept_result is a trait that determines the
94 * result type of the expression
95 * <tt>boost::asio::require_concept(std::declval<T>(),
96 * std::declval<Property>())</tt>.
97 */
98template <typename T, typename Property>
99struct require_concept_result
100{
101 /// The result of the @c require_concept expression.
102 typedef automatically_determined type;
103};
104
105} // namespace asio
106} // namespace boost
107
108#else // defined(GENERATING_DOCUMENTATION)
109
110namespace asio_require_concept_fn {
111
112using boost::asio::decay;
113using boost::asio::declval;
114using boost::asio::enable_if;
115using boost::asio::is_applicable_property;
116using boost::asio::traits::require_concept_free;
117using boost::asio::traits::require_concept_member;
118using boost::asio::traits::static_require_concept;
119
120void require_concept();
121
122enum overload_type
123{
124 identity,
125 call_member,
126 call_free,
127 ill_formed
128};
129
130template <typename T, typename Properties, typename = void>
131struct call_traits
132{
133 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);
134 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
135 typedef void result_type;
136};
137
138template <typename T, typename Property>
139struct call_traits<T, void(Property),
140 typename enable_if<
141 (
142 is_applicable_property<
143 typename decay<T>::type,
144 typename decay<Property>::type
145 >::value
146 &&
147 decay<Property>::type::is_requirable_concept
148 &&
149 static_require_concept<T, Property>::is_valid
150 )
151 >::type>
152{
153 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);
154 BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
155 typedef BOOST_ASIO_MOVE_ARG(T) result_type;
156};
157
158template <typename T, typename Property>
159struct call_traits<T, void(Property),
160 typename enable_if<
161 (
162 is_applicable_property<
163 typename decay<T>::type,
164 typename decay<Property>::type
165 >::value
166 &&
167 decay<Property>::type::is_requirable_concept
168 &&
169 !static_require_concept<T, Property>::is_valid
170 &&
171 require_concept_member<T, Property>::is_valid
172 )
173 >::type> :
174 require_concept_member<T, Property>
175{
176 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);
177};
178
179template <typename T, typename Property>
180struct call_traits<T, void(Property),
181 typename enable_if<
182 (
183 is_applicable_property<
184 typename decay<T>::type,
185 typename decay<Property>::type
186 >::value
187 &&
188 decay<Property>::type::is_requirable_concept
189 &&
190 !static_require_concept<T, Property>::is_valid
191 &&
192 !require_concept_member<T, Property>::is_valid
193 &&
194 require_concept_free<T, Property>::is_valid
195 )
196 >::type> :
197 require_concept_free<T, Property>
198{
199 BOOST_ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);
200};
201
202struct impl
203{
204 template <typename T, typename Property>
205 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
206 call_traits<T, void(Property)>::overload == identity,
207 typename call_traits<T, void(Property)>::result_type
208 >::type
209 operator()(
210 BOOST_ASIO_MOVE_ARG(T) t,
211 BOOST_ASIO_MOVE_ARG(Property)) const
212 BOOST_ASIO_NOEXCEPT_IF((
213 call_traits<T, void(Property)>::is_noexcept))
214 {
215 return BOOST_ASIO_MOVE_CAST(T)(t);
216 }
217
218 template <typename T, typename Property>
219 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
220 call_traits<T, void(Property)>::overload == call_member,
221 typename call_traits<T, void(Property)>::result_type
222 >::type
223 operator()(
224 BOOST_ASIO_MOVE_ARG(T) t,
225 BOOST_ASIO_MOVE_ARG(Property) p) const
226 BOOST_ASIO_NOEXCEPT_IF((
227 call_traits<T, void(Property)>::is_noexcept))
228 {
229 return BOOST_ASIO_MOVE_CAST(T)(t).require_concept(
230 BOOST_ASIO_MOVE_CAST(Property)(p));
231 }
232
233 template <typename T, typename Property>
234 BOOST_ASIO_NODISCARD BOOST_ASIO_CONSTEXPR typename enable_if<
235 call_traits<T, void(Property)>::overload == call_free,
236 typename call_traits<T, void(Property)>::result_type
237 >::type
238 operator()(
239 BOOST_ASIO_MOVE_ARG(T) t,
240 BOOST_ASIO_MOVE_ARG(Property) p) const
241 BOOST_ASIO_NOEXCEPT_IF((
242 call_traits<T, void(Property)>::is_noexcept))
243 {
244 return require_concept(
245 BOOST_ASIO_MOVE_CAST(T)(t),
246 BOOST_ASIO_MOVE_CAST(Property)(p));
247 }
248};
249
250template <typename T = impl>
251struct static_instance
252{
253 static const T instance;
254};
255
256template <typename T>
257const T static_instance<T>::instance = {};
258
259} // namespace asio_require_concept_fn
260namespace boost {
261namespace asio {
262namespace {
263
264static BOOST_ASIO_CONSTEXPR const asio_require_concept_fn::impl&
265 require_concept = asio_require_concept_fn::static_instance<>::instance;
266
267} // namespace
268
269template <typename T, typename Property>
270struct can_require_concept :
271 integral_constant<bool,
272 asio_require_concept_fn::call_traits<T, void(Property)>::overload !=
273 asio_require_concept_fn::ill_formed>
274{
275};
276
277#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
278
279template <typename T, typename Property>
280constexpr bool can_require_concept_v
281 = can_require_concept<T, Property>::value;
282
283#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
284
285template <typename T, typename Property>
286struct is_nothrow_require_concept :
287 integral_constant<bool,
288 asio_require_concept_fn::call_traits<T, void(Property)>::is_noexcept>
289{
290};
291
292#if defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
293
294template <typename T, typename Property>
295constexpr bool is_nothrow_require_concept_v
296 = is_nothrow_require_concept<T, Property>::value;
297
298#endif // defined(BOOST_ASIO_HAS_VARIABLE_TEMPLATES)
299
300template <typename T, typename Property>
301struct require_concept_result
302{
303 typedef typename asio_require_concept_fn::call_traits<
304 T, void(Property)>::result_type type;
305};
306
307} // namespace asio
308} // namespace boost
309
310#endif // defined(GENERATING_DOCUMENTATION)
311
312#include <boost/asio/detail/pop_options.hpp>
313
314#endif // BOOST_ASIO_REQUIRE_CONCEPT_HPP