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

Loop over types in the variant? #213

Closed
Yurlungur opened this issue Dec 21, 2022 · 4 comments · Fixed by #311
Closed

Loop over types in the variant? #213

Yurlungur opened this issue Dec 21, 2022 · 4 comments · Fixed by #311
Labels
discussion enhancement New feature or request help wanted Extra attention is needed

Comments

@Yurlungur
Copy link
Collaborator

I wonder if it's possible to achieve vectorization (for the EOS's that vectorize) for the scalar calls by looping over EOS type in the variant first. I bet this kind of loop construct can be done at compile time. Not sure this is a priority but I wanted to write the idea down somewhere. Would also like to pick your brain @dholladay00 .

@Yurlungur Yurlungur added enhancement New feature or request help wanted Extra attention is needed discussion labels Dec 21, 2022
@dholladay00
Copy link
Collaborator

@Yurlungur this might be a good place to stash that code you had put in our Mattermost convo as well.

@Yurlungur
Copy link
Collaborator Author

👍 good idea @dholladay00 . Something like this allows us to loop over EOS type. I had it in mind for the rewrite of the EOS builder #28 .

#include <iostream>
#include <string>
#include <variant>
#include <type_traits>
#include <tuple>

template <typename... Ts>
struct type_list {};

template <typename... Ts>
struct tl_to_Variant_struct {
  using vt = std::variant<Ts...>;
};

template <typename... Ts>
constexpr auto tl_to_variant(type_list<Ts...>) {
  return tl_to_Variant_struct<Ts...>{};
}

template<typename T, typename... Ts>
constexpr bool contains(){ 
    return std::disjunction_v<std::is_same<T, Ts>...>; 
}

struct Foo {};
struct Bar {};

template<typename T>
struct Mod {
    Mod(T t) {};
};

static constexpr const auto base_list = type_list<Foo, Bar>{};
static constexpr const auto mod_list = type_list<Foo, Bar, Mod<Foo>, Mod<Bar>>{};

using Var_t = typename decltype(tl_to_variant(mod_list))::vt;

template<typename Variant, template <class...> typename T>
Variant Modify(Variant var) {
    return var;
}

template<typename Variant, template <class...> typename T, typename U, typename... Rest>
Variant Modify(Variant var) {
    if (std::holds_alternative<U>(var)) {
        return Variant(T<U>(std::get<U>(var)));
    } else {
        return Modify<Variant,T,Rest...>(var);
    }
}

int main() {
    Var_t f = Foo();
    auto m = Modify<Var_t, Mod, Foo, Bar>(f);
    return 0;
}

@jhp-lanl
Copy link
Collaborator

Interesting... this does look a lot more extensible than the EOS builder machinery

@Yurlungur
Copy link
Collaborator Author

I haven't worked out all the kinks yet, but I think it should let us write code like this (I hope):

EOS my_eos = IdealGas();
if (shifted) {
  my_eos = Modify<Shifted, ... >(my_eos, shift);
}
if (scaled) {
  my_eos = Modify<Scaled,...>(my_eos, scale);
}
// etc

@Yurlungur Yurlungur linked a pull request Oct 13, 2023 that will close this issue
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants