Skip to content

Commit

Permalink
std::thread::id formatter adapter (Twon#285)
Browse files Browse the repository at this point in the history
* std::thread::id formatter adapter
  • Loading branch information
Twon authored Mar 24, 2024
1 parent 7151259 commit d6f7272
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ target_sources(MorpheusCore
filesystem.hpp
stacktrace.hpp
source_location.hpp
thread.hpp
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include "morpheus/core/conformance/format.hpp"
#include "morpheus/core/conformance/format.hpp"

#include <thread>

// clang-format off
#if (__cpp_lib_formatters < 202302L)

template <typename charT>
struct morpheus::fmt_ns::formatter<std::thread::id, charT>
{
constexpr auto parse(morpheus::fmt_ns::format_parse_context& ctx) { return std::begin(ctx); }

constexpr auto format(std::thread::id const& id, morpheus::fmt_ns::format_context& ctx) const
{
#if MORPHEUS_IS_VISUALSTUDIO_COMPATIBLE_COMPILER
return morpheus::fmt_ns::format_to(ctx.out(), "{}", id._Get_underlying_id());
#elif (MORPHEUS_COMPILER == MORPHEUS_APPLE_CLANG_COMPILER)
auto const idAsInt = *reinterpret_cast<std::uint64_t const*>(&id);
return morpheus::fmt_ns::format_to(ctx.out(), "{:#x}", idAsInt);
#elif (MORPHEUS_IS_GCC_COMPATIBLE_COMPILER)
if constexpr (sizeof(id) == sizeof(std::uint64_t))
{
auto const idAsInt = *reinterpret_cast<std::uint64_t const*>(&id);
return morpheus::fmt_ns::format_to(ctx.out(), "{}", idAsInt);
}
else if constexpr (sizeof(id) == sizeof(std::uint32_t))
{
auto const idAsInt = *reinterpret_cast<std::uint32_t const*>(&id);
return morpheus::fmt_ns::format_to(ctx.out(), "{}", idAsInt);
}
else
static_assert(sizeof(id) == sizeof(std::uint32_t) || sizeof(id) == sizeof(std::uint64_t), "Expected size is 32 or 64-bits only. Extend support if required");
#else
#error "Compiler unsupported for fallback std::formatter<std::thread::id> support"
#endif // (MORPHEUS_COMPILER == MORPHEUS_VISUALSTUDIO_COMPILER)
}
};

#endif
// clang-format on
1 change: 1 addition & 0 deletions libraries/core/tests/conformance/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ target_sources(MorpheusCoreTests
print.tests.cpp
scan.tests.cpp
stacktrace.tests.cpp
thread.tests.cpp
)
2 changes: 0 additions & 2 deletions libraries/core/tests/conformance/stacktrace.tests.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#include "morpheus/core/conformance/stacktrace.hpp"
#include "morpheus/core/conformance/format.hpp"
#include "morpheus/core/conversion/adapters/std/stacktrace.hpp"
#include "morpheus/temp_file.hpp"

#include <catch2/catch_all.hpp>
#include <iostream>

namespace morpheus
{
Expand Down
33 changes: 33 additions & 0 deletions libraries/core/tests/conformance/thread.tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "morpheus/core/conformance/format.hpp"
#include "morpheus/core/conversion/adapters/std/thread.hpp"
#include "morpheus/temp_file.hpp"

#include <catch2/catch_all.hpp>
#include <thread>
#include <sstream>

namespace morpheus
{

TEST_CASE("Ensure std::thread::id format specialisation is supported and working", "[morpheus.conformance.thread]")
{
GIVEN("a capture of the current stack trace")
{
auto const id = std::this_thread::get_id();

WHEN("Using std::format to write to a string")
{
// Ensure time zones work
auto const output = fmt_ns::format("{}", id);

THEN("Expect the variables wrote to the stream in the specified order")
{
std::stringstream str;
str << id;
REQUIRE(output == str.str());
}
}
}
}

}

0 comments on commit d6f7272

Please sign in to comment.