$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r50938 - in sandbox/thread_safe_signals/trunk: boost/signals2 libs/signals2/test
From: fmhess_at_[hidden]
Date: 2009-01-31 20:12:04
Author: fmhess
Date: 2009-01-31 20:12:03 EST (Sat, 31 Jan 2009)
New Revision: 50938
URL: http://svn.boost.org/trac/boost/changeset/50938
Log:
Reworked deconstruct<>() so it operates non-intrusively via
argument-dependent lookup instead of needing postconstructible
and predestructible base classes.  Also added support for
passing arguments to postconstructors.
Text files modified: 
   sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct.hpp          |   174 +++++++++++++++++++++++++++++++++------ 
   sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct_ptr.hpp      |     2                                         
   sandbox/thread_safe_signals/trunk/boost/signals2/postconstructible.hpp    |    38 +++++--                                 
   sandbox/thread_safe_signals/trunk/boost/signals2/predestructible.hpp      |    26 ++++-                                   
   sandbox/thread_safe_signals/trunk/libs/signals2/test/deconstruct_test.cpp |    64 ++++++++++++++                          
   5 files changed, 254 insertions(+), 50 deletions(-)
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct.hpp	2009-01-31 20:12:03 EST (Sat, 31 Jan 2009)
@@ -2,6 +2,15 @@
 #define BOOST_SIGNALS2_DECONSTRUCT_HPP
 
 //  deconstruct.hpp
+//
+// A factory function for creating a shared_ptr which creates
+// an object and its owning shared_ptr with one allocation, similar
+// to make_shared<T>().  It also supports postconstructors
+// and predestructors through unqualified calls of adl_postconstruct() and
+// adl_predestruct, relying on argument-dependent
+// lookup to find the appropriate postconstructor or predestructor.
+// Passing arguments to postconstructors is also supported.
+//
 //  based on make_shared.hpp and make_shared_access patch from Michael Marcin
 //
 //  Copyright (c) 2007, 2008 Peter Dimov
@@ -18,8 +27,9 @@
 #include <boost/config.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/signals2/deconstruct_ptr.hpp>
-#include <boost/type_traits/type_with_alignment.hpp>
 #include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
 #include <cstddef>
 #include <new>
 
@@ -31,6 +41,115 @@
 
 namespace detail
 {
+  template< class T > T forward( T t )
+  {
+      return t;
+  }
+  inline void adl_predestruct(...) {}
+} // namespace detail
+
+template<typename T>
+    class postconstructor_invoker
+{
+public:
+    postconstructor_invoker(const shared_ptr<T> & sp):
+        _sp(sp)
+    {}
+    operator shared_ptr<T> () const
+    {
+        return postconstruct();
+    }
+    const shared_ptr<T>& postconstruct() const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()));
+        return _sp;
+    }
+#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
+    template<class T, class... Args>
+      const shared_ptr<T>& postconstruct(Args && ... args)
+    {
+      adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+        detail::forward<Args>(args)...);
+    }
+#else
+    template<typename A1>
+      const shared_ptr<T>& postconstruct(const A1 &a1) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1);
+        return _sp;
+    }
+    template<typename A1, typename A2>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3, typename A4>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3, a4);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3, typename A4, typename A5>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3, a4, a5);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3, typename A4, typename A5,
+      typename A6>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
+      const A6 &a6) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3, a4, a5, a6);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3, typename A4, typename A5,
+      typename A6, typename A7>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
+      const A6 &a6, const A7 &a7) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3, a4, a5, a6, a7);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3, typename A4, typename A5,
+      typename A6, typename A7, typename A8>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
+      const A6 &a6, const A7 &a7, const A8 &a8) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3, a4, a5, a6, a7, a8);
+        return _sp;
+    }
+    template<typename A1, typename A2, typename A3, typename A4, typename A5,
+      typename A6, typename A7, typename A8, typename A9>
+      const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5,
+      const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) const
+    {
+        adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()),
+          a1, a2, a3, a4, a5, a6, a7, a8, a9);
+        return _sp;
+    }
+#endif // else defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
+private:
+    shared_ptr<T> _sp;
+};
+
+namespace detail
+{
 
 template< std::size_t N, std::size_t A > struct sp_aligned_storage
 {
@@ -57,7 +176,8 @@
         if( initialized_ )
         {
             T* p = reinterpret_cast< T* >( storage_.data_ );
-            detail::do_predestruct(p);
+            using boost::signals2::detail::adl_predestruct;
+            adl_predestruct(const_cast<typename boost::remove_const<T>::type *>(p));
             p->~T();
             initialized_ = false;
         }
@@ -96,17 +216,12 @@
     }
 };
 
