The Artima Developer Community
Sponsored Link

Weblogs Forum
boost::any meet ootl::any_ptr

1 reply on 1 page. Most recent reply: Jan 5, 2007 10:14 AM by Art Asano

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 1 reply on 1 page
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

boost::any meet ootl::any_ptr (View in Weblogs)
Posted: May 13, 2005 7:24 AM
Reply to this message Reply
Summary
The boost::any type is a very important type in that it can hold any object which has a copy-constructor. However if you don't want to hold a copy of the value you can instead refer to the object using the ootl::any_ptr type.
Advertisement
My ootl::any_ptr class can point to any object with a copy-constructor, and provides the following public functions:
  void Delete();
  any_ptr Clone() const;
  const type_info& GetType();
  template<typename ValueType> ValueType* PtrCast();
The implementation is below:
  // this class can point to any copy-constructible value_type
  // and let you clone or delete it safely
  class any_ptr
  {
  public:
    // forward declarations
    template <class T>
    struct functions;


    template <class T>
    any_ptr(T* x)
      : m_a(x), m_t(&functions<T>::table)
    {}

    any_ptr()
      : m_a(NULL), m_t(NULL)
    {}

    void Delete() {
      assert(m_a != NULL);
      m_t->Delete(m_a);
      m_a = NULL;
    }
    any_ptr Clone() const {
      any_ptr o(*this);
      o.m_a = m_t->Clone(m_a);
      return o;
    }
    const std::type_info& GetType() const {
      return m_t->GetType(m_a);
    }
    template<typename ValueType>
    ValueType* PtrCast() {
      if (!(typeid(ValueType) == GetType())) {
        throw BadObjectCast();
      }
      return static_cast<ValueType*>(m_a);
    }

    // Function table type
    // order is important, must match all other lists of functions
    struct table {
      void (*Delete)(void*);
      const std::type_info& (*GetType)(void*);
      void* (*Clone)(void*);
    };

    // For a given referenced type T, generates functions for the
    // function table and a static instance of the table.
    template<class T>
    struct functions
    {
      static typename any_ptr::table table;
      static void Delete(void* p) {
        delete static_cast<T*>(p);
      }
      static const std::type_info& GetType(void* p) {
        return typeid(T);
      }
      static void* Clone(void* p) {
        return new T(*static_cast<T*>(p));
      }
    };
  private:
    void* m_a;
    table* m_t;
  };

  template<class T>
  typename any_ptr::table
  any_ptr::functions<T>::table = {
    &any_ptr::template functions<T>::Delete
    ,&any_ptr::template functions<T>::GetType
    ,&any_ptr::template functions<T>::Clone
  };
Those paying close attention to my work, and not intimidated by complex template code, may realize that lately I have been riding in to town with the same horse, but painting it different colors.

What I mean to say is that the basic idea is always the same, create a function pointer table at compile time for every assignment or copy-construction to a different type. Each generated function in the table is responsible for casting the internal pointer to the appropriate type.

Hopefully all this makes some sense, and industrious readers can contribute some interesting applications of this class and/or technique.


Art Asano

Posts: 1
Nickname: arta5an0
Registered: Jan, 2007

Re: boost::any meet ootl::any_ptr Posted: Jan 5, 2007 10:14 AM
Reply to this message Reply
Christopher,
I found any_ptr faster than boost::any and simple enough to use in my current project.
Thank you.

I found that two any_ptr's for the same type but in different dll's have different m_t (table address).
(I'm not very sure about it but it explained the problem I had that time.)
I think that was why you had to use typeid to compare types instead of comparing the value of m_t's.

But, if so, any_ptr's copy constructor (implicit) might work incorrectly in that environment, therefore, so does Clone().

arta5an0

Flat View: This topic has 1 reply on 1 page
Topic: boost::any meet ootl::any_ptr Previous Topic   Next Topic Topic: Monolith: Facts, Failures, Fallacies, Falsehoods and Furphies

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use