This is an automated email from the ASF dual-hosted git repository.

bneradt pushed a commit to branch github-build
in repository https://gitbox.apache.org/repos/asf/trafficserver-libswoc.git

commit 3b300250e02de64b2981e75a00aaf874366813b3
Author: Alan M. Carroll <[email protected]>
AuthorDate: Sun Jun 4 10:02:21 2023 -0500

    IPSpace: update to use struct instead of tuple.
---
 code/include/swoc/IPRange.h         | 335 ++++++++++++++++++++++++++----------
 code/include/swoc/Lexicon.h         |   2 +-
 unit_tests/ex_Lexicon.cc            |   4 +-
 unit_tests/ex_ipspace_properties.cc |   4 +-
 unit_tests/test_ip.cc               | 110 ++++++------
 5 files changed, 301 insertions(+), 154 deletions(-)

diff --git a/code/include/swoc/IPRange.h b/code/include/swoc/IPRange.h
index aa93d17..cf9b66c 100644
--- a/code/include/swoc/IPRange.h
+++ b/code/include/swoc/IPRange.h
@@ -8,22 +8,19 @@
 
 #include <string_view>
 #include <variant> // for std::monostate
+#include <tuple>
 
 #include <swoc/DiscreteRange.h>
 #include <swoc/IPAddr.h>
 
 namespace swoc { inline namespace SWOC_VERSION_NS {
 
-using ::std::string_view;
+using std::string_view;
 
 class IP4Net;
 class IP6Net;
 class IPNet;
 
-namespace detail {
-extern void *const pseudo_nullptr;
-}
-
 /** An inclusive range of IPv4 addresses.
  */
 class IP4Range : public DiscreteRange<IP4Addr> {
@@ -335,6 +332,7 @@ public:
    * @param max Maximum range value.
    */
   IPRange(IP4Addr const &min, IP4Addr const &max);
+
   /** Construct an inclusive range.
    *
    * @param min Minimum range value.
@@ -346,8 +344,8 @@ public:
    *
    * @param addr Address of range.
    */
-
   IPRange(IPAddr const& addr) : IPRange(addr, addr) {}
+
   /** Construct a singleton range.
    *
    * @param addr Address of range.
@@ -366,7 +364,6 @@ public:
   /// Construct from an IPv6 @a range.
   IPRange(IP6Range const &range);
 
-
   /** Construct from a string format.
    *
    * @param text Text form of range.
@@ -384,16 +381,10 @@ public:
   bool operator!=(self_type const& that) const;
 
   /// @return @c true if this is an IPv4 range, @c false if not.
-  bool
-  is_ip4() const {
-    return AF_INET == _family;
-  }
+  bool is_ip4() const;
 
   /// @return @c true if this is an IPv6 range, @c false if not.
-  bool
-  is_ip6() const {
-    return AF_INET6 == _family;
-  }
+  bool is_ip6() const;
 
   /** Check if @a this range is the IP address @a family.
    *
@@ -421,6 +412,9 @@ public:
   /// @return @c true if there are no addresses in the range.
   bool empty() const;
 
+  /// Make the range empty / invalid.
+  self_type & clear();
+
   /// @return The IPv4 range.
   IP4Range const & ip4() const { return _range._ip4; }
 
@@ -438,6 +432,7 @@ public:
    */
   IPMask network_mask() const;
 
+  /// Container for remaining range for network generation.
   class NetSource;
 
   /** Generate a list of networks covering @a this range.
@@ -473,6 +468,7 @@ protected:
     IP4Range _ip4;       ///< IPv4 range.
     IP6Range _ip6;       ///< IPv6 range.
   } _range{std::monostate{}};
+
   /// Family of @a _range.
   sa_family_t _family{AF_UNSPEC};
 };
@@ -533,6 +529,7 @@ protected:
     IP4Range::NetSource _ip4; ///< IPv4 addresses.
     IP6Range::NetSource _ip6; ///< IPv6 addresses.
   };
+
   sa_family_t _family = AF_UNSPEC; ///< Mark for union content.
 };
 
@@ -730,21 +727,20 @@ public:
   /// @return A range that exactly covers the network.
   IPRange as_range() const;
 
+  /// @return @c true if network is IPv4.
   bool is_ip4() const { return _addr.is_ip4(); }
 
+  /// @return @c true if network is IPv6.
   bool is_ip6() const { return _addr.is_ip6(); }
 
+  /// Address family of network.
   sa_family_t family() const { return _addr.family(); }
 
-  IP4Net
-  ip4() const {
-    return IP4Net{_addr.ip4(), _mask};
-  }
+  /// @return The network as explicitly IPv4.
+  IP4Net ip4() const;
 
-  IP6Net
-  ip6() const {
-    return IP6Net{_addr.ip6(), _mask};
-  }
+  /// @return The network as explicitly IPv6.
+  IP6Net ip6() const;
 
   /** Assign an @a addr and @a mask to @a this.
    *
@@ -755,11 +751,7 @@ public:
   self_type &assign(IPAddr const &addr, IPMask const &mask);
 
   /// Reset network to invalid state.
-  self_type &
-  clear() {
-    _mask.clear();
-    return *this;
-  }
+  self_type & clear();
 
   /// Equality.
   bool operator==(self_type const &that) const;
@@ -773,6 +765,105 @@ protected:
 };
 
 // --------------------------------------------------------------------------
+namespace detail {
+/** Value type for @c IPSpace.
+ *
+ * @tparam PAYLOAD User data type to be stored.
+ *
+ * @internal Exported because inner classes in template classes cannot be used 
in partial
+ * specialization which is required for tuple support. This should be removed 
next API incompatible
+ * change release because tuple access is being deprecated.
+ *
+ * @note The @c assign methods are used to update iterators.
+ *
+ * @see IPSpace
+ */
+template < typename PAYLOAD > struct ip_space_value_type {
+  using self_type = ip_space_value_type;
+
+  swoc::IPRange _range; ///< Address range.
+  PAYLOAD * _payload = nullptr; ///< Payload for @a _range.
+
+  /// @return The address range.
+  swoc::IPRange const & range() const { return _range; }
+  /// @return A reference to the payload (user content).
+  PAYLOAD const & payload() const { return *_payload; }
+  /// @return A reference to the payload (user content).
+  PAYLOAD & payload() { return *_payload; }
+
+  /// Reset to default constructed state.
+  self_type & clear();
+
+  /** Update the internal state.
+   *
+   * @param r Range.
+   * @param payload Payload.
+   * @return @a this.
+   */
+  self_type & assign(swoc::IP4Range const& r, PAYLOAD & payload);
+
+  /** Update the internal state.
+   *
+   * @param r Range.
+   * @param payload Payload.
+   * @return @a this.
+   */
+  self_type & assign(swoc::IP6Range const& r, PAYLOAD & payload);
+
+  /** Update from another instance.
+   *
+   * @param that Other instance.
+   * @return @a this.
+   */
+  self_type & assign(self_type const& that);
+
+  /// Support assignemnt to @c std::tie.
+  operator std::tuple<swoc::IPRange &, PAYLOAD &> () { return { _range, 
*_payload }; }
+
+  /// Equality against an equivalent tuple.
+  bool operator == (std::tuple<swoc::IPRange, PAYLOAD> const& t) const;
+};
+
+template <typename PAYLOAD>
+auto
+ip_space_value_type<PAYLOAD>::clear() -> self_type & {
+  _range.clear();
+  _payload = nullptr;
+  return *this;
+}
+
+template <typename PAYLOAD>
+auto
+ip_space_value_type<PAYLOAD>::assign(IP4Range const &r, PAYLOAD &payload) -> 
self_type &{
+  _range = r;
+  _payload = &payload;
+  return *this;
+}
+
+template <typename PAYLOAD>
+auto
+ip_space_value_type<PAYLOAD>::assign(IP6Range const &r, PAYLOAD &payload) -> 
self_type & {
+  _range = r;
+  _payload = &payload;
+  return *this;
+}
+
+template <typename PAYLOAD>
+auto
+ip_space_value_type<PAYLOAD>::assign(ip_space_value_type::self_type const 
&that) -> self_type & {
+  _range = that._range;
+  _payload = that._payload;
+  return *this;
+}
+
+template <typename PAYLOAD>
+bool
+ip_space_value_type<PAYLOAD>::operator==(std::tuple<swoc::IPRange, PAYLOAD> 
const &t) const {
+  return _range == std::get<0>(t) && std::get<1>(t) == *_payload;
+}
+
+} // namespace detail
+
 /** Coloring of IP address space.
  *
  * @tparam PAYLOAD The color class.
@@ -793,7 +884,8 @@ template <typename PAYLOAD> class IPSpace {
 
 public:
   using payload_t  = PAYLOAD; ///< Export payload type.
-  using value_type = std::tuple<IPRange const, PAYLOAD &>;
+  /// Iterator value, a range and payload.
+  using value_type = detail::ip_space_value_type<PAYLOAD>;
 
   /// Construct an empty space.
   IPSpace() = default;
@@ -850,8 +942,7 @@ public:
     self_type & blend(IP4Range const &range, U const &color, F &&blender);
 
   template <typename F, typename U = PAYLOAD>
-    self_type &
-    blend(IP6Range const &range, U const &color, F &&blender);
+    self_type & blend(IP6Range const &range, U const &color, F &&blender);
 
   /// @return The number of distinct ranges.
   size_t count() const;
@@ -898,7 +989,7 @@ public:
     friend class IPSpace;
 
   public:
-    using value_type = std::tuple<IPRange const, PAYLOAD const &>; /// Import 
for API compliance.
+    using value_type = IPSpace::value_type const; /// Import for API 
compliance.
     // STL algorithm compliance.
     using iterator_category = std::bidirectional_iterator_tag;
     using pointer           = value_type *;
@@ -936,31 +1027,11 @@ public:
 
     /// Dereference.
     /// @return A reference to the referent.
-    value_type operator*() const;
+    value_type & operator*() const;
 
     /// Dereference.
     /// @return A pointer to the referent.
-    value_type const *operator->() const;
-
-    /** The range for the iterator.
-     *
-     * @return Iterator range.
-     *
-     * @note If the iterator is not valid the returned range will be empty.
-     */
-    IPRange const& range() const;
-
-    /** The payload for the iterator.
-     *
-     * @return The payload.
-     *
-     * @note This yields undetermined results for invalid iterators. Always 
check for validity befure
-     * using this method.
-     *
-     * @note It is not possible to retrieve a modifiable payload because that 
can break the internal
-     * invariant that adjcent ranges always have different payloads.
-     */
-    PAYLOAD const& payload() const;
+    value_type * operator->() const;
 
     /// Equality
     bool operator==(self_type const &that) const;
@@ -977,7 +1048,7 @@ public:
     typename IP4Space::iterator _iter_4; ///< IPv4 sub-space iterator.
     typename IP6Space::iterator _iter_6; ///< IPv6 sub-space iterator.
     /// Current value.
-    value_type _value{IPRange{}, *static_cast<PAYLOAD 
*>(detail::pseudo_nullptr)};
+    IPSpace::value_type _value;
 
     /** Internal constructor.
      *
@@ -1008,7 +1079,7 @@ public:
     iterator(const_iterator const& that) : const_iterator(that) {}
   public:
     /// Value type of iteration.
-    using value_type = std::tuple<IPRange const, PAYLOAD &>;
+    using value_type = IPSpace::value_type;
     using pointer    = value_type *;
     using reference  = value_type &;
 
@@ -1034,30 +1105,20 @@ public:
     /// Post-increment.
     /// Move to the next element in the list.
     /// @return The iterator value before the increment.
-    self_type
-    operator++(int) {
-      self_type zret{*this};
-      ++*this;
-      return zret;
-    }
+    self_type operator++(int);
 
     /// Post-decrement.
     /// Move to the previous element in the list.
     /// @return The iterator value before the decrement.
-    self_type
-    operator--(int) {
-      self_type zret{*this};
-      --*this;
-      return zret;
-    }
+    self_type operator--(int);
 
     /// Dereference.
     /// @return A reference to the referent.
-    value_type operator*() const;
+    reference operator*() const;
 
     /// Dereference.
     /// @return A pointer to the referent.
-    value_type const *operator->() const;
+    pointer operator->() const;
 
   };
 
@@ -1376,9 +1437,9 @@ template <typename PAYLOAD>
 IPSpace<PAYLOAD>::const_iterator::const_iterator(typename IP4Space::iterator 
const &iter4, typename IP6Space::iterator const &iter6)
 : _iter_4(iter4), _iter_6(iter6) {
   if (_iter_4.has_next()) {
-    new (&_value) value_type{_iter_4->range(), _iter_4->payload()};
+    _value.assign(_iter_4->range(), _iter_4->payload());
   } else if (_iter_6.has_next()) {
-    new (&_value) value_type{_iter_6->range(), _iter_6->payload()};
+    _value.assign(_iter_6->range(), _iter_6->payload());
   }
 }
 
@@ -1387,7 +1448,7 @@ auto
 IPSpace<PAYLOAD>::const_iterator::operator=(self_type const &that) -> 
self_type & {
   _iter_4 = that._iter_4;
   _iter_6 = that._iter_6;
-  new (&_value) value_type{that._value};
+  _value.assign(that._value);
   return *this;
 }
 
@@ -1399,18 +1460,18 @@ IPSpace<PAYLOAD>::const_iterator::operator++() -> 
self_type & {
     ++_iter_4;
     incr_p = true;
     if (_iter_4.has_next()) {
-      new (&_value) value_type{_iter_4->range(), _iter_4->payload()};
+      _value.assign(_iter_4->range(), _iter_4->payload());
       return *this;
     }
   }
 
   if (_iter_6.has_next()) {
     if (incr_p || (++_iter_6).has_next()) {
-      new (&_value) value_type{_iter_6->range(), _iter_6->payload()};
+      _value.assign(_iter_6->range(), _iter_6->payload());
       return *this;
     }
   }
-  new (&_value) value_type{IPRange{}, *static_cast<PAYLOAD 
*>(detail::pseudo_nullptr)};
+  _value.clear();
   return *this;
 }
 
@@ -1427,15 +1488,15 @@ auto
 IPSpace<PAYLOAD>::const_iterator::operator--() -> self_type & {
   if (_iter_6.has_prev()) {
     --_iter_6;
-    new (&_value) value_type{_iter_6->range(), _iter_6->payload()};
+    _value.assign(_iter_6->range(), _iter_6->payload());
     return *this;
   }
   if (_iter_4.has_prev()) {
     --_iter_4;
-    new (&_value) value_type{_iter_4->range(), _iter_4->payload()};
+    _value.assign(_iter_4->range(), _iter_4->payload());
     return *this;
   }
-  new (&_value) value_type{IPRange{}, *static_cast<PAYLOAD 
*>(detail::pseudo_nullptr)};
+  _value.clear();
   return *this;
 }
 
@@ -1449,7 +1510,7 @@ IPSpace<PAYLOAD>::const_iterator::operator--(int) -> 
self_type {
 
 template <typename PAYLOAD>
 auto
-IPSpace<PAYLOAD>::const_iterator::operator*() const -> value_type {
+IPSpace<PAYLOAD>::const_iterator::operator*() const -> value_type & {
   return _value;
 }
 
@@ -1459,14 +1520,6 @@ IPSpace<PAYLOAD>::const_iterator::operator->() const -> 
value_type const * {
   return &_value;
 }
 
-template <typename PAYLOAD>
-IPRange const &
-IPSpace<PAYLOAD>::const_iterator::range() const { return std::get<0>(_value); }
-
-template <typename PAYLOAD>
-PAYLOAD const &
-IPSpace<PAYLOAD>::const_iterator::payload() const { return 
std::get<1>(_value); }
-
 /* Bit of subtlety with equality - although it seems that if @a _iter_4 is 
valid, it doesn't matter
  * where @a _iter6 is (because it is really the iterator location that's being 
checked), it's
  * necessary to do the @a _iter_4 validity on both iterators to avoid the case 
of a false positive
@@ -1496,14 +1549,14 @@ IPSpace<PAYLOAD>::iterator::operator=(self_type const 
&that) -> self_type & {
 
 template <typename PAYLOAD>
 auto
-IPSpace<PAYLOAD>::iterator::operator->() const -> value_type const * {
-  return static_cast<value_type *>(&super_type::_value);
+IPSpace<PAYLOAD>::iterator::operator->() const -> pointer {
+  return & const_cast<self_type*>(this)->_value;
 }
 
 template <typename PAYLOAD>
 auto
-IPSpace<PAYLOAD>::iterator::operator*() const -> value_type {
-  return reinterpret_cast<value_type const &>(super_type::_value);
+IPSpace<PAYLOAD>::iterator::operator*() const -> reference {
+  return const_cast<self_type*>(this)->_value;
 }
 
 template <typename PAYLOAD>
@@ -1513,6 +1566,14 @@ IPSpace<PAYLOAD>::iterator::operator++() -> self_type & {
   return *this;
 }
 
+template <typename PAYLOAD>
+auto
+IPSpace<PAYLOAD>::iterator::operator++(int) -> self_type {
+  self_type zret{*this};
+  ++*this;
+  return zret;
+}
+
 template <typename PAYLOAD>
 auto
 IPSpace<PAYLOAD>::iterator::operator--() -> self_type & {
@@ -1520,7 +1581,14 @@ IPSpace<PAYLOAD>::iterator::operator--() -> self_type & {
   return *this;
 }
 
-// --------------------------------------------------------------------------
+template <typename PAYLOAD>
+auto
+IPSpace<PAYLOAD>::iterator::operator--(int) -> self_type {
+  self_type zret{*this};
+  --*this;
+  return zret;
+}
+
 /// 
------------------------------------------------------------------------------------
 
 // +++ IPRange +++
@@ -1577,6 +1645,12 @@ IPRange::assign(IP6Addr const &min, IP6Addr const &max) 
-> self_type & {
   return *this;
 }
 
+inline auto
+IPRange::clear() -> self_type & {
+  _family = AF_UNSPEC;
+  return *this;
+}
+
 inline auto
 IPRange::networks() const -> NetSource {
   return {NetSource{*this}};
@@ -1592,6 +1666,15 @@ IPRange::operator!=(const self_type &that) const {
   return ! (*this == that);
 }
 
+inline bool
+IPRange::is_ip4() const {
+  return AF_INET == _family;
+}
+
+inline bool IPRange::is_ip6() const {
+  return AF_INET6 == _family;
+}
+
 // +++ IPNet +++
 
 inline IP4Net::IP4Net(swoc::IP4Addr addr, swoc::IPMask mask) : _addr(addr & 
mask), _mask(mask) {}
@@ -1771,6 +1854,22 @@ operator==(IP6Net const &lhs, IPNet const &rhs) {
   return rhs.is_ip6() && rhs.ip6() == lhs;
 }
 
+inline IP4Net
+IPNet::ip4() const {
+  return IP4Net{_addr.ip4(), _mask};
+}
+
+inline IP6Net
+IPNet::ip6() const {
+  return IP6Net{_addr.ip6(), _mask};
+}
+
+inline auto
+IPNet::clear() -> self_type & {
+  _mask.clear();
+  return *this;
+}
+
 // +++ Range -> Network classes +++
 
 inline bool
@@ -2180,12 +2279,12 @@ IPRangeSet::const_iterator::operator--(int) -> 
self_type {
 
 inline auto
 IPRangeSet::const_iterator::operator*() const -> value_type const& {
-  return _iter.range();
+  return _iter->range();
 }
 
 inline auto
 IPRangeSet::const_iterator::operator->() const -> value_type const * {
-  return &(_iter.range());
+  return &(_iter->range());
 }
 
 inline bool
@@ -2284,3 +2383,49 @@ get(swoc::IPNet const &net) {
 /// @endcond
 
 }} // namespace swoc::SWOC_VERSION_NS
+
+// Tuple support for IPSpace values.
+/// @cond NOT_DOCUMENTED
+
+namespace std {
+
+template <typename P> class tuple_size<swoc::detail::ip_space_value_type<P>> : 
public integral_constant<size_t, 2> {};
+
+template <size_t IDX, typename P> class tuple_element<IDX, 
swoc::detail::ip_space_value_type<P>> {
+  static_assert("swoc::IPSpace::value_type tuple index out of range");
+};
+
+template <typename P> class tuple_element<0, 
swoc::detail::ip_space_value_type<P>> {
+public:
+  using type = swoc::IPRange const &;
+};
+
+template <typename P> class tuple_element<1, 
swoc::detail::ip_space_value_type<P>> {
+public:
+  using type = P &;
+};
+
+} // namespace std
+
+namespace swoc { inline namespace SWOC_VERSION_NS { namespace detail {
+template <size_t IDX, typename P>
+auto
+get(ip_space_value_type<P> const &p) -> typename std::tuple_element<IDX, 
ip_space_value_type<P>>::type {
+  if constexpr (IDX == 0) {
+    return p._range;
+  } else if constexpr (IDX == 1) {
+    // Apparently some compilers complain because this can be @c nullptr but 
that's a valid state.
+    #pragma GCC diagnostic push
+    #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+    return *(p._payload);
+    #pragma GCC diagnostic pop
+  }
+}
+}}} // namespace swoc::detail
+
+// Support unqualified @c get because ADL doesn't seem to work.
+using swoc::detail::get;
+// Support @c std::get
+namespace std { using swoc::detail::get; }
+
+/// @endcond
diff --git a/code/include/swoc/Lexicon.h b/code/include/swoc/Lexicon.h
index c81337f..166cb6f 100644
--- a/code/include/swoc/Lexicon.h
+++ b/code/include/swoc/Lexicon.h
@@ -39,7 +39,7 @@ what(std::string_view const &fmt, Args &&...args) {
 }
 
 // Exported because inner classes in template classes cannot be used in 
partial specialization
-// which is required for tuple support. This should be remove next time there 
is a API changing
+// which is required for tuple support. This should be removed next time there 
is a API changing
 // release because tuple access is being deprecated.
 template < typename E > struct lexicon_pair_type {
   E _value;
diff --git a/unit_tests/ex_Lexicon.cc b/unit_tests/ex_Lexicon.cc
index 34281a7..a2ab2cc 100644
--- a/unit_tests/ex_Lexicon.cc
+++ b/unit_tests/ex_Lexicon.cc
@@ -86,7 +86,7 @@ TEST_CASE("Lexicon Example", "[libts][Lexicon]") {
 
   for ( auto const& [ addr, bits ] : AddrList ) {
     // doc.lookup.begin
-    auto && [ range, flags ] = *space.find(addr);
+    auto const& [ range, flags ] = *space.find(addr);
     // doc.lookup.end
     REQUIRE(flags == bits);
   }
@@ -100,7 +100,7 @@ swoc::Lexicon<NetType> const Example1 {
   {NetType::PROD, "prod"},
   {NetType::SECURE, "secure"},
   {NetType::EDGE, "edge"}},
-"*invalid*", // default name for undefined values
+  "*invalid*", // default name for undefined values
   NetType::INVALID // default value for undefined name
 };
 // doc.ctor.1.end
diff --git a/unit_tests/ex_ipspace_properties.cc 
b/unit_tests/ex_ipspace_properties.cc
index d98ef11..7d610c2 100644
--- a/unit_tests/ex_ipspace_properties.cc
+++ b/unit_tests/ex_ipspace_properties.cc
@@ -58,7 +58,7 @@ TEST_CASE("IPSpace bitset blending", 
"[libswoc][ipspace][bitset][blending]") {
   auto dump = [](Space&space) -> void {
     if (Verbose_p) {
       std::cout << W().print("{} ranges\n", space.count());
-      for (auto &&[r, payload] : space) {
+      for (auto && [r, payload] : space) {
         std::cout << W().print("{:25} : {}\n", r, payload);
       }
     }
@@ -411,7 +411,7 @@ bool Table::parse(TextView src) {
 
 auto Table::find(IPAddr const &addr) -> Row * {
   auto spot = _space.find(addr);
-  return spot == _space.end() ? nullptr : &std::get<1>(*spot);
+  return spot == _space.end() ? nullptr : &(spot->payload());
 }
 
 bool operator == (Table::Row const&, Table::Row const&) { return false; }
diff --git a/unit_tests/test_ip.cc b/unit_tests/test_ip.cc
index 711428e..0df4b42 100644
--- a/unit_tests/test_ip.cc
+++ b/unit_tests/test_ip.cc
@@ -38,12 +38,13 @@ using swoc::IP6Net;
 using swoc::IPSpace;
 using swoc::IPRangeSet;
 
-using W = swoc::LocalBufferWriter<256>;
 
 namespace {
+std::string bws;
+
 template<typename P> void dump(IPSpace < P > const& space) {
   for ( auto && [ r, p ] : space ) {
-    std::cout << W().print("{} : {}\n", r, p).view();
+    std::cout << bwprint(bws, "{} : {}\n", r, p);
   }
 }
 } // namespace
@@ -347,54 +348,56 @@ TEST_CASE("Basic IP", "[libswoc][ip]") {
 };
 
 TEST_CASE("IP Net and Mask", "[libswoc][ip][ipnet]") {
-    IP4Addr a24{"255.255.255.0"};
-    REQUIRE(IP4Addr::MAX == IPMask(32).as_ip4());
-    REQUIRE(IP4Addr::MIN == IPMask(0).as_ip4());
-    REQUIRE(IPMask(24).as_ip4() == a24);
-
-    swoc::IP4Net n1{"0/1"};
-    auto nr1 = n1.as_range();
-    REQUIRE(nr1.min() == IP4Addr::MIN);
-    REQUIRE(nr1.max() == IP4Addr("127.255.255.255"));
-
-    IP4Addr a{"8.8.8.8"};
-    swoc::IP4Net n4{a, IPMask{32}};
-    auto nr4 = n4.as_range();
-    REQUIRE(nr4.min() == a);
-    REQUIRE(nr4.max() == a);
-
-    swoc::IP4Net n0{"0/0"};
-    auto nr0 = n0.as_range();
-    REQUIRE(nr0.min() == IP4Addr::MIN);
-    REQUIRE(nr0.max() == IP4Addr::MAX);
-
-    swoc::IPMask m128{128};
-    REQUIRE(m128.as_ip6() == IP6Addr::MAX);
-    swoc::IPMask m0{0};
-    REQUIRE(m0.as_ip6() == IP6Addr::MIN);
-
-    IP6Addr a6{"12:34:56:78:9A:BC:DE:FF"};
-    REQUIRE(a6 == (a6 | IPMask(0)));
-    REQUIRE(IP6Addr::MAX == (a6 | IPMask(IP6Addr::WIDTH)));
-    REQUIRE(IP6Addr::MIN == (a6 & IPMask(0)));
-
-    IP6Addr a6_2{"2001:1f2d:c587:24c3:9128:3349:3cee:143"_tv};
-    swoc::IPMask mask{127};
-    CHECK(a6_2 == (a6_2 | mask));
-    CHECK(a6_2 != (a6_2 & mask));
-    CHECK(a6_2 == (a6_2 & swoc::IPMask(128))); // should always be a no-op.
-
-    IP6Net n6_1{a6_2, IPMask(96)};
-    CHECK(n6_1.min() == IP6Addr("2001:1f2d:c587:24c3:9128:3349::"));
-
-    swoc::IP6Addr a6_3{"2001:1f2d:c587:24c4::"};
-    CHECK(a6_3 == (a6_3 & swoc::IPMask{64}));
-    CHECK(a6_3 == (a6_3 & swoc::IPMask{62}));
-    CHECK(a6_3 != (a6_3 & swoc::IPMask{61}));
-
-    REQUIRE(IPMask(1) == IPMask::mask_for(IP4Addr("0x80.0.0.0")));
-    REQUIRE(IPMask(2) == IPMask::mask_for(IP4Addr("0xC0.0.0.0")));
-    REQUIRE(IPMask(27) == IPMask::mask_for(IP4Addr("0xFF.0xFF.0xFF.0xE0")));
+  IP4Addr a24{"255.255.255.0"};
+  REQUIRE(IP4Addr::MAX == IPMask(32).as_ip4());
+  REQUIRE(IP4Addr::MIN == IPMask(0).as_ip4());
+  REQUIRE(IPMask(24).as_ip4() == a24);
+
+  swoc::IP4Net n1{"0/1"};
+  auto nr1 = n1.as_range();
+  REQUIRE(nr1.min() == IP4Addr::MIN);
+  REQUIRE(nr1.max() == IP4Addr("127.255.255.255"));
+
+  IP4Addr a{"8.8.8.8"};
+  swoc::IP4Net n4{a, IPMask{32}};
+  auto nr4 = n4.as_range();
+  REQUIRE(nr4.min() == a);
+  REQUIRE(nr4.max() == a);
+
+  swoc::IP4Net n0{"0/0"};
+  auto nr0 = n0.as_range();
+  REQUIRE(nr0.min() == IP4Addr::MIN);
+  REQUIRE(nr0.max() == IP4Addr::MAX);
+
+  swoc::IPMask m128{128};
+  REQUIRE(m128.as_ip6() == IP6Addr::MAX);
+  swoc::IPMask m0{0};
+  REQUIRE(m0.as_ip6() == IP6Addr::MIN);
+
+  IP6Addr a6{"12:34:56:78:9A:BC:DE:FF"};
+  REQUIRE(a6 == (a6 | IPMask(0)));
+  REQUIRE(IP6Addr::MAX == (a6 | IPMask(IP6Addr::WIDTH)));
+  REQUIRE(IP6Addr::MIN == (a6 & IPMask(0)));
+
+  IP6Addr a6_2{"2001:1f2d:c587:24c3:9128:3349:3cee:143"_tv};
+  swoc::IPMask mask{127};
+  CHECK(a6_2 == (a6_2 | mask));
+  CHECK(a6_2 != (a6_2 & mask));
+  CHECK(a6_2 == (a6_2 & swoc::IPMask(128))); // should always be a no-op.
+
+  IP6Net n6_1{a6_2, IPMask(96)};
+  CHECK(n6_1.min() == IP6Addr("2001:1f2d:c587:24c3:9128:3349::"));
+
+  swoc::IP6Addr a6_3{"2001:1f2d:c587:24c4::"};
+  CHECK(a6_3 == (a6_3 & swoc::IPMask{64}));
+  CHECK(a6_3 == (a6_3 & swoc::IPMask{62}));
+  CHECK(a6_3 != (a6_3 & swoc::IPMask{61}));
+
+  REQUIRE(IPMask(1) == IPMask::mask_for(IP4Addr("0x80.0.0.0")));
+  REQUIRE(IPMask(2) == IPMask::mask_for(IP4Addr("0xC0.0.0.0")));
+  REQUIRE(IPMask(27) == IPMask::mask_for(IP4Addr("0xFF.0xFF.0xFF.0xE0")));
+  REQUIRE(IPMask(55) == IPMask::mask_for(IP6Addr("1337:dead:beef:CA00::")));
+  REQUIRE(IPMask(91) == 
IPMask::mask_for(IP6Addr("1337:dead:beef:CA00:24c3:3ce0::")));
 }
 
 TEST_CASE("IP Formatting", "[libswoc][ip][bwformat]") {
@@ -1121,15 +1124,14 @@ TEST_CASE("IPSpace docJJ", "[libswoc][ipspace][docJJ]") 
{
   unsigned idx;
 
   idx = 0;
-  for (auto spot = space.begin() ; spot != space.end() && idx < results.size() 
; ++spot) {
-    auto const& [ range, bits ] { *spot };
-    REQUIRE(idx < results.size());
+  for (auto const& [range, bits] : space) {
     CHECK(bits == results[idx]);
     ++idx;
   }
 
   idx = 0;
-  for (auto const& [range, bits] : space) {
+  for (auto spot = space.begin() ; spot != space.end() && idx < results.size() 
; ++spot ) {
+    auto const& [ range, bits ] { *spot };
     CHECK(bits == results[idx]);
     ++idx;
   }

Reply via email to