diff --git a/docs/ct_string.adoc b/docs/ct_string.adoc index 96bae02..f386ed1 100644 --- a/docs/ct_string.adoc +++ b/docs/ct_string.adoc @@ -113,3 +113,73 @@ constexpr auto s = "hello"_ctst; static_assert(always_true); // implicit conversion static_assert(always_true<+s>); // explicit conversion with + ---- + +=== Named Types + +`ct_string.hpp` also contains some functionality that can be used to name types +with a `ct_string`, and detect and retrieve names easily. + +==== `with_name` + +`with_name` is an empty class template that exposes a `constexpr static` `ct_string` +`name` member. A type named in this way models the `named` concept. + +[source,cpp] +---- +struct S : stdx::with_name<"name"> { + // constexpr static auto name = stdx::ct_string{"name"}; +}; + +static_assert(stdx::named); +---- + +==== `name_of_v` and `constant_name_of_{t,v}` + +To retrieve the name of a type, use `name_of_v`. To get it as a `cts_t`, use +`constant_name_of_v` (whose type is `constant_name_of_t`). + +[source,cpp] +---- +static_assert(stdx::name_of_v == "name"_cts); +static_assert(stdx::constant_name_of_v == "name"_ctst>); +using N = stdx::constant_name_of_t; // stdx::cts_t<"name"> +---- + +==== `matching_name` and `same_name` + +Use the `matching_name` concept to check whether a type's name matches a string. +Use `same_name` to check whether two types are named the same. + +[source,cpp] +---- +static_assert(stdx::matching_name); +static_assert(stdx::same_name>); +---- + +`matching_name` and `same_name` have corresponding +https://cppreference.com/cpp/types/integral_constant[`std::bool_constant`] types +and +https://www.boost.org/doc/libs/latest/libs/mp11/doc/html/mp11.html#definitions[quoted +metafunctions] for metaprogramming use. + +[source,cpp] +---- +// _t indicates a std::bool_constant of the concept +static_assert(stdx::matching_name_t::value); +static_assert(stdx::same_name_t>::value); + +// _q indicates a quoted metafunction that exposes fn (returning a std::bool_constant) +static_assert(stdx::matching_name_q<"name">::template fn::value); +static_assert(stdx::same_name_q>::template fn::value); +---- + +==== Formatted names + +Because a `ct_string` can be implicitly constructed from the result of a fully +compile-time invocation of `STDX_CT_FORMAT`, types can be named by formatting: + +[source,cpp] +---- +auto suffix = "name"_ctst; +struct S : stdx::with_name {}; +---- diff --git a/test/ct_format.cpp b/test/ct_format.cpp index 68b8fbc..01b890b 100644 --- a/test/ct_format.cpp +++ b/test/ct_format.cpp @@ -609,3 +609,10 @@ TEST_CASE("format a format_result with named ct argument (2/after rt arg)", STDX_CT_FORMAT("(year={y})", 2022)) == expected); STDX_PRAGMA(diagnostic pop) } + +TEST_CASE("object with formatted name", "[ct_format]") { + using namespace stdx::ct_string_literals; + auto s = "test"_ctst; + using T = stdx::with_name; + STATIC_CHECK(stdx::name_of_v == "T test"_cts); +}