$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55297 - in sandbox/fmhess: boost/generic_ptr libs/generic_ptr/test
From: fmhess_at_[hidden]
Date: 2009-07-30 14:45:37
Author: fmhess
Date: 2009-07-30 14:35:57 EDT (Thu, 30 Jul 2009)
New Revision: 55297
URL: http://svn.boost.org/trac/boost/changeset/55297
Log:
Added new generic pointer type "throwing", which throws when
an attempt is made to use it when it is null.  Added some new
tests.
Added:
   sandbox/fmhess/boost/generic_ptr/throwing.hpp   (contents, props changed)
   sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp   (contents, props changed)
   sandbox/fmhess/libs/generic_ptr/test/throwing_test.cpp   (contents, props changed)
Text files modified: 
   sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2 |    12 +++++++++++-                            
   1 files changed, 11 insertions(+), 1 deletions(-)
Added: sandbox/fmhess/boost/generic_ptr/throwing.hpp
==============================================================================
--- (empty file)
+++ sandbox/fmhess/boost/generic_ptr/throwing.hpp	2009-07-30 14:35:57 EDT (Thu, 30 Jul 2009)
@@ -0,0 +1,202 @@
+//
+//  generic_ptr/throwing.hpp
+//
+//  Copyright (c) 2009 Frank Mori Hess
+//  Copyright (c) 2001, 2002 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/generic_ptr for documentation.
+//
+
+#ifndef BOOST_GENERIC_PTR_THROWING_HPP_INCLUDED
+#define BOOST_GENERIC_PTR_THROWING_HPP_INCLUDED
+
+#include <boost/generic_ptr/pointer_traits.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/utility/swap.hpp>
+#include <stdexcept>
+
+namespace boost
+{
+  namespace generic_ptr
+  {
+    template<typename T>
+    class throwing
+    {
+      typedef throwing this_type; // for detail/operator_bool.hpp
+    public:
+      typedef typename pointer_traits<T>::value_type value_type;
+      typedef T pointer;
+      typedef typename pointer_traits<T>::reference reference;
+
+      template<typename ValueType>
+      struct rebind
+      {
+        typedef throwing<typename generic_ptr::rebind<pointer, ValueType>::other> other;
+      };
+
+      throwing(): px()
+      {}
+      template<typename U>
+      throwing( U p ): px( p )
+      {}
+      template<typename U>
+      throwing(const throwing<U> & other): px(other.px)
+      {}
+#ifndef BOOST_NO_RVALUE_REFERENCES
+      throwing(throwing && other): px(std::move(other.px))
+      {}
+      template<typename U>
+      throwing(throwing<U> && other): px(std::move(other.px))
+      {}
+#endif
+
+      void swap(throwing & other)
+      {
+        boost::swap(px, other.px);
+      }
+
+      throwing & operator=(const throwing & other)
+      {
+        throwing(other).swap(*this);
+        return *this;
+      }
+
+      template<typename U>
+      throwing & operator=(const throwing<U> & other)
+      {
+        throwing(other).swap(*this);
+        return *this;
+      }
+#ifndef BOOST_NO_RVALUE_REFERENCES
+      throwing & operator=(throwing && other)
+      {
+        throwing(std::move(other)).swap(*this);
+        return *this;
+      }
+      template<typename U>
+      throwing & operator=(throwing<U> && other)
+      {
+        throwing(std::move(other)).swap(*this);
+        return *this;
+      }
+#endif
+      void reset()
+      {
+        throwing().swap(*this);
+      }
+      template<typename U> void reset(U p)
+      {
+        throwing(p).swap(*this);
+      }
+
+      pointer get() const {return px;}
+
+// implicit conversion to "bool"
+#include <boost/generic_ptr/detail/operator_bool.hpp>
+
+      pointer operator->() const
+      {
+        if(get_plain_old_pointer(px) == 0)
+        {
+          throw std::invalid_argument("Attempted to access object through null pointer.");
+        }
+        return px;
+      }
+
+      reference operator*() const
+      {
+        if(get_plain_old_pointer(px) == 0)
+        {
+          throw std::invalid_argument("Attempted to dereference null pointer.");
+        }
+        return *px;
+      }
+
+      // conversion to wrapped pointer type
+      operator pointer() const
+      {
+        return px;
+      }
+    private:
+      pointer px;
+    };
+
+    template<typename T>
+    T get_pointer(const throwing<T> &p)
+    {
+      return p.get();
+    }
+
+    // casts
+    template<typename ToValueType, typename U>
+    typename rebind<throwing<U>, ToValueType>::other static_pointer_cast
+    (
+      throwing<U> const & p,
+      mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
+    )
+    {
+        return static_pointer_cast(p.get(), to_type_iden);
+    }
+    template<typename ToValueType, typename U>
+    typename rebind<throwing<U>, ToValueType>::other const_pointer_cast
+    (
+      throwing<U> const & p,
+      mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
+    )
+    {
+        return const_pointer_cast(p.get(), to_type_iden);
+    }
+    template<typename ToValueType, typename U>
+    typename rebind<throwing<U>, ToValueType>::other dynamic_pointer_cast
+    (
+      throwing<U> const & p,
+      mpl::identity<ToValueType> to_type_iden = mpl::identity<ToValueType>()
+    )
+    {
+        return dynamic_pointer_cast(p.get(), to_type_iden);
+    }
+
+    // comparisons
+    template<class T, class U> inline bool operator==(throwing<T> const & a, throwing<U> const & b)
+    {
+      return a.get() == b.get();
+    }
+    template<class T, class U> inline bool operator!=(throwing<T> const & a, throwing<U> const & b)
+    {
+      return a.get() != b.get();
+    }
+    template<class T, class U> inline bool operator==(throwing<T> const & a, U const & b)
+    {
+      return a.get() == b;
+    }
+    template<class T, class U> inline bool operator!=(throwing<T> const & a, U const & b)
+    {
+      return a.get() != b;
+    }
+    template<class T, class U> inline bool operator==(T const & a, throwing<U> const & b)
+    {
+      return a == b.get();
+    }
+    template<class T, class U> inline bool operator!=(T const & a, throwing<U> const & b)
+    {
+      return a != b.get();
+    }
+    #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
+    // Resolve the ambiguity between our op!= and the one in rel_ops
+    template<class T> inline bool operator!=(throwing<T> const & a, throwing<T> const & b)
+    {
+      return a.get() != b.get();
+    }
+    #endif
+    template<class T> inline bool operator<(throwing<T> const & a, throwing<T> const & b)
+    {
+      return std::less<typename throwing<T>::pointer>()(a.get(), b.get());
+    }
+  } // namespace generic_ptr
+} // namespace boost
+
+#endif  // #ifndef BOOST_GENERIC_PTR_THROWING_HPP_INCLUDED
Modified: sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2
==============================================================================
--- sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2	(original)
+++ sandbox/fmhess/libs/generic_ptr/test/Jamfile.v2	2009-07-30 14:35:57 EDT (Thu, 30 Jul 2009)
@@ -11,9 +11,19 @@
 # bring in rules for testing
 import testing ;
 
