Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2002-08-29 04:32:29


Hello,
Yesterday evening I created my own any class. Like boost::any it has
abstract placeholder class:
  struct placeholder
  {
    virtual ~placeholder() {}
    virtual placeholder * clone(dont_use) const = 0;
    virtual const std::type_info & type(dont_use) const = 0;
  };

But holder class template is different. It is derived both from placeholder
and the type it should store:
  template<typename T>
  struct holder : placeholder, T
  {
    holder(const T & val) : T(val) {}
    holder(const holder & other) : T(other) {}
    ~holder() {}
    holder * clone(dont_use) const { return new holder(*this); }
    const std::type_info & type(dont_use) const { return typeid(T); }
};

To store builtin types I use special wrapper class.
So, this any is more flexible because dynamic_cast can be used to cast from
placeholder to T even if T is not polymorphic:
  struct A {};
  struct B : A {};
  placeholder * p = new holder<B>(B());
  A * a = dynamic_cast<A *>(p);
  assert(a);

Implementation of any_cast operations is quite simple. They just redirect to
dynamic_cast. This code shouldn't throw:
  any b = B();
  A & a = any_cast<A &>(b);

Download code from
http://prdownloads.sourceforge.net/cpp-experiment/any-1-0-beta.tar.gz?download
it has a little difference with code snipset: there is no dont_use argument.
I just forgot that without this argument user types can be affected :)

Visitation support can be easily added to my any class without ever
affecting it. It can be done for example in the same way as Andrei
Alexandrescu did in his AdHocVisitor:
http://www.cuj.com/experts/2002/alexandr.htm?topic=experts
But his code cannot detect ambigious visitation. It will visit first
suitable type. Even if types are sorted from derived to bases.
I have some ideas how to implement more accurate visitation. Assume that you
have visitor<L>, where L is a list of visited types and you would like to
visit some any:
  template<class L>
  void visit(any & val, visitor<L> & v);

To start visitation you should first select list of classes that are not
derived from any other class in L. Let's call them leaf classes.
Second, you should make any_cast from &val to pointer to every leaf class.
  T * p = any_cast<T *>(&val); // T is a leaf class

If only one pointer among these is non-zero then visit and exit:
  v.visit(*p);

If more then one pointer is non-zero then
  throw ambigious_visit();

And finally, if all pointers are zero then remove these leaf classes from L
and apply this rule reqursively if L is non empty. If it is empty then
  throw no_visit();

Any interest in integrating my ideas/code into the boost?

--
Best regards,
Alexander Nasonov
e-mail account: alnsn
e-mail server:  mail.ru

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