Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/swoc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.11)

project(Lib-SWOC CXX)
set(LIBSWOC_VERSION "1.5.3")
set(LIBSWOC_VERSION "1.5.5")
set(CMAKE_CXX_STANDARD 17)
cmake_policy(SET CMP0087 NEW)
# override "lib64" to be "lib" unless the user explicitly sets it.
Expand Down
2 changes: 1 addition & 1 deletion lib/swoc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ library_includedir=$(includedir)/swoc

AM_CPPFLAGS += @SWOC_INCLUDES@

libtsswoc_la_LDFLAGS = @AM_LDFLAGS@ -no-undefined -release 1.5.3
libtsswoc_la_LDFLAGS = @AM_LDFLAGS@ -no-undefined -release 1.5.5
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

Expand Down
22 changes: 22 additions & 0 deletions lib/swoc/include/swoc/BufferWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,28 @@ class BufferWriter {
*/
template <typename Binding> BufferWriter &print_n(Binding const &names, TextView const &fmt);

/** Write formattted data.
*
* @tparam T Data type.
* @param spec Format specifier.
* @param t Instance to print.
* @return @a this
*
* Essentially this forwards @a t to @c bwformat.
*/
template <typename T> BufferWriter & format(bwf::Spec const& spec, T && t);

/** Write formattted data.
*
* @tparam T Data type.
* @param spec Format specifier.
* @param t Instance to print.
* @return @a this
*
* Essentially this forwards @a t to @c bwformat.
*/
template <typename T> BufferWriter & format(bwf::Spec const& spec, T const& t);

/** IO stream operator.
*
* @param stream Output stream.
Expand Down
13 changes: 13 additions & 0 deletions lib/swoc/include/swoc/bwf_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -1318,4 +1318,17 @@ BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::HexDump cons
inline BufferWriter &bwformat(BufferWriter &w, bwf::Spec const& spec, BufferWriter const& ww) {
return bwformat(w, spec, TextView(ww));
}

template <typename T>
BufferWriter &
BufferWriter::format(bwf::Spec const &spec, T const &t) {
return bwformat(*this, spec, t);
}

template <typename T>
BufferWriter &
BufferWriter::format(bwf::Spec const &spec, T && t) {
return bwformat(*this, spec, t);
}

}} // namespace swoc::SWOC_VERSION_NS
19 changes: 19 additions & 0 deletions lib/swoc/include/swoc/bwf_ex.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,23 @@ SubText<ARG>
Optional(TextView fmt, ARG &&arg) {
return detail::Optional(meta::CaseArg, fmt, std::forward<ARG>(arg));
}

/** Convert from ASCII hexadecimal to raw bytes.
*
* E.g. if the source span contains "4576696c20446176652052756c7a" then "Evil Dave Rulz" is the output.
* For format specifier support, on lhe max width is used. Any @c MemSpan compatible class can be used
* as the target, including @c std::string and @c std::string_view.
*
* @code
* void f(std::string const& str) {
* w.print("{}", bwf::UnHex(str));
* // ...
* @endcode
*/
struct UnHex {
UnHex(MemSpan<void const> const& span) : _span(span) {}
MemSpan<void const> _span; ///< Source span.
};
} // namespace bwf

/** Repeatedly output a pattern.
Expand Down Expand Up @@ -237,6 +254,8 @@ BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Errno const
*/
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Date const &date);

BufferWriter &bwformat(BufferWriter &w, bwf::Spec const& spec, bwf::UnHex const& obj);

