runtime versions of indexed access functions
mdimura opened this issue · 3 comments
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?
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.
This looks like a good idea, I agree that we should have something like this as part of visit_struct
.
Will write again soon