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
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@ target_sources(
BASE_DIRS
include
FILES
include/log/env.hpp
include/log/level.hpp
include/log/log.hpp)
include/log/log.hpp
include/log/module.hpp)

add_library(cib_msg INTERFACE)
target_compile_features(cib_msg INTERFACE cxx_std_20)
Expand Down
42 changes: 28 additions & 14 deletions include/log/env.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@

#include <boost/mp11/algorithm.hpp>

#ifdef __clang__
#define CIB_PRAGMA_SEMI
#else
#define CIB_PRAGMA_SEMI ;
#endif

namespace logging {
template <auto Query, auto Value> struct prop {
[[nodiscard]] CONSTEVAL static auto query(decltype(Query)) noexcept {
Expand Down Expand Up @@ -44,13 +38,16 @@ template <typename... Envs> struct env {

namespace detail {
template <typename T> struct autowrap {
// NOLINTNEXTLINE(google-explicit-constructor)
CONSTEVAL autowrap(T t) : value(t) {}
T value;
};

// NOLINTNEXTLINE(modernize-avoid-c-arrays)
template <std::size_t N> using str_lit_t = char const (&)[N];

template <std::size_t N> struct autowrap<str_lit_t<N>> {
// NOLINTNEXTLINE(google-explicit-constructor)
CONSTEVAL autowrap(str_lit_t<N> str) : value(str) {}
stdx::ct_string<N> value;
};
Expand All @@ -77,15 +74,32 @@ template <std::size_t... Is> struct for_each_pair<std::index_sequence<Is...>> {
using cib_log_env_t = logging::env<>;

// NOLINTBEGIN(cppcoreguidelines-macro-usage)

#ifdef __clang__
#define CIB_PRAGMA_SEMI
#else
#define CIB_PRAGMA_SEMI ;
#endif

#define CIB_LOG_ENV_DECL(...) \
[[maybe_unused]] typedef decltype([]<logging::detail::autowrap... Args> { \
using new_env_t = \
typename logging::detail::for_each_pair<std::make_index_sequence< \
sizeof...(Args) / 2>>::template type<Args...>; \
return boost::mp11::mp_append<new_env_t, cib_log_env_t>{}; \
}.template operator()<__VA_ARGS__>()) cib_log_env_t

#define CIB_LOG_ENV(...) \
STDX_PRAGMA(diagnostic push) \
STDX_PRAGMA(diagnostic ignored "-Wshadow") \
using cib_log_env_t [[maybe_unused]] = \
decltype([]<logging::detail::autowrap... Args> { \
using new_env_t = typename logging::detail::for_each_pair< \
std::make_index_sequence<sizeof...(Args) / \
2>>::template type<Args...>; \
return boost::mp11::mp_append<new_env_t, cib_log_env_t>{}; \
}.template operator()<__VA_ARGS__>()) CIB_PRAGMA_SEMI \
STDX_PRAGMA(diagnostic pop)
CIB_LOG_ENV_DECL(__VA_ARGS__) \
CIB_PRAGMA_SEMI \
STDX_PRAGMA(diagnostic pop)

#define CIB_WITH_LOG_ENV(...) \
STDX_PRAGMA(diagnostic push) \
STDX_PRAGMA(diagnostic ignored "-Wshadow") \
if constexpr (CIB_LOG_ENV_DECL(__VA_ARGS__); true) \
STDX_PRAGMA(diagnostic pop)

// NOLINTEND(cppcoreguidelines-macro-usage)
38 changes: 38 additions & 0 deletions test/log/env.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#include <log/env.hpp>
#include <log/level.hpp>
#include <log/log.hpp>
#include <log/module.hpp>

#include <catch2/catch_test_macros.hpp>

#include <string_view>
#include <utility>
#include <vector>

namespace {
[[maybe_unused]] constexpr inline struct custom_t {
template <typename T>
Expand Down Expand Up @@ -48,3 +54,35 @@ TEST_CASE("multi-value environment", "[log_env]") {
static_assert(custom(cib_log_env_t{}) == 1);
static_assert(logging::get_module(cib_log_env_t{}) == "hello"_ctst);
}

namespace {
auto logged_modules = std::vector<std::string_view>{};

struct log_handler {
template <logging::level L, typename Env, typename FilenameStringType,
typename LineNumberType, typename MsgType>
auto log(FilenameStringType, LineNumberType, MsgType const &) -> void {
using namespace stdx::literals;
logged_modules.push_back(
std::string_view{logging::get_module(Env{}).value});
}
};

struct log_config {
log_handler logger;
};
} // namespace

template <> inline auto logging::config<> = log_config{};

TEST_CASE("with-scoped environment", "[log_env]") {
logged_modules.clear();

CIB_WITH_LOG_ENV(logging::get_module, "with") { CIB_INFO(""); }
REQUIRE(logged_modules.size() == 1);
CHECK(logged_modules[0] == "with");

CIB_INFO("");
REQUIRE(logged_modules.size() == 2);
CHECK(logged_modules[1] == "default");
}
Loading