Boost logo

Boost-Commit :

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;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk