libstdc++: Implement some missing functions for net::ip::network_v6

libstdc++-v3/ChangeLog:

	* include/experimental/internet (network_v6::network): Define.
	(network_v6::hosts): Finish implementing.
	(network_v6::to_string): Do not concatenate std::string to
	arbitrary std::basic_string specialization.
	* testsuite/experimental/net/internet/network/v6/cons.cc: New
	test.
This commit is contained in:
Jonathan Wakely 2024-02-01 10:08:05 +00:00
parent a6286584e5
commit 5b069117e2
2 changed files with 96 additions and 4 deletions

View file

@ -1347,17 +1347,35 @@ namespace ip
constexpr address_v6 address() const noexcept { return _M_addr; }
constexpr int prefix_length() const noexcept { return _M_prefix_len; }
constexpr address_v6 network() const noexcept; // TODO
_GLIBCXX17_CONSTEXPR address_v6
network() const noexcept
{
address_v6::bytes_type __bytes = _M_addr.to_bytes();
int __nbytes = (_M_prefix_len + 7) / 8;
for (int __n = __nbytes; __n < 16; ++__n)
__bytes[__n] = 0;
if (int __zbits = (__nbytes * 8) - _M_prefix_len)
__bytes[__nbytes - 1] &= 0xFF << __zbits;
return address_v6(__bytes, _M_addr.scope_id());
}
address_v6_range
hosts() const noexcept
{
if (is_host())
return { address(), *++address_v6_iterator(address()) };
return {}; // { network(), XXX broadcast() XXX }; // TODO
address_v6::bytes_type __bytes = _M_addr.to_bytes();
int __nbytes = (_M_prefix_len + 7) / 8;
for (int __n = __nbytes; __n < 16; ++__n)
__bytes[__n] = 0xFF;
if (int __bits = (__nbytes * 8) - _M_prefix_len)
__bytes[__nbytes - 1] |= (1 << __bits) - 1;
address_v6 __last(__bytes, _M_addr.scope_id());
return { network(), *++address_v6_iterator(__last) };
}
constexpr network_v6
_GLIBCXX17_CONSTEXPR network_v6
canonical() const noexcept
{ return network_v6{network(), prefix_length()}; }
@ -1379,7 +1397,7 @@ namespace ip
to_string(const _Allocator& __a = _Allocator()) const
{
return address().to_string(__a) + '/'
+ std::to_string(prefix_length());
+ std::to_string(prefix_length()).c_str();
}
private:

View file

@ -0,0 +1,74 @@
// { dg-do run { target c++14 } }
// { dg-require-effective-target net_ts_ip }
// { dg-add-options net_ts }
#include <experimental/internet>
#include <stdexcept>
#include <testsuite_hooks.h>
using std::experimental::net::ip::network_v6;
using std::experimental::net::ip::address_v6;
constexpr void
test01()
{
network_v6 n0;
VERIFY( n0.address().is_unspecified() );
VERIFY( n0.prefix_length() == 0 );
}
constexpr void
test02()
{
address_v6 a0;
network_v6 n0{ a0, 0 };
VERIFY( n0.address() == a0 );
VERIFY( n0.prefix_length() == 0 );
address_v6 a1{ address_v6::bytes_type{ 1, 2, 4, 8, 16, 32, 64, 128,
3, 7, 47, 71, 83, 165, 199, 255 } };
network_v6 n1{ a1, 99};
VERIFY( n1.address() == a1 );
VERIFY( n1.prefix_length() == 99 );
}
void
test02_errors()
{
address_v6 a0;
try
{
network_v6{a0, -1};
VERIFY(false);
}
catch(const std::out_of_range&)
{
}
try
{
network_v6{a0, 129};
VERIFY(false);
}
catch(const std::out_of_range&)
{
}
}
constexpr bool
test_constexpr()
{
test01();
test02();
return true;
}
int
main()
{
test01();
test02();
test02_errors();
static_assert( test_constexpr(), "valid in constant expressions" );
}