Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-10-20 05:39:49


On Sun, Oct 19, 2003 at 05:27:24PM -0700, Eric Friedman wrote:
> This is something I had been working on about two months ago but didn't
> post to the sandbox until recently.

This looks potentially cool, but I don't quite understand it.

> The basic idea is this:
>
> switch_( [variant] )
> |= case_< [pattern1] >(...)
> |= case_< [pattern2] >(...)
> :::
> |= default_(...) // optional catch-all
> ;
>
> The switch_ will fail to compile if not every case is handled. In terms

Given the general form of patterns you describe below, I can't possibly
imagine how you determine if every case is handled, but for now I'll
take your word for it. :)

> of handling, the case_ constructors take typical function objects,
> though the switch_ ignores any return values.

Why ignore return values? If all cases had the same return type (or
returns types convertible to one fixed type), could you make the whole
thing an expression? Like

   int x = switch_( [variant] ) // or maybe switch_<int>( [variant] )
            |= case_< [pattern1] >(...)
            |= case_< [pattern2] >(...)
            :::
            |= default_(...) // optional catch-all
            ;

(The alternate syntax in the comment suggests that you pass the intended
return type of the whole expression as an argument to switch_, rather
than try to infer it from all the case arms.)

> An example usage is the following (though I have again left out the
> function objects that need to be passed to the case_ constructors):
>
> using namespace boost::type_switch;
>
> variant<
> int
> , pair<int,double>
> , pair<int,int>
> , pair<double,int>
> > var;
>
> switch_(var)
> |= case_< pair<_1,_1> >(...) // matches pair<int,int>
> |= case_< pair<int,_> >(...) // matches pair<int,*>
> |= case_< pair<_,_> >(...) // matches pair<*,*>
> |= case_< int >(...)
> ;

So to make sure I understand, inside the ellipsis here:

   |= case_< pair<_1,_1> >(...) // matches pair<int,int>

I'd put a function object that knows how to accept pairs and do
something? Like "pp" in

   struct PairPrinter {
      template <class T, class U>
      void operator()( pair<T,U> p ) const {
         cout << p.first << p.second << endl;
      }
   } pp;

that code?

> The pattern matching is implemented in terms of lambda_match, which I
> have also added to the sandbox (to boost/mpl). Notably, lambda_match
> leverages the MPL lambda workarounds for deficient compilers, extending
> the applicability of type_switch somewhat.

Does the pattern matching only know about a fixed set of types (like
pair)? Or does it work on any template?

-- 
-Brian McNamara (lorgon_at_[hidden])

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