|
Boost : |
From: Eric Friedman (ebf_at_[hidden])
Date: 2003-09-19 15:28:47
Boosters,
In the past several weeks, I've worked on "finishing" the interface and
implementation of boost::variant. Before spending significant effort on
updating the documentation to reflect these changes, I'd like to first
ensure everyone is satisfied with the current state of the library.
--- Interface: 1) Simple recursive variant types are now easily generated. For example, typedef boost::recursive_variant< int , std::vector< boost::recursive_variant_ > >::type my_recursive_variant; Of course, "manual" recursive variants may be generated using recursive_wrapper (originally boost::incomplete). That is, struct my; typedef boost::variant< int , boost::recursive_wrapper<my> > my_recursive_variant; struct my { my_recursive_variant var; // ... }; 2) Reference content is now fully supported, including support for inheritance hierarchies. That is, Derived d; boost::variant<Base&> b(d); assert( boost::get<Base>(&b) == &d ); will work as indicated, and will not slice d. --- Implementation: The "controversial" double storage technique is now disabled if the first bounded type is nothrow default-constructible (as detected by has_nothrow_constructor). For example, boost::variant<boost::empty, ...> will never use double storage. In the event of the failure of an operation, the first bounded type will be default constructed, leaving variant with a meaningful state. Thus operations on variant always guarantee at least the basic guarantee. For now, I think the double storage implementation should remain, with the above ability to disable it. Further, if every bounded type of variant is nothrow copy-constructible, the double storage technique will similarly be disabled. In the advent of a Boost.Move library, this will be extended as well to all types that are nothrow "move-constructible." Thus, I have not adopted David Abrahams's proposal to use dynamic allocation to generally ensure variant's basic guarantee (instead of double storage), as described in http://aspn.activestate.com/ASPN/Mail/Message/1789195. I'm a bit wary of this approach, as it complicates variant's exception specifications (operations may now throw std::bad_alloc), and while it eliminates the space inefficiency of double storage, it introduces the many inefficiencies associated with dynamic allocation. In short, it is not clear to me that such an approach is in fact "better" (or worse) than the current approach. I'd appreciate feedback on any of this. Thanks, Eric
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk