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
30 changes: 23 additions & 7 deletions include/stdx/ct_conversions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,39 @@ template <auto Value>
CONSTEVAL static auto enum_as_string() -> std::basic_string_view<char> {
#ifdef __clang__
constexpr std::string_view value_string = __PRETTY_FUNCTION__;
constexpr auto rhs = value_string.size() - 2;
#elif defined(__GNUC__) || defined(__GNUG__)
constexpr std::string_view value_string = __PRETTY_FUNCTION__;
constexpr auto rhs = value_string.size() - 2;
#else
static_assert(always_false_v<Tag>,
"Unknown compiler, can't build type name.");
#endif
constexpr auto qual_str = [&]() -> std::string_view {
constexpr auto rhs = value_string.size() - 2;
if (auto const eq_pos = value_string.find_last_of('=');
eq_pos != std::string_view::npos) {
auto const lhs = eq_pos + 2;
return value_string.substr(lhs, rhs - lhs + 1);
}
return value_string;
}();

constexpr auto cast_str = [&]() -> std::string_view {
if (auto const close_paren_pos = qual_str.find_last_of(')');
close_paren_pos != std::string_view::npos) {
if (qual_str[close_paren_pos + 1] != ':') {
return qual_str;
}
}

constexpr auto lhs = [&]() -> std::string_view::size_type {
if (auto const colon_pos = value_string.find_last_of(':');
if (auto const colon_pos = qual_str.find_last_of(':');
colon_pos != std::string_view::npos) {
return colon_pos + 1;
return qual_str.substr(colon_pos + 1);
}
return 0;

return qual_str;
}();
return value_string.substr(lhs, rhs - lhs + 1);

return cast_str;
}
} // namespace v1
} // namespace stdx
11 changes: 9 additions & 2 deletions test/ct_conversions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ enum struct B { Y };

TEST_CASE("enum as string", "[ct_conversion]") {
using namespace std::string_view_literals;
STATIC_REQUIRE(stdx::enum_as_string<X>() == "X"sv);
STATIC_REQUIRE(stdx::enum_as_string<B::Y>() == "Y"sv);
STATIC_CHECK(stdx::enum_as_string<X>() == "X"sv);
STATIC_CHECK(stdx::enum_as_string<B::Y>() == "Y"sv);
}

enum struct C {};

TEST_CASE("enum as string (no identifier)", "[ct_conversion]") {
using namespace std::string_view_literals;
STATIC_CHECK(stdx::enum_as_string<C{17}>() == "(C)17"sv);
}