Ah move semantics, it always crops up every now and then...
Ok, here's a small challenge. In Spirit-2, all nodes have
attributes. The attribute can be generated (synthesized)
by a node, or the user can pass in her own attribute. The
attribute passed in does not have to exactly match the
type of the expected node attribute as long as they are
compatible. What is compatible? For example, if the node
attribute is a vector<char>, a string<char> should be
compatible. The (current) generic procedure is as follows:
1) create an empty (default-constructed) attribute of the
type expected by the node.
2) assign it to the attribute passed in by the client.
Why can't we just pass the attribute passed in as-is?
In certain occasions, we can't. Our only requirement
is that the actual attribute is Assignable to the passed
in attribute. For example, if the expected attribute is
an int, then you can pass a variant<int>. The int is
assignable to the variant. However, the int parser will
go crazy trying to do arithmetic on a variant<int>.
Now... for simple primitives, the procedure above is ok.
It becomes problematic though, once we have more complex
attributes like std containers, tuples, and variations
thereof. Here are the principal actors in this game:
So... In step 2 above, we don't care about the source object.
We want to 'move' the source of type T to the destination
of type U as cheaply as possible. Aha! move! The tricky part
though is that the source and destination do not have to
be of the same type. Again, the requirement is that they only
need to be compatible. So, how do we define "compatible"?
* If Src can be assigned to Dest
* If Src and Dest are fusion sequences with the same size and
with compatible elements.
* If Src and Dest are stl containers with compatible elements.
* If Dest is a variant with an element that is compatible
with Src, or vice-versa.
* If Dest is an optional with a type that is compatible
with Src, or vice-versa.
Obviously, if Src and Dest has the same types, then it's easier.
For example, if Src and Dest are std::vector<int>, a simple
strategy would be to simply swap the vectors.
Ok, so... any takers for this simple (ahem!) problem? :-)
The challenge is to make it as efficient as possible for the
types listed above.
(I'll really need this as soon as possible, so I might be
writing the code myself. I needed to document the problem
anyway, so I wrote this in the guise of a challenge, in the
hope that maybe someone might be interested :-) )