From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1851) id BCCC93994C0F; Wed, 27 May 2020 10:44:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BCCC93994C0F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1590576251; bh=4ihSbDoOIIW8q4MteWqZ5XjQbXGvCbb6RCpTmrFOV8Q=; h=From:To:Subject:Date:From; b=oHB3NOUDKwidreO3e+sr6D3VJeW9LjgVWffmY0aJwROXZF3H8n9J0Ol+flJ80bhG8 ZyBH/+KhvSsO9RwQKIxxkzinr0GIqcPPizid6qYlQ/lHNhv6zdQnZxnnv1/SsCkS4w 0fQ4gNbpHC3y+RsMCecsMnRAUFPRakI8VWTGEK+M= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Martin Liska To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] libstdc++: Better requirements checking in Networking TS X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/users/marxin/heads/marxin-gcc-benchmark-branch X-Git-Oldrev: d9d34449bbde21f6092153828d1b6ee73bd6c4c3 X-Git-Newrev: b780db2ea327f51050d64237e71456b0eacf60e8 Message-Id: <20200527104411.BCCC93994C0F@sourceware.org> Date: Wed, 27 May 2020 10:44:11 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 May 2020 10:44:11 -0000 https://gcc.gnu.org/g:b780db2ea327f51050d64237e71456b0eacf60e8 commit b780db2ea327f51050d64237e71456b0eacf60e8 Author: Jonathan Wakely 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 . (__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 + * include/experimental/bits/net.h (__endpoint, __protocol) + (__acceptable_protocol, __inet_protocol): New concepts. + (__detail::__is_endpoint): Move trait from . + (__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 #include +#if __cplusplus > 201703L +# include +#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 + concept __protocol_like + = copyable<_Tp> && requires { typename _Tp::endpoint; }; + + // Endpoint requirements for non-extensible implementations. + template + concept __endpoint_base = semiregular<_Tp> + && requires { typename _Tp::protocol_type; } + && __protocol_like + && requires(const _Tp __a) { + { __a.protocol() } -> same_as; + }; + + // Endpoint requirements for extensible implementations. + template + concept __endpoint = __endpoint_base<_Tp> + && requires (const _Tp& __a, _Tp& __b, size_t __s) + { + { __a.data() } -> same_as; + { __b.data() } -> same_as; + { __b.size() } -> same_as; + __b.resize(__s); + { __a.capacity() } -> same_as; + }; + + // Protocol requirements for non-extensible implementations. + template + concept __protocol_base = __protocol_like<_Tp> + && __endpoint_base + && same_as; + + // Protocol requirements for extensible implementations. + template + concept __protocol = __protocol_base<_Tp> + && __endpoint + && requires (const _Tp __a) { + { __a.family() } -> same_as; + { __a.type() } -> same_as; + { __a.protocol() } -> same_as; + }; + + template + concept __acceptable_protocol = __protocol<_Tp> + && requires { typename _Tp::socket; } + && move_constructible + && derived_from>; + + template + 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>; + +#else + // Check Endpoint requirements for extensible implementations + template + struct __is_endpoint : false_type + { }; + + template + auto + __endpoint_reqs(const _Tp* __a = nullptr, _Tp* __b = nullptr) + -> enable_if_t<__and_< + is_default_constructible<_Tp>, __is_value_constructible<_Tp>, + is_sameprotocol()), typename _Tp::protocol_type>, + is_samedata()), const void*>, + is_samedata()), void*>, + is_samesize()), size_t>, + is_samecapacity()), size_t> + >::value, + __void_t< typename _Tp::protocol_type::endpoint, + decltype(__b->resize(std::declval())) >>; + + template + struct __is_endpoint<_Tp, decltype(__detail::__endpoint_reqs<_Tp>())> + : true_type + { }; + + // Check Protocol requirements for extensible implementations. + template + struct __is_protocol + : false_type { }; + + template + auto + __protocol_reqs(const _Tp* __a = nullptr) + -> enable_if_t<__and_< + is_copy_constructible<_Tp>, is_copy_assignable<_Tp>, + __is_endpoint, + is_samefamily()), int>, + is_sametype()), int>, + is_sameprotocol()), int> + >::value>; + + template + struct __is_protocol<_Tp, decltype(__detail::__protocol_reqs<_Tp>())> + : true_type + { }; + + // Check AcceptableProtocol requirements + template + struct __is_acceptable_protocol + : false_type { }; + + template + struct __is_acceptable_protocol<_Tp, __void_t> + : __and_<__is_protocol<_Tp>, is_move_constructible, + is_convertible*>>::type + { }; + + // Check InternetProtocol requirements + template + struct __is_inet_protocol + : false_type { }; + + template + auto + __inet_proto_reqs(const _Tp* __a = nullptr) + -> enable_if_t<__and_< + __is_acceptable_protocol<_Tp>, + is_same>, + is_same, + is_same, + is_convertible, + is_convertible + >::value>; + + template + struct __is_inet_protocol<_Tp, decltype(__inet_proto_reqs<_Tp>())> + : true_type { }; + + // Variable templates for requirements (with same names as concepts above). + + template + constexpr bool __endpoint = __is_endpoint<_Tp>::value; + template + constexpr bool __protocol = __is_protocol<_Tp>::value; + template + 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(__e), socket_category()); } - template> - struct __is_endpoint_impl : false_type - { }; - - // Check Endpoint requirements. - template - auto - __endpoint_reqs(const _Tp* __a = 0) - -> enable_if_t<__and_< - is_default_constructible<_Tp>, - __is_value_constructible<_Tp>, - is_same__protocol()), typename _Tp::protocol_type> - >::value, - __void_t< typename _Tp::protocol_type::endpoint >>; - - template - struct __is_endpoint_impl<_Tp, decltype(__endpoint_reqs<_Tp>())> - : true_type - { }; - - template - 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 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 meets the AcceptableProtocol requirements"); + // construct / copy / destroy: explicit