public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] libstdc++: Better requirements checking in Networking TS
@ 2020-05-27 10:44 Martin Liska
0 siblings, 0 replies; only message in thread
From: Martin Liska @ 2020-05-27 10:44 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:b780db2ea327f51050d64237e71456b0eacf60e8
commit b780db2ea327f51050d64237e71456b0eacf60e8
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu May 21 00:59:55 2020 +0100
libstdc++: Better requirements checking in Networking TS
Define concepts and traits for checking type requirements.
* include/experimental/bits/net.h (__endpoint, __protocol)
(__acceptable_protocol, __inet_protocol): New concepts.
(__detail::__is_endpoint): Move trait from <experimental/socket>.
(__is_protocol, __is_acceptable_protocol, __is_inet_protocol): New
traits.
(__endpoint, __protocol, __acceptable_protocol): New variable
templates.
* include/experimental/socket (__is_endpoint): Move to net.h header.
(basic_socket, basic_socket_acceptor): Check requirements.
Diff:
---
libstdc++-v3/ChangeLog | 10 ++
libstdc++-v3/include/experimental/bits/net.h | 152 +++++++++++++++++++++++++++
libstdc++-v3/include/experimental/socket | 34 ++----
3 files changed, 169 insertions(+), 27 deletions(-)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index dec84f03da6..975de44434b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,15 @@
2020-05-21 Jonathan Wakely <jwakely@redhat.com>
+ * include/experimental/bits/net.h (__endpoint, __protocol)
+ (__acceptable_protocol, __inet_protocol): New concepts.
+ (__detail::__is_endpoint): Move trait from <experimental/socket>.
+ (__is_protocol, __is_acceptable_protocol, __is_inet_protocol): New
+ traits.
+ (__endpoint, __protocol, __acceptable_protocol): New variable
+ templates.
+ * include/experimental/socket (__is_endpoint): Move to net.h header.
+ (basic_socket, basic_socket_acceptor): Check requirements.
+
* include/experimental/executor (use_future_t::use_future_t()): Fix
incorrect noexcept-specifier.
* include/experimental/internet (basic_resolver_results): Adjust
diff --git a/libstdc++-v3/include/experimental/bits/net.h b/libstdc++-v3/include/experimental/bits/net.h
index f69ef91c31e..cf7914d0acb 100644
--- a/libstdc++-v3/include/experimental/bits/net.h
+++ b/libstdc++-v3/include/experimental/bits/net.h
@@ -38,6 +38,10 @@
#include <system_error>
#include <experimental/netfwd>
+#if __cplusplus > 201703L
+# include <concepts>
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -164,6 +168,154 @@ inline namespace v1
{ return _Derived::_S_name; }
};
+namespace __detail
+{
+#if __cpp_lib_concepts
+ template<typename _Tp>
+ concept __protocol_like
+ = copyable<_Tp> && requires { typename _Tp::endpoint; };
+
+ // Endpoint requirements for non-extensible implementations.
+ template<typename _Tp>
+ concept __endpoint_base = semiregular<_Tp>
+ && requires { typename _Tp::protocol_type; }
+ && __protocol_like<typename _Tp::protocol_type>
+ && requires(const _Tp __a) {
+ { __a.protocol() } -> same_as<typename _Tp::protocol_type>;
+ };
+
+ // Endpoint requirements for extensible implementations.
+ template<typename _Tp>
+ concept __endpoint = __endpoint_base<_Tp>
+ && requires (const _Tp& __a, _Tp& __b, size_t __s)
+ {
+ { __a.data() } -> same_as<const void*>;
+ { __b.data() } -> same_as<void*>;
+ { __b.size() } -> same_as<size_t>;
+ __b.resize(__s);
+ { __a.capacity() } -> same_as<size_t>;
+ };
+
+ // Protocol requirements for non-extensible implementations.
+ template<typename _Tp>
+ concept __protocol_base = __protocol_like<_Tp>
+ && __endpoint_base<typename _Tp::endpoint>
+ && same_as<typename _Tp::endpoint::protocol_type, _Tp>;
+
+ // Protocol requirements for extensible implementations.
+ template<typename _Tp>
+ concept __protocol = __protocol_base<_Tp>
+ && __endpoint<typename _Tp::endpoint>
+ && requires (const _Tp __a) {
+ { __a.family() } -> same_as<int>;
+ { __a.type() } -> same_as<int>;
+ { __a.protocol() } -> same_as<int>;
+ };
+
+ template<typename _Tp>
+ concept __acceptable_protocol = __protocol<_Tp>
+ && requires { typename _Tp::socket; }
+ && move_constructible<typename _Tp::socket>
+ && derived_from<typename _Tp::socket, basic_socket<_Tp>>;
+
+ template<typename _Tp>
+ concept __inet_protocol = __acceptable_protocol<_Tp>
+ && equality_comparable<_Tp> && requires {
+ { _Tp::v4() } -> same_as<_Tp>;
+ { _Tp::v6() } -> same_as<_Tp>;
+ typename _Tp::resolver;
+ }
+ && same_as<typename _Tp::resolver, ip::basic_resolver<_Tp>>;
+
+#else
+ // Check Endpoint requirements for extensible implementations
+ template<typename _Tp, typename = void>
+ struct __is_endpoint : false_type
+ { };
+
+ template<typename _Tp>
+ auto
+ __endpoint_reqs(const _Tp* __a = nullptr, _Tp* __b = nullptr)
+ -> enable_if_t<__and_<
+ is_default_constructible<_Tp>, __is_value_constructible<_Tp>,
+ is_same<decltype(__a->protocol()), typename _Tp::protocol_type>,
+ is_same<decltype(__a->data()), const void*>,
+ is_same<decltype(__b->data()), void*>,
+ is_same<decltype(__a->size()), size_t>,
+ is_same<decltype(__a->capacity()), size_t>
+ >::value,
+ __void_t< typename _Tp::protocol_type::endpoint,
+ decltype(__b->resize(std::declval<size_t>())) >>;
+
+ template<typename _Tp>
+ struct __is_endpoint<_Tp, decltype(__detail::__endpoint_reqs<_Tp>())>
+ : true_type
+ { };
+
+ // Check Protocol requirements for extensible implementations.
+ template<typename _Tp, typename = void>
+ struct __is_protocol
+ : false_type { };
+
+ template<typename _Tp>
+ auto
+ __protocol_reqs(const _Tp* __a = nullptr)
+ -> enable_if_t<__and_<
+ is_copy_constructible<_Tp>, is_copy_assignable<_Tp>,
+ __is_endpoint<typename _Tp::endpoint>,
+ is_same<decltype(__a->family()), int>,
+ is_same<decltype(__a->type()), int>,
+ is_same<decltype(__a->protocol()), int>
+ >::value>;
+
+ template<typename _Tp>
+ struct __is_protocol<_Tp, decltype(__detail::__protocol_reqs<_Tp>())>
+ : true_type
+ { };
+
+ // Check AcceptableProtocol requirements
+ template<typename _Tp, typename = void>
+ struct __is_acceptable_protocol
+ : false_type { };
+
+ template<typename _Tp>
+ struct __is_acceptable_protocol<_Tp, __void_t<typename _Tp::socket>>
+ : __and_<__is_protocol<_Tp>, is_move_constructible<typename _Tp::socket>,
+ is_convertible<typename _Tp::socket*, basic_socket<_Tp>*>>::type
+ { };
+
+ // Check InternetProtocol requirements
+ template<typename _Tp, typename = void>
+ struct __is_inet_protocol
+ : false_type { };
+
+ template<typename _Tp>
+ auto
+ __inet_proto_reqs(const _Tp* __a = nullptr)
+ -> enable_if_t<__and_<
+ __is_acceptable_protocol<_Tp>,
+ is_same<typename _Tp::resolver, ip::basic_resolver<_Tp>>,
+ is_same<decltype(_Tp::v4()), _Tp>,
+ is_same<decltype(_Tp::v6()), _Tp>,
+ is_convertible<decltype(*__a == *__a), bool>,
+ is_convertible<decltype(*__a != *__a), bool>
+ >::value>;
+
+ template<typename _Tp>
+ struct __is_inet_protocol<_Tp, decltype(__inet_proto_reqs<_Tp>())>
+ : true_type { };
+
+ // Variable templates for requirements (with same names as concepts above).
+
+ template<typename _Tp>
+ constexpr bool __endpoint = __is_endpoint<_Tp>::value;
+ template<typename _Tp>
+ constexpr bool __protocol = __is_protocol<_Tp>::value;
+ template<typename _Tp>
+ constexpr bool __acceptable_protocol = __is_acceptable_protocol<_Tp>::value;
+#endif
+} // namespace __detail
+
/// @}
} // namespace v1
diff --git a/libstdc++-v3/include/experimental/socket b/libstdc++-v3/include/experimental/socket
index 80fb21da95c..84d23ebe37c 100644
--- a/libstdc++-v3/include/experimental/socket
+++ b/libstdc++-v3/include/experimental/socket
@@ -122,33 +122,7 @@ inline namespace v1
make_error_condition(socket_errc __e) noexcept
{ return error_condition(static_cast<int>(__e), socket_category()); }
- template<typename _Tp, typename = __void_t<>>
- struct __is_endpoint_impl : false_type
- { };
-
- // Check Endpoint requirements.
- template<typename _Tp>
- auto
- __endpoint_reqs(const _Tp* __a = 0)
- -> enable_if_t<__and_<
- is_default_constructible<_Tp>,
- __is_value_constructible<_Tp>,
- is_same<decltype(__a->__protocol()), typename _Tp::protocol_type>
- >::value,
- __void_t< typename _Tp::protocol_type::endpoint >>;
-
- template<typename _Tp>
- struct __is_endpoint_impl<_Tp, decltype(__endpoint_reqs<_Tp>())>
- : true_type
- { };
-
- template<typename _Tp>
- struct __is_endpoint : __is_endpoint_impl<_Tp>
- { };
-
- // TODO Endpoint reqs for extensible implementations
- // TODO _Protocol reqs
- // TODO AcceptableProtocol reqs
+
// TODO GettableSocket reqs
// TODO SettableSocket reqs
// TODO BooleanSocketOption reqs
@@ -713,6 +687,9 @@ inline namespace v1
using protocol_type = _Protocol;
using endpoint_type = typename protocol_type::endpoint;
+ static_assert(__detail::__protocol<protocol_type>,
+ "protocol_type meets the Protocol requirements");
+
// basic_socket operations:
executor_type get_executor() noexcept { return __base::get_executor(); }
@@ -1853,6 +1830,9 @@ inline namespace v1
using endpoint_type = typename protocol_type::endpoint;
using socket_type = typename protocol_type::socket;
+ static_assert(__detail::__acceptable_protocol<protocol_type>,
+ "protocol_type meets the AcceptableProtocol requirements");
+
// construct / copy / destroy:
explicit
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-05-27 10:44 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-27 10:44 [gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] libstdc++: Better requirements checking in Networking TS Martin Liska
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).