| // { dg-do run { target c++14 } } |
| // { dg-require-effective-target net_ts_ip } |
| |
| #include <experimental/internet> |
| #include <testsuite_common_types.h> |
| #include <testsuite_hooks.h> |
| |
| using namespace std; |
| |
| template<typename C, typename T, typename P> |
| void check_gettable_sockopt(P p, C c = C()) |
| { |
| static_assert( is_same<decltype(declval<const C&>().level(p)), int>(), "" ); |
| static_assert( noexcept(declval<const C&>().level(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<const C&>().name(p)), int>(), "" ); |
| static_assert( noexcept(declval<const C&>().name(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<C&>().data(p)), void*>(), "" ); |
| static_assert( noexcept(declval<C&>().data(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<const C&>().size(p)), size_t>(), "" ); |
| static_assert( noexcept(declval<const C&>().size(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<C&>().resize(p, 0)), void>(), "" ); |
| static_assert( ! noexcept(declval<C&>().resize(p, 0)), "" ); |
| |
| VERIFY(c.size(p) == sizeof(T)); |
| } |
| |
| template<typename C, typename T, typename P> |
| void check_settable_sockopt(P p, C c = C()) |
| { |
| static_assert( is_same<decltype(declval<const C&>().level(p)), int>(), "" ); |
| static_assert( noexcept(declval<const C&>().level(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<const C&>().name(p)), int>(), "" ); |
| static_assert( noexcept(declval<const C&>().name(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<const C&>().data(p)), const void*>(), "" ); |
| static_assert( noexcept(declval<const C&>().data(p)), "" ); |
| |
| static_assert( is_same<decltype(declval<C&>().size(p)), size_t>(), "" ); |
| static_assert( noexcept(declval<C&>().size(p)), "" ); |
| |
| VERIFY(c.size(p) == sizeof(T)); |
| } |
| |
| template<typename C, typename T = int> |
| void check_boolean_sockopt() |
| { |
| namespace ip = std::experimental::net::ip; |
| #if __has_include(<netinet/in.h>) |
| check_gettable_sockopt<C, T>(ip::tcp::v4()); |
| check_settable_sockopt<C, T>(ip::tcp::v4()); |
| #endif |
| |
| static_assert( is_destructible<C>(), "" ); |
| static_assert( is_nothrow_default_constructible<C>(), "" ); |
| static_assert( is_nothrow_copy_constructible<C>(), "" ); |
| static_assert( is_nothrow_copy_assignable<C>(), "" ); |
| |
| static_assert( is_nothrow_constructible<C, bool>(), "" ); |
| static_assert( is_nothrow_assignable<C&, bool>(), "" ); |
| |
| static_assert( is_same<decltype(declval<const C&>().value()), bool>(), "" ); |
| static_assert( noexcept(declval<const C&>().value()), "" ); |
| |
| static_assert( is_same<decltype(static_cast<bool>(declval<const C&>())), bool>(), "" ); |
| static_assert( noexcept(static_cast<bool>(declval<const C&>())), "" ); |
| |
| static_assert( is_same<decltype(!declval<const C&>()), bool>(), "" ); |
| static_assert( noexcept(!declval<const C&>()), "" ); |
| } |
| |
| template<typename C, typename T = int> |
| void check_integer_sockopt() |
| { |
| namespace ip = std::experimental::net::ip; |
| #if __has_include(<netinet/in.h>) |
| check_gettable_sockopt<C, T>(ip::tcp::v4()); |
| check_settable_sockopt<C, T>(ip::tcp::v4()); |
| #endif |
| |
| static_assert( is_destructible<C>(), "" ); |
| static_assert( is_nothrow_default_constructible<C>(), "" ); |
| static_assert( is_nothrow_copy_constructible<C>(), "" ); |
| static_assert( is_nothrow_copy_assignable<C>(), "" ); |
| |
| static_assert( is_nothrow_constructible<C, int>(), "" ); |
| static_assert( is_nothrow_assignable<C&, int>(), "" ); |
| |
| static_assert( is_same<decltype(declval<const C&>().value()), int>(), "" ); |
| static_assert( noexcept(declval<const C&>().value()), "" ); |
| } |
| |
| template<typename C> |
| void check_mcast_sockopt(C& c) |
| { |
| namespace ip = std::experimental::net::ip; |
| static_assert( is_destructible<C>(), "" ); |
| static_assert( is_copy_constructible<C>(), "" ); |
| static_assert( is_copy_assignable<C>(), "" ); |
| |
| #if __has_include(<netinet/in.h>) |
| check_settable_sockopt<C, ipv6_mreq>(ip::tcp::v6(), c); |
| check_settable_sockopt<C, ip_mreq>(ip::tcp::v4(), c); |
| #endif |
| |
| static_assert( is_nothrow_constructible<C, const ip::address&>(), "" ); |
| static_assert( ! is_convertible<const ip::address&, C>(), "explicit" ); |
| static_assert( is_nothrow_constructible<C, const ip::address_v4&>(), "" ); |
| static_assert( ! is_convertible<const ip::address_v4&, C>(), "explicit" ); |
| static_assert( is_nothrow_constructible<C, const ip::address_v4&, const ip::address_v4&>(), "" ); |
| static_assert( is_nothrow_constructible<C, const ip::address_v6&>(), "" ); |
| static_assert( ! is_convertible<const ip::address_v6&, C>(), "explicit" ); |
| static_assert( is_nothrow_constructible<C, const ip::address_v6&, unsigned>(), "" ); |
| } |
| |
| void test_option_types() |
| { |
| namespace ip = std::experimental::net::ip; |
| |
| #if __has_include(<netinet/in.h>) |
| #if __has_include(<netinet/tcp.h>) |
| check_boolean_sockopt<ip::tcp::no_delay>(); |
| #endif |
| |
| check_boolean_sockopt<ip::v6_only>(); |
| |
| check_integer_sockopt<ip::unicast::hops>(); |
| |
| ip::multicast::join_group join(ip::address_v4::any()); |
| check_mcast_sockopt(join); |
| |
| ip::multicast::leave_group leave(ip::address_v4::any()); |
| check_mcast_sockopt(leave); |
| |
| using outbound_if = ip::multicast::outbound_interface; |
| outbound_if oif(ip::address_v4::any()); |
| check_settable_sockopt<outbound_if, unsigned>(ip::tcp::v6(), oif); |
| check_settable_sockopt<outbound_if, ::in_addr>(ip::tcp::v4(), oif); |
| static_assert( is_destructible<outbound_if>(), "" ); |
| static_assert( ! is_default_constructible<outbound_if>(), "" ); |
| static_assert( is_nothrow_copy_constructible<outbound_if>(), "" ); |
| static_assert( is_nothrow_copy_assignable<outbound_if>(), "" ); |
| static_assert( is_nothrow_constructible<outbound_if, const ip::address_v4&>(), "" ); |
| static_assert( ! is_convertible<const ip::address_v4&, outbound_if>(), "explicit" ); |
| static_assert( is_nothrow_constructible<outbound_if, unsigned>(), "" ); |
| static_assert( ! is_convertible<unsigned, outbound_if>(), "explicit" ); |
| |
| check_integer_sockopt<ip::multicast::hops>(); |
| |
| check_boolean_sockopt<ip::multicast::enable_loopback>(); |
| #endif |
| } |
| |
| int main() |
| { |
| test_option_types(); |
| } |