there used to be a variant adapter for fusion sequences, but it has
been rightfully removed:
on Wed Dec 19 2007, Joel de Guzman <joel-AT-boost-consulting.com> wrote:
> I intend to remove the variant adapter from fusion. After thorough
> investigation, I think now that the move to make variant a
> fusion sequence is rather quirky. A variant will always
> have a size==1 regardless of the number of types it can contain
> and there's no way to know at compile time what it contains.
> Iterating over its types is simply wrong. All these imply that
> the variant is *not* a fusion sequence.
Let's say I have a recursive variant and would like to flatten the
variant to create some sort of heterogeneous sequence from it.
Particularly, I would like to chop the variant into multiple disjunct
Fusion sequences, each of which are handed to generic component that
operates with Fusion sequences. The above suggests that Fusion is not
the right tool. What would be a better approach to handle this problem?
Should I split the variant into smaller variants instead? What made
Fusion so attractive is the notion of tiers, i.e., light-weight views of
references to the actual data. Is there a variant equivalent of tiers?
Matthias
--
Matthias Vallentin
vall...@icsi.berkeley.edu
http://www.icir.org/matthias
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Matthias Vallentin wrote:
> there used to be a variant adapter for fusion sequences, but it has
> been rightfully removed:
>
> on Wed Dec 19 2007, Joel de Guzman <joel-AT-boost-consulting.com> wrote:
>
>> I intend to remove the variant adapter from fusion. After thorough
>> investigation, I think now that the move to make variant a
>> fusion sequence is rather quirky. A variant will always
>> have a size==1 regardless of the number of types it can contain
>> and there's no way to know at compile time what it contains.
>> Iterating over its types is simply wrong. All these imply that
>> the variant is *not* a fusion sequence.
>>
>
> Let's say I have a recursive variant and would like to flatten the
> variant to create some sort of heterogeneous sequence from it.
> Particularly, I would like to chop the variant into multiple disjunct
> Fusion sequences, each of which are handed to generic component that
> operates with Fusion sequences. The above suggests that Fusion is not
> the right tool. What would be a better approach to handle this problem?
>
> Should I split the variant into smaller variants instead? What made
> Fusion so attractive is the notion of tiers, i.e., light-weight views of
> references to the actual data. Is there a variant equivalent of tiers?
>
I'm not sure that I really understand what
you want. Can you give an example of the kind
of recursive variant and the sequence(s) that you
want to get out of it? In particular how are the
runtime values of the elements of the sequence
to be determined?
Depending on what you're doing, you might
be able to use the nested types typedef of
variant, which is an MPL sequence.
In Christ,
Steven Watanabe
Let this be the variant type
typedef boost::make_recursive_variant<
int,
double,
std::vector<boost::recursive_variant_>
>::type variant;
and this an instance of it
std::vector<variant> vec;
vec.push_back(42);
vec.push_back(4.2);
vec.push_back(vec);
variant v = vec;
> In particular how are the runtime values of the elements of the
> sequence to be determined?
Conceptually, I am thinking of a visitor that goes over the variant and
flattens it. In the above example, the corresponding sequence would be
[42, 4.2, 42, 4.2]
which corresponds to a fusion::vector<int, double, int, double>.
Practically, I don't see a way how to get the type of the vector at
runtime unless knowing in advance the type of the fusion vector (which
could be a potential assumption).
I was also talking about "chopping" the variant in disjunct sequences.
By this, I mean that a visitor goes over the variant and creates several
sequences, say
[42]
[4.2, 42]
[42]
for the above example. That's the scenario I ultimately target. Ideally,
these sequences are only views (tiers) of the original variant.
> Depending on what you're doing, you might be able to use the nested
> types typedef of variant, which is an MPL sequence.
Are you referring to the variant<T>::types MPL sequence?
Matthias
--
Matthias Vallentin
vall...@icsi.berkeley.edu
http://www.icir.org/matthias
Matthias Vallentin wrote:
>> In particular how are the runtime values of the elements of the
>> sequence to be determined?
>>
>
> Conceptually, I am thinking of a visitor that goes over the variant and
> flattens it. In the above example, the corresponding sequence would be
>
> [42, 4.2, 42, 4.2]
>
> which corresponds to a fusion::vector<int, double, int, double>.
> Practically, I don't see a way how to get the type of the vector at
> runtime unless knowing in advance the type of the fusion vector (which
> could be a potential assumption).
>
You have to know the type of the vector at compile time.
> I was also talking about "chopping" the variant in disjunct sequences.
> By this, I mean that a visitor goes over the variant and creates several
> sequences, say
>
> [42]
> [4.2, 42]
> [42]
>
I think the easiest way is probably to create a runtime
iterator that walks over the vector and recurses into
any variants that it contains. Then you can use fusion's
algorithms to iterate over the fusion::vector and the
vector in parallel.
> for the above example. That's the scenario I ultimately target. Ideally,
> these sequences are only views (tiers) of the original variant.
>
If you want it to be a view, you can use a fusion vector of references.
>> Depending on what you're doing, you might be able to use the nested
>> types typedef of variant, which is an MPL sequence.
>>
>
> Are you referring to the variant<T>::types MPL sequence?
>
Yes.
In Christ,
Steven Watanabe
Even if I know the type of the vector at compile time, how could I
create the fusion vector incrementally from the variant? Since push_back
always returns a new type, I don't know how to do this with a visitor.
> >I was also talking about "chopping" the variant in disjunct sequences.
> >By this, I mean that a visitor goes over the variant and creates several
> >sequences, say
> >
> > [42]
> > [4.2, 42]
> > [42]
>
> I think the easiest way is probably to create a runtime
> iterator that walks over the vector and recurses into
> any variants that it contains.
>
> Then you can use fusion's
> algorithms to iterate over the fusion::vector and the
> vector in parallel.
I'm not sure if I can follow. If I start with the variant and have some
plan to partition it into sequences, how would I use an iterator rather
a visitor? Would you mind illustrating your idea with a small code
snippet?
Matthias
--
Matthias Vallentin
vall...@icsi.berkeley.edu
http://www.icir.org/matthias
Matthias Vallentin wrote:
>> I think the easiest way is probably to create a runtime
>> iterator that walks over the vector and recurses into
>> any variants that it contains.
>>
>> Then you can use fusion's
>> algorithms to iterate over the fusion::vector and the
>> vector in parallel.
>>
>
> I'm not sure if I can follow. If I start with the variant and have some
> plan to partition it into sequences, how would I use an iterator rather
> a visitor? Would you mind illustrating your idea with a small code
> snippet?
>
Actually making an iterator is rather a pain. It's probably easiest to copy
the variant into a flattened vector like this.
#include <boost/variant.hpp>
#include <vector>
#include <algorithm>
template<class Iter>
class visitor {
public:
typedef void result_type;
visitor(Iter& iter) : out(&iter) {}
template<class T>
void operator()(T& t) const {
*(*out)++ = &t;
}
template<class T>
void operator()(std::vector<T>& v) const {
std::for_each(v.begin(), v.end(), boost::apply_visitor(*this));
}
Iter* out;
};
template<class V, class Iter>
Iter flatten_variant(V& v, Iter out) {
boost::apply_visitor(visitor<Iter>(out), v);
return out;
}
int main() {
boost::make_recursive_variant<
int,
double,
std::vector<boost::recursive_variant_>
>::type v;
std::vector<boost::variant<int*, double*> > temp;
flatten_variant(v, std::back_inserter(temp));
}
In Christ,
Steven Watanabe
I like this solution, thanks.
Matthias
--
Matthias Vallentin
vall...@icsi.berkeley.edu
http://www.icir.org/matthias