-template< class T > T forward( T t )
-{
-    return t;
-}
-
 class deconstruct_access
 {
 public:
 
     template< class T >
-    static boost::shared_ptr< T > deconstruct()
+    static postconstructor_invoker<T> deconstruct()
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -117,9 +232,8 @@
         new( pv ) T();
         pd->set_initialized();
 
-        boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) );
-        detail::do_postconstruct(retval.get());
-        return retval;
+        boost::shared_ptr< T > sp( pt, static_cast< T* >( pv ) );
+        return postconstructor_invoker<T>(sp);
     }
 
 #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
@@ -127,7 +241,7 @@
     // Variadic templates, rvalue reference
 
     template< class T, class... Args >
-    static boost::shared_ptr< T > deconstruct( Args && ... args )
+    static postconstructor_invoker<T> deconstruct( Args && ... args )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -146,7 +260,7 @@
 #else
 
     template< class T, class A1 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -163,7 +277,7 @@
     }
 
     template< class T, class A1, class A2 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -180,7 +294,7 @@
     }
 
     template< class T, class A1, class A2, class A3 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -197,7 +311,7 @@
     }
 
     template< class T, class A1, class A2, class A3, class A4 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -214,7 +328,7 @@
     }
 
     template< class T, class A1, class A2, class A3, class A4, class A5 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -231,7 +345,7 @@
     }
 
     template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -248,7 +362,7 @@
     }
 
     template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -265,7 +379,7 @@
     }
 
     template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -282,7 +396,7 @@
     }
 
     template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
-    static boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
+    static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
     {
         boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() );
 
@@ -325,55 +439,55 @@
 // C++03 version
 
 template< class T, class A1 >
-boost::shared_ptr< T > deconstruct( A1 const & a1 )
+postconstructor_invoker<T> deconstruct( A1 const & a1 )
 {
         return detail::deconstruct_access::deconstruct<T>(a1);
 }
 
 template< class T, class A1, class A2 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 )
 {
    return detail::deconstruct_access::deconstruct<T>(a1,a2);
 }
 
 template< class T, class A1, class A2, class A3 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 )
 {
         return detail::deconstruct_access::deconstruct<T>(a1,a2,a3);
 }
 
 template< class T, class A1, class A2, class A3, class A4 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
 {
     return detail::deconstruct_access::deconstruct<T>(a1,a2,a3,a4);
 }
 
 template< class T, class A1, class A2, class A3, class A4, class A5 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
 {
     return detail::deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5);
 }
 
 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
 {
     return detail::deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6);
 }
 
 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
 {
     return detail::deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7);
 }
 
 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
 {
     return detail::deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8);
 }
 
 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
-boost::shared_ptr< T > deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
+postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
 {
     return detail::deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8,a9);
 }
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct_ptr.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct_ptr.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/deconstruct_ptr.hpp	2009-01-31 20:12:03 EST (Sat, 31 Jan 2009)
@@ -1,3 +1,5 @@
+// DEPRECATED in favor of adl_postconstruct and adl_predestruct with
+// deconstruct<T>().
 // A factory function for creating a shared_ptr that enhances the plain
 // shared_ptr constructors by adding support for postconstructors
 // and predestructors through the boost::signals2::postconstructible and
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/postconstructible.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/postconstructible.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/postconstructible.hpp	2009-01-31 20:12:03 EST (Sat, 31 Jan 2009)
@@ -1,3 +1,4 @@
+// DEPRECATED in favor of adl_postconstruct with deconstruct<T>().
 // A simple framework for creating objects with postconstructors.
 // The objects must inherit from boost::signals2::postconstructible, and
 // have their lifetimes managed by
