Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2002-11-25 11:26:13


Remy Blank wrote:

> Hello Boosters,
>
> I am trying to use dynamic_any to store either objects or pointers to
> (polymorphic) objects.

You can extract a base (or a reference to base) for non-polymorphic type as
well.

>
> I am able to extract a pointer to the base class of a contained object:
>
> class B { };
>
> class D: public B { };
>
> void Test()
> {
> any d(D());
>
> B* pb = extract<B>(&d);
> }
>
> This is alread quite useful. However the following code does not work:
>
> void Test2()
> {
> D d;
> any pd(&d);
>
> B* pb = extract<B*>(pd); // pb = 0
>
> char c;
> any AnyChar(c);
>
> int i = extract<int>(AnyChar); // bad_extract
> }

This is how dynamic_any designed. You are allowed to extract (a) exact type
or (b) unambiguous base class. It's possible without introducing complex
inheritance-relationship framework (but with multiply inheritance which can
decrease performance).
I think, many classes can be stored as values, not pointers. Firsrt, it
simplifies life-time management. You don't need to care about calling
operator delete. Second, there are many different smart pointers that
should be supported as well. It means that some policies should be designed
and it will complicate the library.
After all, you can extract a reference and modify stored value inplace. As a
result you can copy only once: at creation time.

> So I have to know the exact type of the contained object and cannot
> rely on implicit conversions (D* -> B* or char -> int) to work.
> This is quite understandable from the fact that any wraps non-class
> types into unrelated classes.
>
> Now my question: is there a way to make these implicit conversions work?
>
> My best answer at the moment: explicitly register conversion functions
> from one type to the other in a map<pair<type_info const&, type_info
> const&>, void* (*)(void*)> and look up the right function based on the
> type contained and the type requested.
>
> But there has to be a better way, hasn't it?
>
> Best regards.
> --Remy

You can create your own framework for dynamic_any using
dynamic_any::function. In a combination with simple and typesafe interface
it could make great library. Basic idea is here:

namespace your_framework
{
  // ...
  namespace detail
  {
    // ...
    struct raw_convert
      : boost::dynamic_any::function
        <
          convert,
          void * (boost::dynamic_any::arg &)
>
    {
      raw_convert(const std::type_info & convert_to);

      template<typename T>
      void * call(T & content)
      {
        const std::type_info & convert_from = typeid(T);
        convert_function fun =
          lookup_convert_function(convert_from, convert_to_);
        return fun(&content);
      }
      // ...
    };

  } // namespace detail

  typedef boost::dynamic_any::any<
    boost::mpl::list<detail::raw_convert>
> any;

  template<typename T>
  T extract(any & a)
  {
    const std::type_info & convert_to = typeid(T):
    void * raw_ptr = detail::raw_convert(convert_to)(a);
    // ... (various checks)
    T * ptr = (T *) raw_ptr;
    return *ptr;
  }

}

Best regards,
Alexander Nasonov
mailbox: alnsn
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