aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-02-01 10:08:05 +0000
committerJonathan Wakely <jwakely@redhat.com>2024-06-11 13:35:08 +0100
commit5f885bd5f435ea05ad18d28860b3f22c7705d967 (patch)
tree4d0b409cef7030bc2f79d144446120b648f40c48
parent3494bc7b03997f96e84e84f6904917854466d5ea (diff)
downloadgcc-5f885bd5f435ea05ad18d28860b3f22c7705d967.zip
gcc-5f885bd5f435ea05ad18d28860b3f22c7705d967.tar.gz
gcc-5f885bd5f435ea05ad18d28860b3f22c7705d967.tar.bz2
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. (cherry picked from commit 5b069117e261ae0b438aee0cdff8707827810adf)
-rw-r--r--libstdc++-v3/include/experimental/internet26
-rw-r--r--libstdc++-v3/testsuite/experimental/net/internet/network/v6/cons.cc74
2 files changed, 96 insertions, 4 deletions
diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet
index 5b05b0f..c57b48b 100644
--- a/libstdc++-v3/include/experimental/internet
+++ b/libstdc++-v3/include/experimental/internet
@@ -1310,17 +1310,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()}; }
@@ -1342,7 +1360,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:
diff --git a/libstdc++-v3/testsuite/experimental/net/internet/network/v6/cons.cc b/libstdc++-v3/testsuite/experimental/net/internet/network/v6/cons.cc
new file mode 100644
index 0000000..9b4b791
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/net/internet/network/v6/cons.cc
@@ -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" );
+}