Add deref utilities & use them for log writer
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
|
||||
// @Todo Don't use internal get_stdout_writer, make console module
|
||||
|
||||
static asl::log::DefaultLogger g_default_logger{asl::print_internals::get_stdout_writer()};
|
||||
static asl::log::DefaultLogger<asl::Writer*> g_default_logger{asl::print_internals::get_stdout_writer()};
|
||||
static asl::log::Logger* g_head = &g_default_logger;
|
||||
|
||||
static constexpr asl::string_view kLevelName[] = {
|
||||
@ -20,9 +20,9 @@ void asl::log::register_logger(box<Logger> logger_box)
|
||||
logger->m_next = exchange(g_head, logger);
|
||||
}
|
||||
|
||||
void asl::log::DefaultLogger::log(const message& msg)
|
||||
void asl::log::DefaultLoggerBase::log_inner(Writer& writer, const message& msg)
|
||||
{
|
||||
asl::format(m_writer, "[{}] {}:{}: {}\n",
|
||||
asl::format(&writer, "[{}] {}:{}: {}\n",
|
||||
kLevelName[msg.level], // NOLINT
|
||||
msg.location.file,
|
||||
msg.location.line,
|
||||
|
@ -39,16 +39,24 @@ public:
|
||||
constexpr Logger* next_logger() const { return m_next; }
|
||||
};
|
||||
|
||||
// @Todo Make a deref_as trait & deref utility
|
||||
// @Todo Accept writer as box, pointer, reference, or value
|
||||
class DefaultLogger : public Logger
|
||||
class DefaultLoggerBase : public Logger
|
||||
{
|
||||
Writer* m_writer;
|
||||
protected:
|
||||
static void log_inner(Writer&, const message&);
|
||||
};
|
||||
|
||||
template<derefs_as<Writer> W>
|
||||
class DefaultLogger : public DefaultLoggerBase
|
||||
{
|
||||
W m_writer;
|
||||
|
||||
public:
|
||||
explicit constexpr DefaultLogger(Writer* writer) : m_writer{writer} {}
|
||||
explicit constexpr DefaultLogger(W&& writer) : m_writer{ASL_FWD(writer)} {}
|
||||
|
||||
void log(const message&) override;
|
||||
constexpr void log(const message& m) override
|
||||
{
|
||||
log_inner(deref<Writer>(m_writer), m);
|
||||
}
|
||||
};
|
||||
|
||||
void register_logger(box<Logger>);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <asl/log/log.hpp>
|
||||
#include <asl/testing/testing.hpp>
|
||||
#include <asl/string_builder.hpp>
|
||||
|
||||
ASL_TEST(log)
|
||||
{
|
||||
@ -8,3 +9,15 @@ ASL_TEST(log)
|
||||
ASL_LOG_ERROR("Oh no! {}", 42);
|
||||
}
|
||||
|
||||
static asl::StringWriter g_string_writer{};
|
||||
|
||||
ASL_TEST(custom_writer)
|
||||
{
|
||||
asl::log::register_logger<asl::log::DefaultLogger<asl::StringWriter<>&>>(g_string_writer);
|
||||
|
||||
ASL_LOG_INFO("Hello");
|
||||
auto sv = g_string_writer.as_string_view();
|
||||
|
||||
ASL_TEST_EXPECT(sv == "[ INFO ] asl/log/log_tests.cpp:18: Hello\n");
|
||||
}
|
||||
|
||||
|
27
asl/meta.hpp
27
asl/meta.hpp
@ -117,6 +117,8 @@ template<typename T> struct _is_ref_helper<T&> { static constexpr bool l = true
|
||||
template<typename T> struct _is_ref_helper<T&&> { static constexpr bool l = false; static constexpr bool r = true; };
|
||||
|
||||
template<typename T> concept is_ref = _is_ref_helper<T>::l || _is_ref_helper<T>::r;
|
||||
template<typename T> concept is_rref = _is_ref_helper<T>::r;
|
||||
template<typename T> concept is_lref = _is_ref_helper<T>::l;
|
||||
|
||||
template<typename T> struct _is_ptr_helper : false_type {};
|
||||
template<typename T> struct _is_ptr_helper<T*> : true_type {};
|
||||
@ -218,4 +220,29 @@ concept has_niche = constructible_from<T, niche_t> && equality_comparable_with<T
|
||||
template<typename T>
|
||||
concept is_niche = same_as<un_cvref_t<T>, niche_t>;
|
||||
|
||||
template<typename T, typename U>
|
||||
concept _derefs_with_indirection_as = requires(T& t)
|
||||
{
|
||||
*t;
|
||||
requires convertible_from<U&, decltype(*t)>;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
concept _derefs_reference_as = is_ref<T> && convertible_from<U&, T>;
|
||||
|
||||
template<typename T, typename U>
|
||||
concept _derefs_value_as = !is_ref<T> && convertible_from<U&, T&>;
|
||||
|
||||
template<typename U, _derefs_with_indirection_as<U> T>
|
||||
constexpr U& deref(T&& t) { return static_cast<U&>(*t); }
|
||||
|
||||
template<typename U, _derefs_reference_as<U> T>
|
||||
constexpr U& deref(T&& t) { return static_cast<U&>(t); }
|
||||
|
||||
template<typename U, _derefs_value_as<U> T>
|
||||
constexpr U& deref(T&& t) { return static_cast<U&>(t); }
|
||||
|
||||
template<typename T, typename U>
|
||||
concept derefs_as = _derefs_with_indirection_as<T, U> || _derefs_reference_as<T, U> || _derefs_value_as<T, U>;
|
||||
|
||||
} // namespace asl
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "asl/meta.hpp"
|
||||
#include "asl/tests/test_types.hpp"
|
||||
#include "asl/testing/testing.hpp"
|
||||
#include "asl/box.hpp"
|
||||
|
||||
struct Struct {};
|
||||
union Union {};
|
||||
@ -247,3 +249,41 @@ static_assert(!asl::is_enum<int>);
|
||||
static_assert(asl::is_enum<Enum1>);
|
||||
static_assert(asl::is_enum<Enum2>);
|
||||
|
||||
static_assert(asl::derefs_as<int, int>);
|
||||
static_assert(asl::derefs_as<int*, int>);
|
||||
static_assert(asl::derefs_as<int&, int>);
|
||||
static_assert(asl::derefs_as<asl::box<int>, int>);
|
||||
|
||||
static_assert(asl::derefs_as<Derived, Base>);
|
||||
static_assert(asl::derefs_as<Derived*, Base>);
|
||||
static_assert(asl::derefs_as<Derived&, Base>);
|
||||
static_assert(asl::derefs_as<asl::box<Derived>, Base>);
|
||||
|
||||
static void wants_int(int) {}
|
||||
static void wants_base(Base&) {}
|
||||
static void wants_base_ptr(Base*) {}
|
||||
|
||||
ASL_TEST(deref)
|
||||
{
|
||||
int a = 4;
|
||||
auto b = asl::make_box<int>(5);
|
||||
|
||||
wants_int(asl::deref<int>(5));
|
||||
wants_int(asl::deref<int>(a));
|
||||
wants_int(asl::deref<int>(&a));
|
||||
wants_int(asl::deref<int>(b));
|
||||
|
||||
Derived c{};
|
||||
auto d = asl::make_box<Derived>();
|
||||
|
||||
wants_base(asl::deref<Base>(Derived{}));
|
||||
wants_base(asl::deref<Base>(c));
|
||||
wants_base(asl::deref<Base>(&c));
|
||||
wants_base(asl::deref<Base>(d));
|
||||
|
||||
wants_base_ptr(&asl::deref<Base>(Derived{}));
|
||||
wants_base_ptr(&asl::deref<Base>(c));
|
||||
wants_base_ptr(&asl::deref<Base>(&c));
|
||||
wants_base_ptr(&asl::deref<Base>(d));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user