//----------------------------------------------------------------------------- // ___ __ _ _ // / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __ // / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ / // / ___/ (_| | | \__ \ __/ /__| | | | | < // \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ . // //----------------------------------------------------------------------------- // Author: Kurt Sassenrath // Module: Logging // // Type traits for massaging various types into something fmt-printable. // // Copyright (c) 2023 Kurt Sassenrath. // // License TBD. //----------------------------------------------------------------------------- #ifndef logging_traits_34e410874c0179c6 #define logging_traits_34e410874c0179c6 #include #include namespace parselink { namespace logging { // Customization point for printing out the enum name (value) and not the // full type. The default prints the type name. An example is provided below. // // enum class Foo { Bar, Cat }; // Foo v{Foo::Bar}; // logger.log<...>("value: {}", v); // logs "value: Foo::Bar" // logger.log<...>("value: {}", enum_name_only{v}); // logs "value: Bar" template requires std::is_enum_v struct enum_name_only { E v; }; template enum_name_only(E) -> enum_name_only; // Wrapper for a string that will be colorized as if it's an error, instead of // a normal string. struct error_str { template T> error_str(T&& t) : v(std::forward(t)) {} std::string_view v; }; namespace detail { // The following concepts aim to describe both raw and smart pointers in a // way that the log formatter can deduce theme (color/format) as well as // print the address without libformat's boilerplate (fmt::ptr). template struct is_smart_pointer_type : std::false_type {}; template struct is_smart_pointer_type> : std::true_type {}; template struct is_smart_pointer_type> : std::true_type {}; template concept smart_pointer = is_smart_pointer_type>::value; template using underlying_ptr_type = std::remove_cv_t< std::remove_pointer_t>>>; template concept non_string_pointer = std::is_pointer_v>> && !std::is_same_v, void> && !std::is_same_v, char>; template concept printable_pointer = smart_pointer || non_string_pointer; // Some simple assertions to avoid breaking the code above. static_assert(printable_pointer); static_assert(printable_pointer); static_assert(printable_pointer); static_assert(printable_pointer); static_assert(printable_pointer); static_assert(printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(!printable_pointer); static_assert(printable_pointer>); static_assert(printable_pointer&>); static_assert(printable_pointer const&>); static_assert(printable_pointer>); static_assert(printable_pointer&>); static_assert(printable_pointer const&>); } // namespace detail } // namespace logging } // namespace parselink #endif // logging_traits_34e410874c0179c6