template<typename T> \
concept has_##CONCEPT_NAME = requires \
{ \
{std::decay_t<T>::CONCEPT_NAME()} -> std::convertible_to<std::string>; \
{std::decay_t<T>::CONCEPT_NAME()} -> std::convertible_to<std::string_view>; \
{std::decay_t<T>::CONCEPT_NAME()} -> std::convertible_to<const char *>; \
}; \
template<has_##CONCEPT_NAME T> \
constexpr auto CONCEPT_NAME##_of(const T&) { return T::CONCEPT_NAME(); } \
\
template<has_##CONCEPT_NAME T> \
_consteval auto CONCEPT_NAME##_of() { return std::decay_t<T>::CONCEPT_NAME(); }