Boost logo

Boost :

Subject: Re: [boost] boost::optional<A,B,...>
From: Larry Evans (cppljevans_at_[hidden])
Date: 2010-03-04 08:06:20


On 03/03/10 23:48, Daniel Larimer wrote:
> I have a situation where I have a class that stores two mutually exclusive optional values. This results in double overhead of two bools and twice the "reserved" space. I could opt for a boost::optional<boost::variant<A,B> >, but this would incur extra costs associated with the implementation of boost::variant. Considering the fact that boost::variant<> explicitly guarantees to be always "valid", it seems like it would be reasonable to have boost::optional<A,...> that behaves like boost::variant<>, yet is optimized specifically for allowing "empty" states as well.
>
> The boolean could then become the type index where 0 is empty, 1 is A, 2 is B etc.
>
>

http://www.boostpro.com/vault/index.php?&directory=Data%20Structures

contains composite_tagged_seq.zip which contains a template,
composite_tagged_seq, which can be used as follows to satisfy
your requirements:

   using namespace boost::composite_tags;
   using namespace boost::mpl;
       typedef
     composite_tagged_seq
     < one_of_maybe
     , integral_c<int,1>
     , vector<A,B>
>
   a_or_b_maybe_t;
     a_or_b_maybe_t
   a_or_b_maybe_v;
   BOOST_ASSERT(( a_or_b_maybe_v.which() == 0 ));
   a_or_b_maybe_v.inject<1>(A());
   BOOST_ASSERT(( a_or_b_maybe_v.which() == 1 ));
   A* a_ptr=a_or_b_maybe.project<1>();
   BOOST_ASSERT(( a__ptr ));
   B* b_ptr=a_or_b_maybe.project<2>();
   BOOST_ASSERT(( !b__ptr ));

Of course one problem with this compared with variant<unused,A,B> is
that it requires:

   1) the extra template parameters, one_of_maybe and integral_c.
   2) the more verbose inject<1>(A()) instead of directly assigning
      from A().
   3) the more verbose project<1>() instead of directly assigning
      to an A *and* checking the nullness of the result.

OTOH, one advantage is that A and B can be the same type. This may not
be useful in your case; however, it more closely reflects
a disjoint union:

   http://en.wikipedia.org/wiki/Disjoint_union

which is useful in representing the output of a lexical
analyzer. For example, each keyword in a language would
have an unused type and the lexical analyzer only needs
to indicate which keyword (i.e. the value of the
"type index", in your words) was found.

HTH.

-regards,
Larry


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