Boost logo

Boost :

From: Eric Friedman (ebf_at_[hidden])
Date: 2002-07-01 01:21:11


Drawing upon input from the Boost community, I've completely rewritten
my variant class (though, yes, Andrei, it is still inspired by your
original idea -- formal credit will come in documentation).

The current headers and test file are available at (which includes
some MPL patches and additions -- mpl::sort (!) -- I have made):

  http://groups.yahoo.com/group/boost/files/variant-20020701.zip

I still have a number of items on my todo list (namely conversion
from value types outside bounds and from foreign variant types),
but I wanted to get an update out for peer review before I dug myself
too deep.

Disclaimer: the test code currently breaks on GCC, but it compiles
under MSVC 7.0 without problem (and may on other compilers, too).
I'm working on getting the code to function again under GCC.

I welcome any and all feedback on the rewrite.

---
Overview:
* Generic visitation by any functionable object.
  This is *very* powerful; nearly all of variant's internal features
  are implemented in terms of generic (templated) visitation.
  For example:
    struct displayer {
      template <typename T>
      void operator()(const T& operand)
      { std::cout << operand << '\n'; }
    };
    void f()
    {
      boost::variant<...> var;
      var.visit_with(displayer());
      // Lambda support!
      var.visit_with(std::cout << _1 << '\n');
    }
* Typeswitch facility (idea courtesy Douglas Gregor).
  This, like visitation, is very powerful (and nicer syntactically).
  As well, support for a switch on variant is not hard-coded; 
  the facility simply invokes the free-method:
    switch_on(operand, cases);
  where operand is the value provided to switch_ and cases is a 
  function object generated by the case_<T>(f) | case_<U>(g) | ...
  mechanism.
  For example:
    using namespace boost::type_switch;
    switch_(var)[
        case_<int>(&handle_int) // function pointer
      | case_<double>(handle_double()) // function object
      | template_(displayer()) // generic, "catch-all" case
//    | default_(F) is also available as a no-argument "catch-all"
      ];
* variant_cast.
  Mirrors functionality of any_cast.
* Small space overhead:
    sizeof(variant) ==
        sizeof(int) // no more vptr (idea courtesy Douglas Gregor)
      + max_sizeof<bounded_types>
* Supports incomplete (and thus recursive) types (idea courtesy
  Itay Maman).
* Fully exception-safe (inspiration from Itay Maman) with initial
  optimatizations for variant::swap.
---
Eric Friedman

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