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

runtime versions of indexed access functions #11

Open
mdimura opened this issue Apr 12, 2018 · 3 comments
Open

runtime versions of indexed access functions #11

mdimura opened this issue Apr 12, 2018 · 3 comments

Comments

@mdimura
Copy link

mdimura commented Apr 12, 2018

It may be sometimes useful to have also runtime reflection. So I came up with some wrappers in GUI object properties editor code, like these:

#include "visit_struct/visit_struct.hpp"
#include <iostream>
#include <variant>
#include <string>

struct S {
    int n;
    float f;
    char c;
};
VISITABLE_STRUCT(S, n, f, c);

using var_type=std::variant<int,float,char>;

template<std::size_t I = 0, typename FuncT,typename T>
inline typename std::enable_if<I == visit_struct::field_count<T>(), void>::type
for_index(int, T&, FuncT)
{ }

template<std::size_t I = 0, typename FuncT,typename T>
inline typename std::enable_if<I < visit_struct::field_count<T>(), void>::type
for_index(int index, T& t, FuncT f)
{
    if (index == 0) f(visit_struct::get<I>(t));
    for_index<I + 1, FuncT>(index-1, t, f);
}

template<typename T>
var_type get_variant(const T& t,int i)
{
    var_type var;
    for_index(i,t,[&var](auto&& v) {
        var=v;
    });
    return var;
}

template<typename T>
void set_field(T& t, const var_type& var, int i)
{
    for_index(i,t,[&i,&var](auto&& prop) {
        std::visit([&prop](auto&& v) {
            prop=v;
        },var);
    });
}

int main()
{
    S s{42,3.14,'Z'};
    auto printer=[](auto&& v) {
        std::cout<<v<<'\n';
    };
    var_type var;
    var=get_variant(s,2);
    std::visit(printer,var);

    var=2.718f;
    set_field(s,var,1);
    var=get_variant(s,1);
    std::visit(printer,var);
    return 0;
}

It is far from complete and is probably not the best way to implement it, but shows the idea. Would it be useful to have similar wrappers as a part of visit_struct?

@cbeck88
Copy link
Owner

cbeck88 commented Apr 13, 2018

One issue is, std::variant is C++17, while visit_struct targets C++11.

Another issue is, lots of projects use lots of different variants, for example, std::variant is not strongly exception-safe so it isn't appropriate in many cases.

You could side-step that to some extent I suppose if you make it a variant containing references to the value actually contained in the struct instead of copies of those values?

I agree that this would be useful functionality, although it would expand the scope of visit_struct significantly. I'll write again with more thoughts.

@mdimura
Copy link
Author

mdimura commented Apr 14, 2018

Based on your examples, I've put together a minimum functional set of wrappers.

@cbeck88
Copy link
Owner

cbeck88 commented Apr 17, 2018

This looks like a good idea, I agree that we should have something like this as part of visit_struct.
Will write again soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants