#include <iostream>

using namespace std;

struct Logger
{
    template<typename Type>
    constexpr bool IsRawString()
    {
        return std::is_same<const char*, Type>::value || std::is_same<char*, Type>::value;
    }

    template<typename Type, typename Enable = void>
    struct Traits
    {
        static const int Index = 1;
    };

    template<typename Type>
    struct Traits<Type, std::enable_if_t<IsRawString<Type>()>>
    {
        static const int Index = 2;
    };

    template<typename Type>
    struct Traits<Type, std::enable_if_t<std::is_pointer<Type>::value && !IsRawString<Type>()>>
    {
        static const int Index = 3;
    };

};

int main()
{
    cout << Logger::Traits<int>::Index << endl
         << Logger::Traits<char*>::Index << endl
         << Logger::Traits<const char*>::Index << endl
         << Logger::Traits<void*>::Index << endl;


    return 0;
}