@@ -18,21 +19,34 @@
 {
   namespace signals2
   {
-    class postconstructible;
-    namespace detail
+    namespace postconstructible_adl_barrier
     {
-      void do_postconstruct(const boost::signals2::postconstructible *ptr);
+      class postconstructible;
     }
-
-    class postconstructible
+    namespace detail
+    {
+      void do_postconstruct(const boost::signals2::postconstructible_adl_barrier::postconstructible *ptr);
+    } // namespace detail
+    
+    namespace postconstructible_adl_barrier
     {
-    public:
-      friend void detail::do_postconstruct(const boost::signals2::postconstructible *ptr);
-    protected:
-      postconstructible() {}
-      virtual ~postconstructible() {}
-      virtual void postconstruct() = 0;
-    };
+      class postconstructible
+      {
+      public:
+        friend void detail::do_postconstruct(const postconstructible *ptr);
+        template<typename T>
+          friend void adl_postconstruct(const shared_ptr<T> &sp, postconstructible *p)
+        {
+          p->postconstruct();
+        }
+      protected:
+        postconstructible() {}
+        virtual ~postconstructible() {}
+        virtual void postconstruct() = 0;
+      };
+    } // namespace postconstructible_adl_barrier
+    using postconstructible_adl_barrier::postconstructible;
+    
   }
 }
 
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/predestructible.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/predestructible.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/predestructible.hpp	2009-01-31 20:12:03 EST (Sat, 31 Jan 2009)
@@ -1,3 +1,4 @@
+// DEPRECATED in favor of adl_predestruct with deconstruct<T>().
 // A simple framework for creating objects with predestructors.
 // The objects must inherit from boost::signals2::predestructible, and
 // have their lifetimes managed by
@@ -20,14 +21,25 @@
   {
     template<typename T> class predestructing_deleter;
 
-    class predestructible
+    namespace predestructible_adl_barrier
     {
-    protected:
-      predestructible() {}
-    public:
-      virtual ~predestructible() {}
-      virtual void predestruct() = 0;
-    };
+      class predestructible
+      {
+      protected:
+        predestructible() {}
+      public:
+        template<typename T>
+          friend void adl_postconstruct(const shared_ptr<T> &, ...)
+        {};
+        friend void adl_predestruct(predestructible *p)
+        {
+          p->predestruct();
+        }
+        virtual ~predestructible() {}
+        virtual void predestruct() = 0;
+      };
+    } // namespace predestructible_adl_barrier
+    using predestructible_adl_barrier::predestructible;
   }
 }
 
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/deconstruct_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/deconstruct_test.cpp	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/deconstruct_test.cpp	2009-01-31 20:12:03 EST (Sat, 31 Jan 2009)
@@ -53,6 +53,7 @@
   {
     BOOST_CHECK(_postconstructed);
   }
+  int value;
 protected:
   virtual void postconstruct()
   {
@@ -61,10 +62,58 @@
   bool _postconstructed;
 private:
   friend class boost::signals2::deconstruct_access;
-  by_deconstruct_only(int): _postconstructed(false)
+  by_deconstruct_only(int value_in):
+    value(value_in), _postconstructed(false)
   {}
 };
 
+namespace mytest
+{
+  class A
+  {
+  public:
+    template<typename T> friend
+      void adl_postconstruct(const boost::shared_ptr<T> &sp, A *p)
+    {
+      if(p)
+      {
+        p->_postconstructed = true;
+      }
+    }
+    template<typename T> friend
+      void adl_postconstruct(const boost::shared_ptr<T> &sp, A *p, int val)
+    {
+      if(p)
+      {
+        p->value = val;
+        p->_postconstructed = true;
+      }
+    }
+    friend void adl_predestruct(A *p)
+    {
+      if(p)
+      {
+        p->_predestructed = true;
+      }
+    }
+    ~A()
+    {
+      BOOST_CHECK(_postconstructed);
+      BOOST_CHECK(_predestructed);
+    }
+    int value;
+  private:
+    friend class boost::signals2::deconstruct_access;
+    A(int value_in):
+      value(value_in),
+      _postconstructed(false),
+      _predestructed(false)
+    {}
+    bool _postconstructed;
+    bool _predestructed;
+  };
+}
+
 void deconstruct_ptr_test()
 {
   {
@@ -91,6 +140,19 @@
   }
   {
     boost::shared_ptr<by_deconstruct_only> a = boost::signals2::deconstruct<by_deconstruct_only>(1);
+    BOOST_CHECK(a->value == 1);
+  }
+  {
+    boost::shared_ptr<mytest::A> a = boost::signals2::deconstruct<mytest::A>(1);
+    BOOST_CHECK(a->value == 1);
+  }
+  {// deconstruct const type
+    boost::shared_ptr<const mytest::A> a = boost::signals2::deconstruct<const mytest::A>(3);
+    BOOST_CHECK(a->value == 3);
+  }
+  {// passing arguments to postconstructor
+    boost::shared_ptr<mytest::A> a = boost::signals2::deconstruct<mytest::A>(1).postconstruct(2);
+    BOOST_CHECK(a->value == 2);
   }
 }