Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support cartesian product for enum_switch #213

Open
Sarna555 opened this issue Sep 8, 2022 · 7 comments
Open

Support cartesian product for enum_switch #213

Sarna555 opened this issue Sep 8, 2022 · 7 comments
Labels
help wanted Extra attention is needed

Comments

@Sarna555
Copy link

Sarna555 commented Sep 8, 2022

Not so good but showing some use case example

enum class MyType {
    INT2,
    INT4,
    INT8,
    FLOAT4,
    FLOAT8
};

struct MyData {
    void * data;
    MyType type;
};

auto var1 = init_my_data(10, MyType::INT4);
auto var2 = init_my_data(10.23, MyType::FLOAT4);

auto switcher = overloaded{
    [&]( magic_enum::enum_constant<MyType::INT4>, magic_enum::enum_constant<MyType::FLOAT4> ) {
        float result = *static_cast<int*>(var1.data) + *static_cast<float*>(var2.data);
        return init_my_type( result, MyType::FLOAT4 );
    },
    []( auto, auto ) { throw notimplemented; }
};
enum_switch( switcher, var1.type, var2.type );

It's similar to what std::visit is doing with std::variant and cartesian product.
Right now I think you need to add enum_switch in enum_switch to achive it and that imo produces boilerplate code.

@Neargye
Copy link
Owner

Neargye commented Sep 8, 2022

@Sarna555
Copy link
Author

Sarna555 commented Sep 14, 2022

Yes, but it's still doesn't give me the flexibility of std::visit, what I'd like to actually do is

// probably pseudocode :)
auto switcher = overloaded{
    [&]( auto lhsType, auto rhsType ) {
        ReturnTypeTrait<lhs,rhs>::type result = *static_cast<TypeTrait<lhs>::type*>(var1.data) + *static_cast<TypeTrait<rhs>::type*>(var2.data);
        return init_my_type( result, ReturnTypeTrait<lhs,rhs>::type );
    },
    []( auto, auto ) { throw notimplemented; }
};
enum_switch( switcher, var1.type, var2.type );

this way I don't have to write every case manually like with enum_fuse.

@Neargye Neargye added the enhancement New feature or request label Oct 11, 2022
@schaumb
Copy link
Contributor

schaumb commented Oct 18, 2022

Related: #200 (comment)

@falemagn
Copy link

falemagn commented Oct 18, 2022

@Sarna555 Any specific reason you can't use std::variant?

constexpr struct notimplemented_t{} notimplemented{};

struct MyType {
    using INT2 = std::int16_t;
    using INT4 = std::int32_t;
    using INT8 = std::int64_t;
    using FLOAT4 = float;
    using FLOAT8 = double;
};

using MyData = std::variant<
    MyType::INT2,
    MyType::INT4,
    MyType::INT8,
    MyType::FLOAT4,
    MyType::FLOAT8
>;

auto var1 = MyData(std::in_place_type<MyType::INT4>, 10);
auto var2 = MyData(std::in_place_type<MyType::FLOAT4>, 10.23);

auto switcher = overloaded{
    [](MyType::INT4 &var1, MyType::FLOAT4 &var2) {
        float result = var1 + var2;
        return MyData(std::in_place_type<MyType::FLOAT4>, result);;
    },
    
    []( auto, auto ) { throw notimplemented; return MyData(); }
};

auto result = std::visit(switcher, var1, var2);

I've used MyType:: just to keep the analogy with your code more evident, but the code can be simplified a lot if you use the raw types directly.

@Sarna555
Copy link
Author

@falemagn I can and I'm doing it but it would be easier and clear not using it :)

@falemagn
Copy link

Well, I beg to differ. It seems easier to directly use the types you need and not allocate any memory on the heap, rather than keeping a list of enums and allocate heap. But ok.

@Sarna555
Copy link
Author

I understand your point, but there are different cases not just this one and sometimes you don't have a comfort to refactor whole code base to not use enum and sometimes it's just convenient to use enum.

@Neargye Neargye added help wanted Extra attention is needed and removed enhancement New feature or request labels May 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants