]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/experimental/bits/net.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / experimental / bits / net.h
CommitLineData
e5989e71
JW
1// Networking implementation details -*- C++ -*-
2
99dee823 3// Copyright (C) 2015-2021 Free Software Foundation, Inc.
e5989e71
JW
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file experimental/bits/net.h
26 * This is an internal header file, included by other library headers.
041aa6ab 27 * Do not attempt to use it directly. @headername{experimental/net}
e5989e71
JW
28 */
29
30#ifndef _GLIBCXX_EXPERIMENTAL_NET_H
31#define _GLIBCXX_EXPERIMENTAL_NET_H 1
32
33#pragma GCC system_header
34
35#if __cplusplus >= 201402L
36
37#include <type_traits>
38#include <system_error>
39#include <experimental/netfwd>
40
b780db2e
JW
41#if __cplusplus > 201703L
42# include <concepts>
43#endif
44
e5989e71
JW
45namespace std _GLIBCXX_VISIBILITY(default)
46{
a70a4be9 47_GLIBCXX_BEGIN_NAMESPACE_VERSION
e5989e71
JW
48namespace experimental
49{
50namespace net
51{
52inline namespace v1
53{
e5989e71 54
3084625d
JW
55 /** @addtogroup networking-ts
56 * @{
e5989e71
JW
57 */
58
59 template<typename _CompletionToken, typename _Signature, typename>
60 class async_result;
61
041aa6ab
JW
62 /// @cond undocumented
63
e5989e71
JW
64 // A type denoted by DEDUCED in the TS.
65 template<typename _CompletionToken, typename _Signature>
66 using __deduced_t = typename
67 async_result<decay_t<_CompletionToken>, _Signature, void>::return_type;
68
69 // Trait to check for construction from const/non-const lvalue/rvalue.
70 template<typename _Tp>
71 using __is_value_constructible = typename __and_<
72 is_copy_constructible<_Tp>, is_move_constructible<_Tp>,
73 is_constructible<_Tp, _Tp&>, is_constructible<_Tp, const _Tp&&>
74 >::type;
75
041aa6ab
JW
76 struct __throw_on_error
77 {
78 explicit
79 __throw_on_error(const char* __msg) : _M_msg(__msg) { }
80
81 ~__throw_on_error() noexcept(false)
e5989e71 82 {
041aa6ab
JW
83 if (_M_ec)
84 _GLIBCXX_THROW_OR_ABORT(system_error(_M_ec, _M_msg));
85 }
e5989e71 86
041aa6ab
JW
87 __throw_on_error(const __throw_on_error&) = delete;
88 __throw_on_error& operator=(const __throw_on_error&) = delete;
e5989e71 89
041aa6ab 90 operator error_code&() noexcept { return _M_ec; }
e5989e71 91
041aa6ab
JW
92 const char* _M_msg;
93 error_code _M_ec;
94 };
e5989e71 95
041aa6ab 96 /// @endcond
e5989e71
JW
97
98 // Base class for types meeting IntegerSocketOption requirements.
99 template<typename _Tp>
100 struct __sockopt_base
101 {
102 __sockopt_base() = default;
103
104 explicit __sockopt_base(int __val) : _M_value(__val) { }
105
106 int value() const noexcept { return _M_value; }
107
108 template<typename _Protocol>
109 void*
110 data(const _Protocol&) noexcept
111 { return std::addressof(_M_value); }
112
113 template<typename _Protocol>
114 const void*
115 data(const _Protocol&) const noexcept
116 { return std::addressof(_M_value); }
117
118 template<typename _Protocol>
119 size_t
120 size(const _Protocol&) const noexcept
121 { return sizeof(_M_value); }
122
123 template<typename _Protocol>
124 void
125 resize(const _Protocol&, size_t __s)
126 {
127 if (__s != sizeof(_M_value))
128 __throw_length_error("invalid value for socket option resize");
129 }
130
131 protected:
132 _Tp _M_value { };
133 };
134
135 // Base class for types meeting BooleanSocketOption requirements.
136 template<>
137 struct __sockopt_base<bool> : __sockopt_base<int>
138 {
139 __sockopt_base() = default;
140
141 explicit __sockopt_base(bool __val) : __sockopt_base<int>(__val) { }
142
143 bool value() const noexcept { return __sockopt_base<int>::_M_value; }
144 explicit operator bool() const noexcept { return value(); }
145 bool operator!() const noexcept { return !value(); }
146 };
147
148 template<typename _Derived, typename _Tp = int>
149 struct __sockopt_crtp : __sockopt_base<_Tp>
150 {
151 using __sockopt_base<_Tp>::__sockopt_base;
152
153 _Derived&
154 operator=(_Tp __value)
155 {
156 __sockopt_base<_Tp>::_M_value = __value;
157 return static_cast<_Derived&>(*this);
158 }
159
160 template<typename _Protocol>
161 int
162 level(const _Protocol&) const noexcept
163 { return _Derived::_S_level; }
164
165 template<typename _Protocol>
166 int
167 name(const _Protocol&) const noexcept
168 { return _Derived::_S_name; }
169 };
170
b780db2e
JW
171namespace __detail
172{
173#if __cpp_lib_concepts
174 template<typename _Tp>
175 concept __protocol_like
176 = copyable<_Tp> && requires { typename _Tp::endpoint; };
177
178 // Endpoint requirements for non-extensible implementations.
179 template<typename _Tp>
180 concept __endpoint_base = semiregular<_Tp>
181 && requires { typename _Tp::protocol_type; }
182 && __protocol_like<typename _Tp::protocol_type>
183 && requires(const _Tp __a) {
184 { __a.protocol() } -> same_as<typename _Tp::protocol_type>;
185 };
186
187 // Endpoint requirements for extensible implementations.
188 template<typename _Tp>
189 concept __endpoint = __endpoint_base<_Tp>
190 && requires (const _Tp& __a, _Tp& __b, size_t __s)
191 {
192 { __a.data() } -> same_as<const void*>;
193 { __b.data() } -> same_as<void*>;
194 { __b.size() } -> same_as<size_t>;
195 __b.resize(__s);
196 { __a.capacity() } -> same_as<size_t>;
197 };
198
199 // Protocol requirements for non-extensible implementations.
200 template<typename _Tp>
201 concept __protocol_base = __protocol_like<_Tp>
202 && __endpoint_base<typename _Tp::endpoint>
203 && same_as<typename _Tp::endpoint::protocol_type, _Tp>;
204
205 // Protocol requirements for extensible implementations.
206 template<typename _Tp>
207 concept __protocol = __protocol_base<_Tp>
208 && __endpoint<typename _Tp::endpoint>
209 && requires (const _Tp __a) {
210 { __a.family() } -> same_as<int>;
211 { __a.type() } -> same_as<int>;
212 { __a.protocol() } -> same_as<int>;
213 };
214
215 template<typename _Tp>
216 concept __acceptable_protocol = __protocol<_Tp>
217 && requires { typename _Tp::socket; }
218 && move_constructible<typename _Tp::socket>
219 && derived_from<typename _Tp::socket, basic_socket<_Tp>>;
220
221 template<typename _Tp>
222 concept __inet_protocol = __acceptable_protocol<_Tp>
223 && equality_comparable<_Tp> && requires {
224 { _Tp::v4() } -> same_as<_Tp>;
225 { _Tp::v6() } -> same_as<_Tp>;
226 typename _Tp::resolver;
227 }
228 && same_as<typename _Tp::resolver, ip::basic_resolver<_Tp>>;
229
230#else
231 // Check Endpoint requirements for extensible implementations
232 template<typename _Tp, typename = void>
233 struct __is_endpoint : false_type
234 { };
235
236 template<typename _Tp>
237 auto
238 __endpoint_reqs(const _Tp* __a = nullptr, _Tp* __b = nullptr)
239 -> enable_if_t<__and_<
240 is_default_constructible<_Tp>, __is_value_constructible<_Tp>,
241 is_same<decltype(__a->protocol()), typename _Tp::protocol_type>,
242 is_same<decltype(__a->data()), const void*>,
243 is_same<decltype(__b->data()), void*>,
244 is_same<decltype(__a->size()), size_t>,
245 is_same<decltype(__a->capacity()), size_t>
246 >::value,
247 __void_t< typename _Tp::protocol_type::endpoint,
248 decltype(__b->resize(std::declval<size_t>())) >>;
249
250 template<typename _Tp>
251 struct __is_endpoint<_Tp, decltype(__detail::__endpoint_reqs<_Tp>())>
252 : true_type
253 { };
254
255 // Check Protocol requirements for extensible implementations.
256 template<typename _Tp, typename = void>
257 struct __is_protocol
258 : false_type { };
259
260 template<typename _Tp>
261 auto
262 __protocol_reqs(const _Tp* __a = nullptr)
263 -> enable_if_t<__and_<
264 is_copy_constructible<_Tp>, is_copy_assignable<_Tp>,
265 __is_endpoint<typename _Tp::endpoint>,
266 is_same<decltype(__a->family()), int>,
267 is_same<decltype(__a->type()), int>,
268 is_same<decltype(__a->protocol()), int>
269 >::value>;
270
271 template<typename _Tp>
272 struct __is_protocol<_Tp, decltype(__detail::__protocol_reqs<_Tp>())>
273 : true_type
274 { };
275
276 // Check AcceptableProtocol requirements
277 template<typename _Tp, typename = void>
278 struct __is_acceptable_protocol
279 : false_type { };
280
281 template<typename _Tp>
282 struct __is_acceptable_protocol<_Tp, __void_t<typename _Tp::socket>>
283 : __and_<__is_protocol<_Tp>, is_move_constructible<typename _Tp::socket>,
284 is_convertible<typename _Tp::socket*, basic_socket<_Tp>*>>::type
285 { };
286
287 // Check InternetProtocol requirements
288 template<typename _Tp, typename = void>
289 struct __is_inet_protocol
290 : false_type { };
291
292 template<typename _Tp>
293 auto
294 __inet_proto_reqs(const _Tp* __a = nullptr)
295 -> enable_if_t<__and_<
296 __is_acceptable_protocol<_Tp>,
297 is_same<typename _Tp::resolver, ip::basic_resolver<_Tp>>,
298 is_same<decltype(_Tp::v4()), _Tp>,
299 is_same<decltype(_Tp::v6()), _Tp>,
300 is_convertible<decltype(*__a == *__a), bool>,
301 is_convertible<decltype(*__a != *__a), bool>
302 >::value>;
303
304 template<typename _Tp>
305 struct __is_inet_protocol<_Tp, decltype(__inet_proto_reqs<_Tp>())>
306 : true_type { };
307
308 // Variable templates for requirements (with same names as concepts above).
309
310 template<typename _Tp>
311 constexpr bool __endpoint = __is_endpoint<_Tp>::value;
312 template<typename _Tp>
313 constexpr bool __protocol = __is_protocol<_Tp>::value;
314 template<typename _Tp>
315 constexpr bool __acceptable_protocol = __is_acceptable_protocol<_Tp>::value;
316#endif
317} // namespace __detail
318
e5989e71
JW
319 /// @}
320
e5989e71
JW
321} // namespace v1
322} // namespace net
323} // namespace experimental
a70a4be9 324_GLIBCXX_END_NAMESPACE_VERSION
e5989e71
JW
325} // namespace std
326
327#endif // C++14
328
329#endif // _GLIBCXX_EXPERIMENTAL_NET_H