/** Output a nested formatted string.
*
* @tparam Args Argument pack for @a subtext.
Expand Down
6 changes: 6 additions & 0 deletions lib/swoc/include/swoc/bwf_std.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "swoc/bwf_base.h"

namespace swoc { inline namespace SWOC_VERSION_NS {
using namespace literals;

/// Format atomics by stripping the atomic and formatting the underlying type.
template <typename T>
Expand Down Expand Up @@ -48,5 +49,10 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, std::chrono::time_point<Clock,
return bwformat(w, spec, t.time_since_epoch());
}

inline BufferWriter &
bwformat(BufferWriter &w, bwf::Spec const& spec, std::exception const& e) {
w.write("Exception - "_tv);
return bwformat(w, spec, e.what());
}

}} // end namespace swoc
19 changes: 12 additions & 7 deletions lib/swoc/include/swoc/swoc_meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,22 @@ template <typename T> T TypeFunc();
* This has no effect on @a u but fools the compiler in to thinking @a T has been used.
* This avoids metaprogramming issues with unused template parameters.
*
* Suppose an API has changed a function from "delain" to "Delain". To handle this the metacase support is used, but there is
* no apparent template parameter. A fake one can be used and defaulted to @c void. But that creates the unused template
* parameter warning. This is fixed by doing something like
* Suppose an API has changed a function from "cheer_for_delain" to "cheer_delain". To handle this
* the metacase support is used, but there is no apparent template parameter. A fake one can be used
* and defaulted to @c void. But that creates the unused template parameter warning. This is fixed
* by doing something to erase the template parameter @a V while forwarding parameter @a x. The result
* is a function @c f that calls the correct function automatically. Note this can't be in the body of
* the function because even for SFINAE the function body must compile and the variant with the wrong
* function will fail.
*
* @code
* template <typename V = void>
* auto f(UDT x, swoc::meta::CaseTag<0>) -> decltype(delain(eraser<V>(x)))
* { return delain(eraser<V>(x)); }
* auto f(UDT x, swoc::meta::CaseTag<0>) -> decltype(cheer_for_delain(eraser<V>(x)))
* { return cheer_for_delain(eraser<V>(x)); }
*
* template <typename V = void>
* auto f(UDT x, swoc::meta::CaseTag<1>) -> decltype(Delain(eraser<V>(x)))
* { return Delain(eraser<V>(vc)); }
* auto f(UDT x, swoc::meta::CaseTag<1>) -> decltype(cheer_delain(eraser<V>(x)))
* { return cheer_delain(eraser<V>(x)); }
*
* f(x, swoc::meta::CaseArg); // Invoke the correctly named function
* @endcode
Expand Down
4 changes: 2 additions & 2 deletions lib/swoc/include/swoc/swoc_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
#pragma once

#if !defined(SWOC_VERSION_NS)
#define SWOC_VERSION_NS _1_5_3
#define SWOC_VERSION_NS _1_5_5
#endif

namespace swoc { inline namespace SWOC_VERSION_NS {
static constexpr unsigned MAJOR_VERSION = 1;
static constexpr unsigned MINOR_VERSION = 5;
static constexpr unsigned POINT_VERSION = 3;
static constexpr unsigned POINT_VERSION = 5;
}} // namespace swoc::SWOC_VERSION_NS
4 changes: 3 additions & 1 deletion lib/swoc/src/Errata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,14 @@ bwformat(BufferWriter &bw, bwf::Spec const &spec, Errata::Severity level) {

BufferWriter &
bwformat(BufferWriter &bw, bwf::Spec const &, Errata const &errata) {
bwf::Format const code_fmt{"[{0:s} {0:d}] "};

if (errata.has_severity()) {
bw.print("{}{}", errata.severity(), errata.severity_glue_text());
}

if (errata.code()) {
bw.print("[{0:s} {0:d}] ", errata.code());
bw.print(code_fmt, errata.code());
}

bool trailing_p = false;
Expand Down
25 changes: 18 additions & 7 deletions lib/swoc/src/bw_format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -960,30 +960,41 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, bwf::Pattern const &pattern) {
return w;
}

swoc::BufferWriter &
bwformat(swoc::BufferWriter &w, swoc::bwf::Spec const &spec, std::error_code const &ec) {
static const auto GENERIC_CATEGORY = &std::generic_category();
static const auto SYSTEM_CATEGORY = &std::system_category();
BufferWriter &
bwformat(BufferWriter &w, bwf::Spec const &spec, std::error_code const &ec) {
static const auto G_CAT = &std::generic_category();
static const auto S_CAT = &std::system_category();

// This provides convenient safe access to the errno short name array.
static const swoc::bwf::Format number_fmt{"[{}]"_sv}; // numeric value format.
if (spec.has_numeric_type()) {
// if numeric type, print just the numeric part.
bwformat(w, spec, ec.value());
} else {
if ((&ec.category() == GENERIC_CATEGORY || &ec.category() == SYSTEM_CATEGORY) && swoc::ERRNO_RANGE.contains(ec.value())) {
if ((&ec.category() == G_CAT || &ec.category() == S_CAT) && swoc::ERRNO_RANGE.contains(ec.value())) {
bwformat(w, spec, swoc::ERRNO_SHORT_NAME[ec.value()]);
} else {
w.write(ec.message());
}
if (spec._type != 's' && spec._type != 'S') {
w.write(' ');
w.print(number_fmt, ec.value());
bwformat(w, spec, ec.value());
w.write(' ').write('[').format(spec, ec.value()).write(']');
}
}
return w;
}

BufferWriter&
bwformat(BufferWriter &w, bwf::Spec const& spec, bwf::UnHex const& obj) {
auto span { obj._span };
size_t limit = spec._max;
while (span.size() >= 2 && limit--) {
auto b = svto_radix<16>(span.clip_prefix(2).rebind<char const>());
w.write(b);
}
return w;
}

}} // namespace swoc::SWOC_VERSION_NS

namespace std {
Expand Down