// Rangarajan Krishnamoorthy, August 12, 2023
// std::is_scoped_enum_v<>
//

#include <iostream>
#include <type_traits>

#if 0
enum WeekDay { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
enum Automobile { Car, Jeep, Van, Truck };
enum Fruit : unsigned char{ Orange, Apple, Banana, Grape }; // Use fixed underlying type

int main()
{
    WeekDay day1{ Wednesday };
    Automobile auto1{ Van };

    int a = Saturday; // Implicit conversion to integer
    int b = Jeep; // Implicit conversion to integer
    std::cout << "Sum = " << (day1 + auto1) << std::endl; // Add as integers
    if (auto1 == day1)
        std::cout << "WeekDay and Automobile are same!\n";
}

#endif

#if 0
enum class WeekDay{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
enum struct Automobile { Car, Jeep, Van, Truck };

int main()
{
    WeekDay day1{ WeekDay::Wednesday }; // Scope operator needed
    Automobile auto1{ Automobile::Van }; // Scope operator needed

    int a = static_cast<int>(WeekDay::Saturday); // Explicit cast needed
    int b = static_cast<int>(Automobile::Jeep); // Explicit cast needed

//    std::cout << "Sum = " << (day1 + auto1) << std::endl; // Compiler error
//    if (auto1 == day1) // Compiler error
//        std::cout << "WeekDay and Automobile are same!\n";
}

#endif

#if 0
enum Vegetable { Carrot, Tomato, Potato };
enum class WeekDay { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
enum struct Automobile { Car, Jeep, Van, Truck };

struct X {};
class Y {};

int main()
{
    std::cout << std::boolalpha;
    std::cout << std::is_scoped_enum_v<Vegetable> << std::endl;
    std::cout << std::is_scoped_enum_v<WeekDay> << std::endl;
    std::cout << std::is_scoped_enum_v<Automobile> << std::endl;
    std::cout << std::is_scoped_enum_v<double> << std::endl;
    std::cout << std::is_scoped_enum_v<X> << std::endl;
    std::cout << std::is_scoped_enum_v<Y> << std::endl;
}

#endif

enum Vegetable { Carrot, Tomato, Potato };
enum class WeekDay { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
enum struct Automobile { Car, Jeep, Van, Truck };

template<typename T>
requires std::is_scoped_enum_v<T>
void foo(T)
{
    // Do something
}

int main()
{
    foo(WeekDay::Friday);
    foo(Automobile::Truck);
//    foo(Vegetable::Carrot); // This won't compile
//    foo(100); // This won't compile
}

