Boost logo

Boost :

Subject: Re: [boost] [Boost.Variant] Parameterized Visitors
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-01-12 21:41:54


AMDG

On 01/12/2012 04:30 PM, Andy Jost wrote:
> New poster.
>
> When I'm using Boost.Variant, I often want to pass additional parameters to a visitor. A common case is when the variant is a class member and I want to have access to other members (or even "this") in the visitor.
>
> I muddled through for a long time writing visitors with explicit constructors and data members to take whichever parameters I needed, but I finally got around to making this generic with Boost.Fusion and I love it. I'm wondering whether I should submit this for consideration as an addition to the Boost.Variant library and how.
>
> First a few questions:
>
> 1. Is there already an equivalent solution that I should be aware of?
>

bind<result_type>(my_visitor1(), 1, 3.14, 'k', _1)?

> 2. Should this be considered for an addition to Boost?
>
> 3. If so, how do I begin the review process?
>
> 4. This is a small change (400 or so lines of code). Is there anyone willing to help with the logistics, testing, and/or documentation (perhaps in exchange for a credit in the docs)?
>
> Here's an example, which should be fairly self-explanatory:
>
> struct A {}; struct B {}; struct C {};
>
> struct my_visitor1 : param_visitor<my_visitor1, bool>
> {
> result_type operator()(int, float, char, A) const {...}
> result_type operator()(int, float, char, B) const {...}
> result_type operator()(int, float, char, C) const {...}
> };
>
> struct my_visitor2 : fused_param_visitor<my_visitor2, bool>
> {
> template<typename Sequence>
> result_type operator()(Sequence const &, A) const {...}
> ...
> };
>
> int main()
> {
> boost::variant<A,B,C> abc;
> boost::apply_visitor(my_visitor1().tie(1, 3.14, 'k'), abc);
> boost::apply_visitor(my_visitor2().tie(1, 3.14, 'k'), abc);
> return 0;
> }
>
> In terms of technical detail, there's not much to it. The base classes provide tie() and load() methods to take arguments by reference or value, respectively. A call to one of those returns a helper object that contains a copy of the derived visitor and a fusion::vector of arguments. Visiting that causes the user-defined visitor to be called with all of the arguments. For parameter forwarding, I use an implementation of perfect forwarding based on boost/flyweight/detail/dyn_perfect_fwd.hpp (I used a default limit of 4 parameters).
>

In Christ,
Steven Watanabe


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk