This is an automated email from the ASF dual-hosted git repository. amc pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new 7433988c8 libswoc: Update to 1.4.6 (#9530) 7433988c8 is described below commit 7433988c86a100093535bb913fb223cb689c9d72 Author: Alan M. Carroll <a...@apache.org> AuthorDate: Sat Mar 18 09:23:31 2023 -0500 libswoc: Update to 1.4.6 (#9530) --- lib/swoc/CMakeLists.txt | 2 +- lib/swoc/Makefile.am | 2 +- lib/swoc/include/swoc/DiscreteRange.h | 9 ++ lib/swoc/include/swoc/Errata.h | 128 ++++++++++++++-- lib/swoc/include/swoc/IPAddr.h | 2 + lib/swoc/include/swoc/IPRange.h | 273 +++++++++++++++++++++++++++++++--- lib/swoc/include/swoc/swoc_version.h | 4 +- lib/swoc/src/Errata.cc | 32 +++- lib/swoc/src/bw_format.cc | 12 +- lib/swoc/src/swoc_ip.cc | 6 +- 10 files changed, 414 insertions(+), 56 deletions(-) diff --git a/lib/swoc/CMakeLists.txt b/lib/swoc/CMakeLists.txt index 420da122e..f0a7755f5 100644 --- a/lib/swoc/CMakeLists.txt +++ b/lib/swoc/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.11) project(Lib-SWOC CXX) -set(LIBSWOC_VERSION "1.4.5") +set(LIBSWOC_VERSION "1.4.6") set(CMAKE_CXX_STANDARD 17) cmake_policy(SET CMP0087 NEW) # override "lib64" to be "lib" unless the user explicitly sets it. diff --git a/lib/swoc/Makefile.am b/lib/swoc/Makefile.am index bd1c51dea..210d7c6b4 100644 --- a/lib/swoc/Makefile.am +++ b/lib/swoc/Makefile.am @@ -22,7 +22,7 @@ library_includedir=$(includedir)/swoc AM_CPPFLAGS += @SWOC_INCLUDES@ -libtsswoc_la_LDFLAGS = @AM_LDFLAGS@ -no-undefined -release 1.4.5 +libtsswoc_la_LDFLAGS = @AM_LDFLAGS@ -no-undefined -release 1.4.6 libtsswoc_la_SOURCES = \ src/ArenaWriter.cc src/bw_format.cc src/bw_ip_format.cc src/Errata.cc src/MemArena.cc src/RBTree.cc src/swoc_file.cc src/swoc_ip.cc src/TextView.cc src/string_view_util.cc diff --git a/lib/swoc/include/swoc/DiscreteRange.h b/lib/swoc/include/swoc/DiscreteRange.h index cfefbf510..a04a3e7d2 100644 --- a/lib/swoc/include/swoc/DiscreteRange.h +++ b/lib/swoc/include/swoc/DiscreteRange.h @@ -850,6 +850,9 @@ public: /// @return The number of distinct ranges. size_t count() const; + /// @return @c true if there are no ranges in the container, @c false otherwise. + bool empty() const; + /// @return Iterator for the first range. iterator begin() { return _list.begin(); } /// @return Iterator past the last node. @@ -977,6 +980,12 @@ DiscreteSpace<METRIC, PAYLOAD>::count() const { return _list.count(); } +template <typename METRIC, typename PAYLOAD> +bool +DiscreteSpace<METRIC, PAYLOAD>::empty() const { + return _list.empty(); +} + template <typename METRIC, typename PAYLOAD> auto DiscreteSpace<METRIC, PAYLOAD>::head() -> Node * { diff --git a/lib/swoc/include/swoc/Errata.h b/lib/swoc/include/swoc/Errata.h index 94c9b9a2c..3995e279c 100644 --- a/lib/swoc/include/swoc/Errata.h +++ b/lib/swoc/include/swoc/Errata.h @@ -76,7 +76,7 @@ public: /// Code used if not specified. static inline const code_type DEFAULT_CODE; - /// Severity used if not specified. + /// Severity reported if severity not set. static Severity DEFAULT_SEVERITY; /// Severity level at which the instance is a failure of some sort. static Severity FAILURE_SEVERITY; @@ -189,7 +189,13 @@ protected: /// Allocate from the arena. swoc::MemSpan<char> alloc(size_t n); - Severity _severity{Errata::DEFAULT_SEVERITY}; ///< Severity. + TextView _annotation_glue_text = DEFAULT_ANNOTATION_GLUE_TEXT; + TextView _annotation_severity_glue_text = DEFAULT_SEVERITY_GLUE_TEXT; + TextView _severity_glue_text = DEFAULT_SEVERITY_GLUE_TEXT; + TextView _indent_text = DEFAULT_INDENT_TEXT; + bool _glue_final_p = true; ///< Add glue after the last annotation? + + std::optional<Severity> _severity; ///< Severity. code_type _code{Errata::DEFAULT_CODE}; ///< Message code / ID Container _notes; ///< The message stack. swoc::MemArena _arena; ///< Annotation text storage. @@ -360,7 +366,11 @@ public: friend std::ostream &operator<<(std::ostream &, self_type const &); /// Default glue value (a newline) for text rendering. - static std::string_view DEFAULT_GLUE; + static inline TextView DEFAULT_ANNOTATION_GLUE_TEXT = "\n"; + /// Default glue text for use after the severity name. + static inline TextView DEFAULT_SEVERITY_GLUE_TEXT = ": "; + // Text used for each level of indent. + static inline TextView DEFAULT_INDENT_TEXT = " "; /** Test status. @@ -391,6 +401,8 @@ public: */ bool is_ok() const; + bool has_severity() const { return _data && _data->_severity.has_value(); } + /** Get the maximum severity of the messages in the erratum. * * @return Max severity for all messages. @@ -442,12 +454,65 @@ public: //! Reference one past bottom item on the stack. const_iterator end() const; + /** First annotation. + * + * @return The first annotation. + * + * It is an error to call this on an empty instance. + */ const Annotation &front() const; + /** lask annotation. + * + * @return The last annotation. + * + * It is an error to call this on an empty instance. + */ const Annotation &back() const; // Logging support. + /// @return The annotation glue text for @a this. + TextView annotation_glue_text() const; + + /** Assign text to use between annotations while printing. + * + * @param text Glue text. + * @param final_glue_p Add glue after last annotation? + * @return @a this + */ + self_type & assign_annotation_glue_text(TextView text, bool final_glue_p = false); + + /// @return Glue text for the annotation severity. + TextView annotation_severity_glue_text() const; + + /** Assign text to use after the severity for an annoation while printing. + * + * @param text Glue text. + * @return @a this + */ + self_type & assign_annotation_severity_glue_text(TextView text); + + /// @return The severity glue text for @a this. + TextView severity_glue_text() const; + + /** Assign text to use after the severity while printing. + * + * @param text Glue text. + * @return @a this + */ + self_type & assign_severity_glue_text(TextView text); + + /// @return The text used for each level of indentation. + TextView indent_text() const; + + /** Assign the text used for indentation. + * + * @param text Text for each level of indentation. + * @return @a this. + */ + self_type & assign_indent_text(TextView text); + /** Base class for erratum sink. When an errata is abandoned, this will be called on it to perform any client specific logging. @@ -528,6 +593,7 @@ protected: friend struct Data; friend class Item; + friend BufferWriter &bwformat(BufferWriter &bw, bwf::Spec const &, Errata const &errata); }; extern std::ostream &operator<<(std::ostream &os, Errata const &stat); @@ -941,7 +1007,7 @@ inline auto Errata::assign(code_type code) -> self_type & { inline auto Errata::severity() const -> Severity { - return _data ? _data->_severity : DEFAULT_SEVERITY; + return _data ? _data->_severity.value() : DEFAULT_SEVERITY; } inline auto Errata::assign(Severity severity) -> self_type & { @@ -949,15 +1015,6 @@ inline auto Errata::assign(Severity severity) -> self_type & { return *this; } -inline auto Errata::update(Severity severity) -> self_type & { - if (_data) { - _data->_severity = std::max(_data->_severity, severity); - } else { - this->assign(severity); - } - return *this; -} - inline size_t Errata::length() const { return _data ? _data->_notes.count() : 0; @@ -1063,6 +1120,51 @@ Errata::end() const { return _data ? _data->_notes.end() : const_iterator(); } +inline TextView +Errata::annotation_glue_text() const { + return _data ? _data->_annotation_glue_text : DEFAULT_ANNOTATION_GLUE_TEXT; +} + +inline auto +Errata::assign_annotation_glue_text(TextView text, bool final_glue_p) -> self_type & { + this->data()->_annotation_glue_text = this->data()->localize(text); + this->data()->_glue_final_p = final_glue_p; + return *this; +} + +inline TextView +Errata::annotation_severity_glue_text() const { + return _data ? _data->_annotation_severity_glue_text : DEFAULT_SEVERITY_GLUE_TEXT; +} + +inline auto +Errata::assign_annotation_severity_glue_text(TextView text) -> self_type & { + this->data()->_annotation_severity_glue_text = this->data()->localize(text); + return *this; +} + +inline TextView +Errata::severity_glue_text() const { + return _data ? _data->_severity_glue_text : DEFAULT_SEVERITY_GLUE_TEXT; +} + +inline auto +Errata::assign_severity_glue_text(TextView text) -> self_type & { + this->data()->_severity_glue_text = this->data()->localize(text); + return *this; +} + +inline TextView +Errata::indent_text() const { + return _data ? _data->_indent_text : DEFAULT_INDENT_TEXT; +} + +inline auto +Errata::assign_indent_text(TextView text) -> self_type & { + this->data()->_indent_text = this->data()->localize(text); + return *this; +} + inline void Errata::SinkWrapper::operator()(Errata const &e) const { _f(e); diff --git a/lib/swoc/include/swoc/IPAddr.h b/lib/swoc/include/swoc/IPAddr.h index 44198f3df..ac359c4c9 100644 --- a/lib/swoc/include/swoc/IPAddr.h +++ b/lib/swoc/include/swoc/IPAddr.h @@ -9,6 +9,8 @@ #include <netinet/in.h> #include <sys/socket.h> +#include <cstddef> + #include "swoc/swoc_version.h" #include "swoc/swoc_meta.h" #include "swoc/MemSpan.h" diff --git a/lib/swoc/include/swoc/IPRange.h b/lib/swoc/include/swoc/IPRange.h index 89b69cd71..9f05c5a5e 100644 --- a/lib/swoc/include/swoc/IPRange.h +++ b/lib/swoc/include/swoc/IPRange.h @@ -322,14 +322,51 @@ public: /// Default constructor - construct invalid range. IPRange() = default; + /** Construct an inclusive range. + * + * @param min Minimum range value. + * @param max Maximum range value. + */ IPRange(IPAddr const &min, IPAddr const &max); + /** Construct an inclusive range. + * + * @param min Minimum range value. + * @param max Maximum range value. + */ + IPRange(IP4Addr const &min, IP4Addr const &max); + /** Construct an inclusive range. + * + * @param min Minimum range value. + * @param max Maximum range value. + */ + IPRange(IP6Addr const &min, IP6Addr const &max); + + /** Construct a singleton range. + * + * @param addr Address of range. + */ + + IPRange(IPAddr const& addr) : IPRange(addr, addr) {} + /** Construct a singleton range. + * + * @param addr Address of range. + */ + IPRange(IP4Addr addr) : IPRange(addr, addr) {} + + /** Construct a singleton range. + * + * @param addr Address of range. + */ + IPRange(IP6Addr const & addr) : IPRange(addr, addr) {} + /// Construct from an IPv4 @a range. IPRange(IP4Range const &range); /// Construct from an IPv6 @a range. IPRange(IP6Range const &range); + /** Construct from a string format. * * @param text Text form of range. @@ -338,6 +375,9 @@ public: */ IPRange(string_view const &text); + self_type & assign(IP4Addr const& min, IP4Addr const& max); + self_type & assign(IP6Addr const& min, IP6Addr const& max); + /// Equality bool operator==(self_type const &that) const; /// Inequality @@ -796,22 +836,24 @@ public: blend(IP6Range const &range, U const &color, F &&blender); /// @return The number of distinct ranges. - size_t - count() const { - return _ip4.count() + _ip6.count(); - } + size_t count() const; - size_t - count_ip4() const { - return _ip4.count(); - } - size_t - count_ip6() const { - return _ip6.count(); - } + /// @return The number of IPv4 ranges. + size_t count_ip4() const; + /// @return The number of IPv6 ranges. + size_t count_ip6() const; + + /** Number of rnages for a specific address family. + * + * @param f Address family. + * @return The number of ranges of @a family. + */ size_t count(sa_family_t f) const; + /// @return @c true if there are no ranges in the space, @c false otherwise. + bool empty() const; + /// Remove all ranges. void clear(); @@ -882,6 +924,8 @@ public: /// @return A pointer to the referent. value_type const *operator->() const; + IPRange const& range() const; + /// Equality bool operator==(self_type const &that) const; @@ -978,6 +1022,7 @@ public: /// Dereference. /// @return A pointer to the referent. value_type const *operator->() const; + }; /** Find the payload for an @a addr. @@ -1103,6 +1148,8 @@ protected: iterator iterator_at(typename IP6Space::iterator const& spot) { return iterator(_ip4.end(), spot); } + + friend class IPRangeSet; }; /** An IPSpace that contains only addresses. @@ -1117,6 +1164,20 @@ class IPRangeSet { using self_type = IPRangeSet; + /// Empty struct to use for payload. + /// This declares the struct and defines the singleton instance used. + /// @internal For some reason @c std::monostate didn't work, but I don't remember why. + static inline constexpr struct Mark { + using self_type = Mark; + /// @internal @c IPSpace requires equality / inequality operators. + /// These make all instance equal to each other. + bool operator==(self_type const &that); + bool operator!=(self_type const &that); + } MARK{}; + + /// Range set type. + using Space = swoc::IPSpace<Mark>; + public: /// Default construct empty set. IPRangeSet() = default; @@ -1145,22 +1206,85 @@ public: /// @return Number of ranges in the set. size_t count() const; + bool empty() const; + /// Remove all addresses in the set. void clear(); -protected: - /// Empty struct to use for payload. - /// This declares the struct and defines the singleton instance used. - static inline constexpr struct Mark { - using self_type = Mark; - /// @internal @c IPSpace requires equality / inequality operators. - /// These make all instance equal to each other. - bool operator==(self_type const &that); - bool operator!=(self_type const &that); - } MARK{}; + /// Constant iterator for iteration over ranges. + class const_iterator { + using self_type = const_iterator; ///< Self reference type. + using super_type = Space::const_iterator; + friend class IPRangeSet; + + public: + using value_type = IPRange const; + // STL algorithm compliance. + using iterator_category = std::bidirectional_iterator_tag; + using pointer = value_type *; + using reference = value_type &; + using const_reference = value_type const &; + using difference_type = int; + + /// Default constructor. + const_iterator() = default; + /// Copy constructor. + const_iterator(self_type const &that) = default; + + /// Assignment. + self_type &operator=(self_type const &that) = default; + + /// Pre-increment. + /// Move to the next element in the list. + /// @return The iterator. + self_type &operator++(); + + /// Pre-decrement. + /// Move to the previous element in the list. + /// @return The iterator. + self_type &operator--(); + + /// Post-increment. + /// Move to the next element in the list. + /// @return The iterator value before the increment. + 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); + + /// Dereference. + /// @return A reference to the referent. + value_type const& operator*() const; + + /// Dereference. + /// @return A pointer to the referent. + value_type const *operator->() const; + + /// Equality + bool operator==(self_type const &that) const; + + /// Inequality + bool operator!=(self_type const &that) const; + + protected: + const_iterator(super_type const& spot) : _iter(spot) {} + + super_type _iter; ///< Underlying iterator. + }; + + using iterator = const_iterator; + + /// @return Iterator to first range. + const_iterator begin() const { return _addrs.begin(); } + /// @return Iterator past last range. + const_iterator end() const { return _addrs.end(); } + +protected: /// The address set. - swoc::IPSpace<Mark> _addrs; + Space _addrs; }; inline auto @@ -1189,6 +1313,11 @@ IPRangeSet::count() const return _addrs.count(); } +inline bool +IPRangeSet::empty() const { + return _addrs.empty(); +} + inline void IPRangeSet::clear() { @@ -1294,9 +1423,13 @@ 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); } + /* 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 - * neccesary to do the @a _iter_4 validity on both iterators to avoid the case of a false positive + * necessary to do the @a _iter_4 validity on both iterators to avoid the case of a false positive * where different internal iterators are valid. However, in practice the other (non-active) * iterator won't have an arbitrary value, it will be either @c begin or @c end in step with the * active iterator therefore it's effective and cheaper to just check both values. @@ -1378,10 +1511,32 @@ inline IPRange::IPRange(IP6Range const &range) : _family(AF_INET6) { _range._ip6 = range; } +inline IPRange::IPRange(IP4Addr const &min, IP4Addr const &max) { + this->assign(min, max); +} + +inline IPRange::IPRange(IP6Addr const &min, IP6Addr const &max) { + this->assign(min, max); +} + inline IPRange::IPRange(string_view const &text) { this->load(text); } +inline auto +IPRange::assign(IP4Addr const &min, IP4Addr const &max) -> self_type & { + _range._ip4.assign(min, max); + _family = AF_INET; + return *this; +} + +inline auto +IPRange::assign(IP6Addr const &min, IP6Addr const &max) -> self_type & { + _range._ip6.assign(min, max); + _family = AF_INET6; + return *this; +} + inline auto IPRange::networks() const -> NetSource { return {NetSource{*this}}; @@ -1911,12 +2066,82 @@ IPSpace<PAYLOAD>::end(sa_family_t family) const -> const_iterator { return this->end(); } +template <typename PAYLOAD> +size_t +IPSpace<PAYLOAD>::count_ip4() const { + return _ip4.count(); +} + +template <typename PAYLOAD> +size_t +IPSpace<PAYLOAD>::count_ip6() const { + return _ip6.count(); +} + +template <typename PAYLOAD> +size_t +IPSpace<PAYLOAD>::count() const { + return _ip4.count() + _ip6.count(); +} + template <typename PAYLOAD> size_t IPSpace<PAYLOAD>::count(sa_family_t f) const { return IP4Addr::AF_value == f ? _ip4.count() : IP6Addr::AF_value == f ? _ip6.count() : 0; } +template <typename PAYLOAD> +bool +IPSpace<PAYLOAD>::empty() const { + return _ip4.empty() && _ip6.empty(); +} + +inline auto +IPRangeSet::const_iterator::operator++() -> self_type & { + ++_iter; + return *this; +} + +inline auto +IPRangeSet::const_iterator::operator--() -> self_type & { + --_iter; + return *this; +} + +inline auto +IPRangeSet::const_iterator::operator++(int) -> self_type { + self_type zret{*this}; + ++_iter; + return zret; +} + +inline auto +IPRangeSet::const_iterator::operator--(int) -> self_type { + self_type zret{*this}; + --_iter; + return zret; +} + +inline auto +IPRangeSet::const_iterator::operator*() const -> value_type const& { + return _iter.range(); +} + +inline auto +IPRangeSet::const_iterator::operator->() const -> value_type const * { + return &(_iter.range()); +} + +inline bool +IPRangeSet::const_iterator::operator==(IPRangeSet::const_iterator::self_type const &that) const { + return _iter == that._iter; +} + +inline bool +IPRangeSet::const_iterator::operator!=(IPRangeSet::const_iterator::self_type const &that) const { + return _iter != that._iter; +} + }} // namespace swoc::SWOC_VERSION_NS /// @cond NOT_DOCUMENTED diff --git a/lib/swoc/include/swoc/swoc_version.h b/lib/swoc/include/swoc/swoc_version.h index 636eae0b3..9c7d2748c 100644 --- a/lib/swoc/include/swoc/swoc_version.h +++ b/lib/swoc/include/swoc/swoc_version.h @@ -23,11 +23,11 @@ #pragma once #if !defined(SWOC_VERSION_NS) -#define SWOC_VERSION_NS _1_4_5 +#define SWOC_VERSION_NS _1_4_6 #endif namespace swoc { inline namespace SWOC_VERSION_NS { static constexpr unsigned MAJOR_VERSION = 1; static constexpr unsigned MINOR_VERSION = 4; -static constexpr unsigned POINT_VERSION = 5; +static constexpr unsigned POINT_VERSION = 6; }} // namespace swoc::SWOC_VERSION_NS diff --git a/lib/swoc/src/Errata.cc b/lib/swoc/src/Errata.cc index c354f0a9e..80e6bea91 100644 --- a/lib/swoc/src/Errata.cc +++ b/lib/swoc/src/Errata.cc @@ -25,8 +25,6 @@ namespace { std::vector<Errata::Sink::Handle> Sink_List; } -std::string_view Errata::DEFAULT_GLUE{"\n", 1}; - string_view Errata::Data::localize(string_view src) { auto span = _arena.alloc(src.size()).rebind<char>(); @@ -110,7 +108,9 @@ Errata & Errata::note(const self_type &that) { if (that._data) { auto d = this->data(); - d->_severity = std::max<Severity>(d->_severity, that._data->_severity); + if (that.has_severity()) { + this->update(that.severity()); + } for (auto const &annotation : that) { d->_notes.append(d->_arena.make<Annotation>(d->localize(annotation._text), annotation._severity, annotation._level + 1)); } @@ -118,6 +118,13 @@ Errata::note(const self_type &that) { return *this; } +auto Errata::update(Severity severity) -> self_type & { + if (! _data || ! _data->_severity.has_value() || _data->_severity.value() < severity) { + this->assign(severity); + } + return *this; +} + void Errata::register_sink(Sink::Handle const &s) { Sink_List.push_back(s); @@ -135,18 +142,31 @@ bwformat(BufferWriter &bw, bwf::Spec const &spec, Errata::Severity level) { BufferWriter & bwformat(BufferWriter &bw, bwf::Spec const &, Errata const &errata) { - bw.print("{}: ", errata.severity()); + if (errata.has_severity()) { + bw.print("{}{}", errata.severity(), errata.severity_glue_text()); + } if (errata.code()) { bw.print("[{0:s} {0:d}] ", errata.code()); } + bool trailing_p = false; + auto glue = errata.annotation_glue_text(); + auto a_s_glue = errata.annotation_severity_glue_text(); + auto id_txt = errata.indent_text(); for (auto ¬e : errata) { if (note.text()) { - bw.print("{}{}{}\n", swoc::bwf::Pattern{int(note.level()), " "}, swoc::bwf::If(note.has_severity(), "{}: ", note.severity()), - note.text()); + bw.print("{}{}{}{}" + , swoc::bwf::If(trailing_p, "{}", glue) + , swoc::bwf::Pattern{int(note.level()), id_txt} + , swoc::bwf::If(note.has_severity(), "{}{}", note.severity(), a_s_glue) + , note.text()); + trailing_p = true; } } + if (trailing_p && errata._data->_glue_final_p) { + bw.print("{}", glue); + } return bw; } diff --git a/lib/swoc/src/bw_format.cc b/lib/swoc/src/bw_format.cc index 4d4432e8e..0aa735986 100644 --- a/lib/swoc/src/bw_format.cc +++ b/lib/swoc/src/bw_format.cc @@ -936,11 +936,13 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Date const &date) { BufferWriter & bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Pattern const &pattern) { - auto limit = std::min<size_t>(spec._max, pattern._text.size() * pattern._n); - decltype(limit) n = 0; - while (n < limit) { - w.write(pattern._text); - n += pattern._text.size(); + if (! pattern._text.empty()) { // If there's no text, no point in looping. + auto limit = std::min<size_t>(spec._max, pattern._text.size() * pattern._n); + decltype(limit) n = 0; + while (n < limit) { + w.write(pattern._text); + n += pattern._text.size(); + } } return w; } diff --git a/lib/swoc/src/swoc_ip.cc b/lib/swoc/src/swoc_ip.cc index c9a5564d2..469d90f6e 100644 --- a/lib/swoc/src/swoc_ip.cc +++ b/lib/swoc/src/swoc_ip.cc @@ -1055,11 +1055,9 @@ IP6Range::load(std::string_view text) { IPRange::IPRange(IPAddr const &min, IPAddr const &max) { if (min.is_ip4() && max.is_ip4()) { - _range._ip4.assign(min.ip4(), max.ip4()); - _family = AF_INET; + this->assign(min.ip4(), max.ip4()); } else if (min.is_ip6() && max.is_ip6()) { - _range._ip6.assign(min.ip6(), max.ip6()); - _family = AF_INET6; + this->assign(min.ip6(), max.ip6()); } }