Skip to content

Commit

Permalink
LAZY OBJECT STREAMING
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Jan 24, 2024
1 parent 38696df commit 3198902
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
8 changes: 2 additions & 6 deletions nano/lib/logging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <shared_mutex>
#include <sstream>

#include <fmt/ostream.h>
#include <spdlog/spdlog.h>

namespace nano::log
Expand Down Expand Up @@ -146,12 +147,7 @@ class logger final
auto logger = get_logger (type);
if (logger.should_log (spdlog::level::trace))
{
std::stringstream ss;

nano::object_stream obs{ ss };
(obs.write (args.name, args.value), ...);

logger.trace ("\"{}\" {}", to_string (detail), ss.str ());
logger.trace ("\"{}\" {}", to_string (detail), nano::object_stream_formatter{ std::forward<Args> (args)... });
}
}

Expand Down
40 changes: 35 additions & 5 deletions nano/lib/object_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string_view>
#include <type_traits>

#include <fmt/ostream.h>
#include <magic_enum.hpp>

namespace nano
Expand Down Expand Up @@ -44,16 +45,14 @@ class array_stream;
*/

template <typename T>
concept object_streamable = requires (T const & obj, object_stream & obs)
{
concept object_streamable = requires (T const & obj, object_stream & obs) {
{
obj (obs)
};
};

template <typename T>
concept array_streamable = requires (T const & obj, array_stream & ars)
{
concept array_streamable = requires (T const & obj, array_stream & ars) {
{
obj (ars)
};
Expand Down Expand Up @@ -180,8 +179,39 @@ class root_object_stream : private object_stream_base
void write (Value const & value);
};

/**
* Wraps `Args &&... args` and provides a `<< (std::ostream &, ...)` operator that writes the arguments to the stream in a lazy manner.
*/
template <class... Args>
struct object_stream_formatter
{
std::tuple<Args...> args;

explicit object_stream_formatter (Args &&... args) :
args{ std::forward<Args> (args)... }
{
}

friend std::ostream & operator<< (std::ostream & os, object_stream_formatter<Args...> const & self)
{
object_stream obs{ os };
std::apply ([&obs] (auto &&... args) {
((obs.write (args.name, args.value)), ...);
},
self.args);
return os;
}
};

// Needed for fmt formatting, uses the ostream operator under the hood
template <class... Args>
auto format_as (object_stream_formatter<Args...> const & val)
{
return fmt::streamed (val);
}

/*
* Impl
* implementation
*/

template <class Value>
Expand Down

0 comments on commit 3198902

Please sign in to comment.