Boost logo

Boost :

From: Peter Petrov (piettropro_at_[hidden])
Date: 2002-11-25 10:21:37


Hi,

The boost::any type is currently limited because it's impossible to be used
as the key type in a map or a hash_map for example. It is obvious that
adding comparison operators to boost::any is unnacceptable, because that
would require all value types to also have these operators defined.

However, it is possible to derive classes from boost::any which support
comparison. They will not interfere with the base class, but for the most
effective implementation, it will be required to make some members of
boost::any protected instead of private.

Let's start with a definition of how I understand the term "comparison of
any":

Equality comparison:
  (comparable_any(A) == comparable_any(B))
if and only if
  (typeid(A) == typeid(B)) && (A == B)

LessThan comparison:
  (ordered_any(A) < ordered_any(B))
if and only if
  (typeid(A).before(typeid(B))) || ((typeid(A) == typeid(B)) && (A < B))

My proposal is to derive the class boost::comparable_any from boost::any,
and boost::ordered_any from boost::comparable_any. The class
boost::comparable_any will add operator== and operator!=, and the class
boost::ordered_any will add operator<, operator>, operator<= and operator>=.
The rule is respected that comparable_any is an any, and that ordered_any is
a comparable_any.

This way, boost::ordered_any will be usable as a key type in maps and
hash_maps, as well as in sets and hash_sets. Although not suitable for this
task, the class boost::comparable_any will still be useful in certain
situations.

Regarding the implementation. Pretty straightforward, but if efficiency is a
priority, then the currently private members of boost::any will have to be
changed to protected. Given this, the inner class boost::any::placeholder
will be derived in the inheritors to provide the relevant virtual functions
or operators for comparison. And the member variable "content" will actually
point to an instance of these derived classes. This will require some
static_casting in the implementations of comparable_any and ordered_any, and
that's normal. Also, the clone() method will keep its semantics to return a
normal placeholder. The derived classes will have comparable_clone() and
ordered_clone() which will return the appropriate derivative of placeholder.

If the change from private to protected is not acceptable, the virtual
functions for comparison will have to be provided by another member
variable. But besides wasting memory, doing so will also require that the
destructor of boost::any is made virtual to ensure proper cleanup.

Please share your thoughts on the subject.

Best regards,
Peter


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