+rule thread-run ( sources )
+{
+    return
+    [ run $(sources) : : : <library>../../thread/build//boost_thread/
+        <threading>multi ]
+    ;
+}
+
 {
     test-suite "generic_ptr"
-        : [ run cloning_test.cpp ]
+        : [ thread-run basic_generic_pointer_test.cpp ]
+          [ run cloning_test.cpp ]
+          [ run throwing_test.cpp ]
         ;
 }
 
Added: sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/fmhess/libs/generic_ptr/test/basic_generic_pointer_test.cpp	2009-07-30 14:35:57 EDT (Thu, 30 Jul 2009)
@@ -0,0 +1,135 @@
+//
+//  basic_generic_pointer_test.cpp
+//
+//  Copyright (c) 2009 Frank Mori Hess
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/generic_ptr/cloning.hpp>
+#include <boost/generic_ptr/intrusive.hpp>
+#include <boost/generic_ptr/monitor.hpp>
+#include <boost/generic_ptr/pointer_cast.hpp>
+#include <boost/generic_ptr/pointer_traits.hpp>
+#include <boost/generic_ptr/shared.hpp>
+#include <boost/generic_ptr/throwing.hpp>
+
+class Y
+{
+public:
+  virtual ~Y() {}
+};
+
+class X: public Y
+{
+public:
+  static const int return_value = 1;
+  int f() { return return_value; }
+};
+
+void intrusive_ptr_add_ref(const Y *) {};
+void intrusive_ptr_release(const Y *) {};
+
+template<typename GenericPointer>
+void member_access_test(GenericPointer &p)
+{
+  BOOST_TEST(p->f() == X::return_value);
+}
+
+template<typename GenericPointer>
+void dereference_test(GenericPointer &p)
+{
+  BOOST_TEST((*p).f() == X::return_value);
+}
+
+template<typename GenericPointer>
+void rebind_test(GenericPointer &p)
+{
+  typedef typename boost::generic_ptr::rebind
+  <
+    GenericPointer,
+    const typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type
+  >::other other_type;
+  BOOST_TEST(typeid(const typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type) ==
+    typeid(typename boost::generic_ptr::pointer_traits<other_type>::value_type));
+}
+
+template<typename GenericPointer>
+void cast_test(GenericPointer &p)
+{
+  typedef typename boost::generic_ptr::rebind<GenericPointer, Y>::other pointer_to_y_type;
+
+  pointer_to_y_type yp = boost::generic_ptr::static_pointer_cast<Y>(p);
+  GenericPointer xp = boost::generic_ptr::static_pointer_cast
+    <typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type>(yp);
+
+  yp = boost::generic_ptr::dynamic_pointer_cast<Y>(p);
+  xp = boost::generic_ptr::dynamic_pointer_cast
+    <typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type>(yp);
+  BOOST_TEST(boost::generic_ptr::get_plain_old_pointer(xp) != 0);
+
+  typedef typename boost::generic_ptr::rebind
+  <
+    GenericPointer,
+    const typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type
+  >::other pointer_to_const_x_type;
+  pointer_to_const_x_type xp_const = boost::generic_ptr::const_pointer_cast
+    <const typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type>(p);
+  xp = boost::generic_ptr::const_pointer_cast
+    <
+      typename boost::generic_ptr::pointer_traits<GenericPointer>::value_type
+    >(xp_const);
+}
+
+int main()
+{
+  {
+    X x;
+    X *p = &x;
+    rebind_test(p);
+    cast_test(p);
+  }
+  {
+    X x;
+    boost::generic_ptr::throwing<X*> p(&x);
+    member_access_test(p);
+    dereference_test(p);
+    rebind_test(p);
+    cast_test(p);
+  }
+  {
+    X x;
+    boost::generic_ptr::monitor<X*> p(&x);
+    member_access_test(p);
+    // dereference_test(p); // monitors don't support dereference
+    rebind_test(p);
+    cast_test(p);
+  }
+  {
+    boost::generic_ptr::shared<X*> p(new X());
+    member_access_test(p);
+    dereference_test(p);
+    rebind_test(p);
+    cast_test(p);
+  }
+  {
+    X x;
+    boost::generic_ptr::intrusive<X*> p(&x);
+    member_access_test(p);
+    dereference_test(p);
+    rebind_test(p);
+    cast_test(p);
+  }
+  {
+    boost::generic_ptr::cloning<X*> p(new X());
+    member_access_test(p);
+    dereference_test(p);
+    rebind_test(p);
+    cast_test(p);
+  }
+  return 0;
+}
Added: sandbox/fmhess/libs/generic_ptr/test/throwing_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/fmhess/libs/generic_ptr/test/throwing_test.cpp	2009-07-30 14:35:57 EDT (Thu, 30 Jul 2009)
@@ -0,0 +1,30 @@
+//
+//  throwing_test.cpp
+//
+//  Copyright (c) 2009 Frank Mori Hess
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/generic_ptr/throwing.hpp>
+
+void implicit_conversion_test()
+{
+  int x;
+  boost::generic_ptr::throwing<int*> tp;
+  tp = &x;
+  BOOST_TEST(tp == &x);
+  int *p = tp;
+  BOOST_TEST(p == tp);
+  BOOST_TEST(p == &x);
+}
+
+int main()
+{
+  implicit_conversion_test();
+  return 0;
+}