Open akrzemi1 opened 8 years ago
Here is how your broader mutating example from https://github.com/akrzemi1/__sandbox__/blob/master/mach7_with_variant.md can be written in Mach7 in the way typically done in other languages:
struct TankA { int va = 0; };
struct TankB { int vb = 0; };
struct TankX { };
using Tank = boost::variant<TankA, TankB, TankX>;
namespace mch ///< Mach7 library namespace
{
template <> struct bindings<TankA> { Members(TankA::va); };
template <> struct bindings<TankB> { Members(TankB::vb); };
} // of namespace mch
int read(Tank const& tank)
{
using namespace mch;
var<const int&> v; // You create a reference to bind to a subcomponent
Match(tank)
{
Case(C<TankA>(v)) return v; // Once bound, you simply use it in the RHS
Case(C<TankB>(v)) return v + 10;
Case(C<TankX>()) return -1;
}
EndMatch
}
int write(Tank& tank)
{
using namespace mch;
var<int&> v;
Match(tank)
{
Case(C<TankA>(v)) v = 1; return v; // NOTE: You can also modify value bound via reference to a subcomponent
Case(C<TankB>(v)) v = 42; return 0;
Case(C<TankX>()) return -1;
}
EndMatch
}
int main()
{
Tank t = TankB();
assert (read(t) == 10);
write(t);
TankB* ptb = boost::get<TankB>(&t);
assert(ptb && ptb->vb == 42);
}
Thank you. That is quite interesting, and I start to see the expressiveness of the library. But let me change the problem a bit. Suppose all members of my types are private, and can only be accessed via public member functions. See "Challenge 2" in the same file: https://github.com/akrzemi1/__sandbox__/blob/master/mach7_with_variant.md
Whoa! I have just realized you can teach it to recognize member functions (getters). Impressive!
Yes, Members() macro accepts data members, nullary member functions and unary free-standing functions with the argument taking class as an argument. An example of the latter can be seen here:
https://github.com/solodon4/Mach7/blob/master/code/test/unit/example05.cpp#L67-L69
I am using the library to switch on
boost::variant
and inspect/modify a given sub-type, as per the example below.This doesn't work, because (to my knowedge) there is no way to get access to a mutable
A
from an instance ofvar<A&>
.Would it be possible to extend the interface of
mch::var
to get mutating access to its contained value?