From 46f00ea9935a3be7b8d1f14a2d4a0db0a3705b58 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 15 Dec 2015 19:13:20 +0200 Subject: [PATCH 1/9] Fix hash support for shared_ptr, --- include/boost/smart_ptr/shared_ptr.hpp | 2 +- test/Jamfile.v2 | 3 +++ test/sp_hash_test2.cpp | 34 ++++++++++++++++++++++++++ test/sp_hash_test3.cpp | 34 ++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 test/sp_hash_test2.cpp create mode 100644 test/sp_hash_test3.cpp diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 47bc33d..bcefda8 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -1065,7 +1065,7 @@ template< class T > struct hash; template< class T > std::size_t hash_value( boost::shared_ptr const & p ) BOOST_NOEXCEPT { - return boost::hash< T* >()( p.get() ); + return boost::hash< typename boost::shared_ptr::element_type* >()( p.get() ); } } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 62fab50..963eebc 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -181,5 +181,8 @@ import testing ; [ run weak_from_this_test2.cpp ] [ run sp_bml_unique_ptr_test.cpp ] + + [ run sp_hash_test2.cpp ] + [ run sp_hash_test3.cpp ] ; } diff --git a/test/sp_hash_test2.cpp b/test/sp_hash_test2.cpp new file mode 100644 index 0000000..c1cbf70 --- /dev/null +++ b/test/sp_hash_test2.cpp @@ -0,0 +1,34 @@ +// +// sp_hash_test2.cpp +// +// Copyright 2011, 2015 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 +// + +#include +#include +#include + +int main() +{ + boost::hash< boost::shared_ptr > hasher; + + boost::shared_ptr< int[] > p1, p2( p1 ), p3( new int[1] ), p4( p3 ), p5( new int[1] ); + + BOOST_TEST_EQ( p1, p2 ); + BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) ); + + BOOST_TEST_NE( p1, p3 ); + BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) ); + + BOOST_TEST_EQ( p3, p4 ); + BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) ); + + BOOST_TEST_NE( p3, p5 ); + BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) ); + + return boost::report_errors(); +} diff --git a/test/sp_hash_test3.cpp b/test/sp_hash_test3.cpp new file mode 100644 index 0000000..4d4acad --- /dev/null +++ b/test/sp_hash_test3.cpp @@ -0,0 +1,34 @@ +// +// sp_hash_test3.cpp +// +// Copyright 2011, 2015 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 +// + +#include +#include +#include + +int main() +{ + boost::hash< boost::shared_ptr > hasher; + + boost::shared_ptr< int[1] > p1, p2( p1 ), p3( new int[1] ), p4( p3 ), p5( new int[1] ); + + BOOST_TEST_EQ( p1, p2 ); + BOOST_TEST_EQ( hasher( p1 ), hasher( p2 ) ); + + BOOST_TEST_NE( p1, p3 ); + BOOST_TEST_NE( hasher( p1 ), hasher( p3 ) ); + + BOOST_TEST_EQ( p3, p4 ); + BOOST_TEST_EQ( hasher( p3 ), hasher( p4 ) ); + + BOOST_TEST_NE( p3, p5 ); + BOOST_TEST_NE( hasher( p3 ), hasher( p5 ) ); + + return boost::report_errors(); +} From 821925c536ccbdf1592d5ca614d0dc16012f29a2 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 8 Nov 2015 00:38:22 -0500 Subject: [PATCH 2/9] Refactor make_unique implementations Before the pending refactor of make_shared/allocate_shared for arrays. --- include/boost/make_unique.hpp | 14 +-- .../boost/smart_ptr/detail/up_if_array.hpp | 26 ----- .../smart_ptr/detail/up_if_not_array.hpp | 31 ----- include/boost/smart_ptr/make_unique.hpp | 108 ++++++++++++++++-- include/boost/smart_ptr/make_unique_array.hpp | 31 ----- .../boost/smart_ptr/make_unique_object.hpp | 45 -------- test/make_unique_args_test.cpp | 22 ++-- test/make_unique_array_noinit_test.cpp | 22 ++-- test/make_unique_array_test.cpp | 22 ++-- test/make_unique_array_throws_test.cpp | 22 ++-- test/make_unique_noinit_test.cpp | 22 ++-- test/make_unique_test.cpp | 22 ++-- test/make_unique_throws_test.cpp | 22 ++-- test/make_unique_value_test.cpp | 22 ++-- 14 files changed, 202 insertions(+), 229 deletions(-) delete mode 100644 include/boost/smart_ptr/detail/up_if_array.hpp delete mode 100644 include/boost/smart_ptr/detail/up_if_not_array.hpp delete mode 100644 include/boost/smart_ptr/make_unique_array.hpp delete mode 100644 include/boost/smart_ptr/make_unique_object.hpp diff --git a/include/boost/make_unique.hpp b/include/boost/make_unique.hpp index c163673..4dc82c3 100644 --- a/include/boost/make_unique.hpp +++ b/include/boost/make_unique.hpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #ifndef BOOST_MAKE_UNIQUE_HPP_INCLUDED #define BOOST_MAKE_UNIQUE_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/up_if_array.hpp b/include/boost/smart_ptr/detail/up_if_array.hpp deleted file mode 100644 index 7e62d10..0000000 --- a/include/boost/smart_ptr/detail/up_if_array.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP -#define BOOST_SMART_PTR_DETAIL_UP_IF_ARRAY_HPP - -#include - -namespace boost { - namespace detail { - template - struct up_if_array; - - template - struct up_if_array { - typedef std::unique_ptr type; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/up_if_not_array.hpp b/include/boost/smart_ptr/detail/up_if_not_array.hpp deleted file mode 100644 index fd74f25..0000000 --- a/include/boost/smart_ptr/detail/up_if_not_array.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP -#define BOOST_SMART_PTR_DETAIL_UP_IF_NOT_ARRAY_HPP - -#include - -namespace boost { - namespace detail { - template - struct up_if_not_array { - typedef std::unique_ptr type; - }; - - template - struct up_if_not_array { - }; - - template - struct up_if_not_array { - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/make_unique.hpp b/include/boost/smart_ptr/make_unique.hpp index 90402e2..f1f4a7c 100644 --- a/include/boost/smart_ptr/make_unique.hpp +++ b/include/boost/smart_ptr/make_unique.hpp @@ -1,15 +1,105 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP #define BOOST_SMART_PTR_MAKE_UNIQUE_HPP -#include -#include +#include +#include + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif + +namespace boost { +namespace detail { +template +struct up_if_object { + typedef std::unique_ptr type; +}; + +template +struct up_if_object { +}; + +template +struct up_if_object { +}; + +template +struct up_if_array { +}; + +template +struct up_if_array { + typedef std::unique_ptr type; +}; + +template +struct up_value { + typedef T&& type; +}; + +template +struct up_element { +}; + +template +struct up_element { + typedef T type; +}; +} /* detail */ + +template +inline typename detail::up_if_object::type +make_unique() +{ + return std::unique_ptr(new T()); +} + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline typename detail::up_if_object::type +make_unique(Args&&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} +#endif + +template +inline typename detail::up_if_object::type +make_unique(typename detail::up_value::type value) +{ + return std::unique_ptr(new T(std::move(value))); +} + +template +inline typename detail::up_if_object::type +make_unique_noinit() +{ + return std::unique_ptr(new T); +} + +template +inline typename detail::up_if_array::type +make_unique(std::size_t n) +{ + return std::unique_ptr(new + typename detail::up_element::type[n]()); +} + +template +inline typename detail::up_if_array::type +make_unique_noinit(std::size_t n) +{ + return std::unique_ptr(new + typename detail::up_element::type[n]); +} +} /* boost */ #endif diff --git a/include/boost/smart_ptr/make_unique_array.hpp b/include/boost/smart_ptr/make_unique_array.hpp deleted file mode 100644 index eb0528e..0000000 --- a/include/boost/smart_ptr/make_unique_array.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP -#define BOOST_SMART_PTR_MAKE_UNIQUE_ARRAY_HPP - -#include -#include - -namespace boost { - template - inline typename boost::detail::up_if_array::type - make_unique(std::size_t size) { - typedef typename boost::detail::array_inner::type U; - return std::unique_ptr(new U[size]()); - } - - template - inline typename boost::detail::up_if_array::type - make_unique_noinit(std::size_t size) { - typedef typename boost::detail::array_inner::type U; - return std::unique_ptr(new U[size]); - } -} - -#endif diff --git a/include/boost/smart_ptr/make_unique_object.hpp b/include/boost/smart_ptr/make_unique_object.hpp deleted file mode 100644 index 9e6108a..0000000 --- a/include/boost/smart_ptr/make_unique_object.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP -#define BOOST_SMART_PTR_MAKE_UNIQUE_OBJECT_HPP - -#include -#include -#include -#include - -namespace boost { - template - inline typename boost::detail::up_if_not_array::type - make_unique() { - return std::unique_ptr(new T()); - } - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - inline typename boost::detail::up_if_not_array::type - make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); - } -#endif - - template - inline typename boost::detail::up_if_not_array::type - make_unique(typename add_rvalue_reference::type value) { - return std::unique_ptr(new T(std::move(value))); - } - - template - inline typename boost::detail::up_if_not_array::type - make_unique_noinit() { - return std::unique_ptr(new T); - } -} - -#endif diff --git a/test/make_unique_args_test.cpp b/test/make_unique_args_test.cpp index 6c13d41..7231a8d 100644 --- a/test/make_unique_args_test.cpp +++ b/test/make_unique_args_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -41,7 +41,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ BOOST_TEST(type::instances == 0); { std::unique_ptr a1 = boost::make_unique(); @@ -139,7 +140,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_array_noinit_test.cpp b/test/make_unique_array_noinit_test.cpp index edaa67f..675c470 100644 --- a/test/make_unique_array_noinit_test.cpp +++ b/test/make_unique_array_noinit_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -30,7 +30,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { std::unique_ptr a1 = boost::make_unique_noinit(3); BOOST_TEST(a1.get() != 0); @@ -81,7 +82,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_array_test.cpp b/test/make_unique_array_test.cpp index 8e5ea79..af0a065 100644 --- a/test/make_unique_array_test.cpp +++ b/test/make_unique_array_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -30,7 +30,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { std::unique_ptr a1 = boost::make_unique(3); BOOST_TEST(a1.get() != 0); @@ -105,7 +106,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_array_throws_test.cpp b/test/make_unique_array_throws_test.cpp index 3efbc2a..e38b145 100644 --- a/test/make_unique_array_throws_test.cpp +++ b/test/make_unique_array_throws_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -33,7 +33,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ BOOST_TEST(type::instances == 0); try { boost::make_unique(6); @@ -70,7 +71,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_noinit_test.cpp b/test/make_unique_noinit_test.cpp index 1ef0daa..3de787c 100644 --- a/test/make_unique_noinit_test.cpp +++ b/test/make_unique_noinit_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -30,7 +30,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { std::unique_ptr a1 = boost::make_unique_noinit(); BOOST_TEST(a1.get() != 0); @@ -58,7 +59,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_test.cpp b/test/make_unique_test.cpp index ab13c33..a2c6b99 100644 --- a/test/make_unique_test.cpp +++ b/test/make_unique_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -30,7 +30,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { std::unique_ptr a1 = boost::make_unique(); BOOST_TEST(a1.get() != 0); @@ -65,7 +66,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_throws_test.cpp b/test/make_unique_throws_test.cpp index 9594c90..c8fdcc8 100644 --- a/test/make_unique_throws_test.cpp +++ b/test/make_unique_throws_test.cpp @@ -1,15 +1,15 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include class type { public: @@ -33,7 +33,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ BOOST_TEST(type::instances == 0); try { boost::make_unique(); @@ -46,7 +47,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } diff --git a/test/make_unique_value_test.cpp b/test/make_unique_value_test.cpp index 03cdf47..4b34af8 100644 --- a/test/make_unique_value_test.cpp +++ b/test/make_unique_value_test.cpp @@ -1,22 +1,23 @@ /* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2014 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #if !defined(BOOST_NO_CXX11_SMART_PTR) #include -#include +#include struct type { int x; int y; }; -int main() { +int main() +{ { std::unique_ptr a1 = boost::make_unique(); BOOST_TEST(a1.get() != 0); @@ -51,7 +52,8 @@ int main() { } #else -int main() { +int main() +{ return 0; } From 8298952a1203dd40103feb912d5f46568d06e8b7 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 9 Nov 2015 22:35:34 -0500 Subject: [PATCH 3/9] Update unit tests for make_shared/allocate_shared for arrays Before pending refactor of make_shared and allocate_shared for arrays. --- test/allocate_shared_array_construct_test.cpp | 111 ++++++------------ test/allocate_shared_array_esft_test.cpp | 26 ++-- test/allocate_shared_array_noinit_test.cpp | 48 ++------ test/allocate_shared_array_test.cpp | 48 ++------ test/allocate_shared_array_throws_test.cpp | 40 ++----- test/allocate_shared_array_value_test.cpp | 25 ++-- test/allocate_shared_arrays_test.cpp | 25 ++-- test/make_shared_array_esft_test.cpp | 26 ++-- test/make_shared_array_noinit_test.cpp | 48 ++------ test/make_shared_array_test.cpp | 48 ++------ test/make_shared_array_throws_test.cpp | 38 ++---- test/make_shared_array_value_test.cpp | 25 ++-- test/make_shared_arrays_test.cpp | 11 +- 13 files changed, 163 insertions(+), 356 deletions(-) diff --git a/test/allocate_shared_array_construct_test.cpp b/test/allocate_shared_array_construct_test.cpp index fe9fe3f..0228275 100644 --- a/test/allocate_shared_array_construct_test.cpp +++ b/test/allocate_shared_array_construct_test.cpp @@ -1,43 +1,38 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include + +struct tag { }; template class creator { public: typedef T value_type; - creator() { } - template creator(const creator&) { } - T* allocate(std::size_t size) { - void* p1 = ::operator new(size * sizeof(T)); - return static_cast(p1); + void* p = ::operator new(size * sizeof(T)); + return static_cast(p); } - void deallocate(T* memory, std::size_t) { - void* p1 = memory; - ::operator delete(p1); + void* p = memory; + ::operator delete(p); } - template void construct(U* memory) { - void* p1 = memory; - ::new(p1) U(); + void* p = memory; + ::new(p) U(tag()); } - template void destroy(U* memory) { memory->~U(); @@ -45,116 +40,88 @@ public: }; class type { - friend class creator; - public: static unsigned int instances; - static const type object; - -protected: - explicit type() { + explicit type(tag) { instances++; } - type(const type&) { instances++; } - ~type() { instances--; } }; -unsigned int type::instances; -const type type::object; +unsigned int type::instances = 0; -int main() { - BOOST_TEST(type::instances == 1); +int main() +{ +#if !defined(BOOST_NO_CXX11_ALLOCATOR) { boost::shared_ptr a1 = boost::allocate_shared(creator(), 3); BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.get() != 0); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type::instances == 3); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator()); BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.get() != 0); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type::instances == 3); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator(), 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator(), 3); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type::instances == 3); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type::instances == 3); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator(), 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 1); { boost::shared_ptr a1 = boost::allocate_shared(creator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type::instances == 0); } - +#endif return boost::report_errors(); } -#else - -int main() { - return 0; -} - -#endif diff --git a/test/allocate_shared_array_esft_test.cpp b/test/allocate_shared_array_esft_test.cpp index b342366..30edfff 100644 --- a/test/allocate_shared_array_esft_test.cpp +++ b/test/allocate_shared_array_esft_test.cpp @@ -1,28 +1,25 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include #include +#include class type : public boost::enable_shared_from_this { public: static unsigned int instances; - explicit type() { instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -30,7 +27,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); @@ -41,7 +39,6 @@ int main() { BOOST_TEST(type::instances == 3); } } - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); @@ -52,6 +49,5 @@ int main() { BOOST_TEST(type::instances == 3); } } - return boost::report_errors(); } diff --git a/test/allocate_shared_array_noinit_test.cpp b/test/allocate_shared_array_noinit_test.cpp index 6c8ff3d..83b48ec 100644 --- a/test/allocate_shared_array_noinit_test.cpp +++ b/test/allocate_shared_array_noinit_test.cpp @@ -1,28 +1,25 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include #include #include class type { public: static unsigned int instances; - explicit type() { instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -30,7 +27,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); int* a2 = a1.get(); @@ -38,7 +36,6 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); int* a2 = a1.get(); @@ -46,19 +43,16 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); const int* a2 = a1.get(); @@ -66,7 +60,6 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); const int* a2 = a1.get(); @@ -74,20 +67,16 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); type* a2 = a1.get(); @@ -99,8 +88,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); type* a2 = a1.get(); @@ -112,8 +99,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); BOOST_TEST(a1.get() != 0); @@ -122,8 +107,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); BOOST_TEST(a1.get() != 0); @@ -132,8 +115,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 3); const type* a2 = a1.get(); @@ -144,8 +125,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); const type* a2 = a1.get(); @@ -156,8 +135,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator(), 2); BOOST_TEST(a1.get() != 0); @@ -166,8 +143,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared_noinit(std::allocator()); BOOST_TEST(a1.get() != 0); @@ -176,6 +151,5 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - return boost::report_errors(); } diff --git a/test/allocate_shared_array_test.cpp b/test/allocate_shared_array_test.cpp index 43715a7..c5a5714 100644 --- a/test/allocate_shared_array_test.cpp +++ b/test/allocate_shared_array_test.cpp @@ -1,28 +1,25 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include #include #include class type { public: static unsigned int instances; - explicit type() { instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -30,7 +27,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); int* a2 = a1.get(); @@ -41,7 +39,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); int* a2 = a1.get(); @@ -52,7 +49,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); BOOST_TEST(a1.get() != 0); @@ -62,7 +58,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); @@ -72,7 +67,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); const int* a2 = a1.get(); @@ -83,7 +77,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); const int* a2 = a1.get(); @@ -94,7 +87,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); BOOST_TEST(a1.get() != 0); @@ -104,7 +96,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); @@ -114,8 +105,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); type* a2 = a1.get(); @@ -127,8 +116,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); type* a2 = a1.get(); @@ -140,8 +127,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); BOOST_TEST(a1.get() != 0); @@ -150,8 +135,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); @@ -160,8 +143,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); const type* a2 = a1.get(); @@ -172,8 +153,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); const type* a2 = a1.get(); @@ -184,8 +163,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); BOOST_TEST(a1.get() != 0); @@ -194,8 +171,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); @@ -204,6 +179,5 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - return boost::report_errors(); } diff --git a/test/allocate_shared_array_throws_test.cpp b/test/allocate_shared_array_throws_test.cpp index 71a3ce9..e14d984 100644 --- a/test/allocate_shared_array_throws_test.cpp +++ b/test/allocate_shared_array_throws_test.cpp @@ -1,29 +1,26 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include class type { public: static unsigned int instances; - explicit type() { if (instances == 5) { throw true; } instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -31,70 +28,55 @@ private: unsigned int type::instances = 0; -int main() { - BOOST_TEST(type::instances == 0); +int main() +{ try { boost::allocate_shared(std::allocator(), 6); BOOST_ERROR("allocate_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared(std::allocator(), 3); BOOST_ERROR("allocate_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared(std::allocator()); BOOST_ERROR("allocate_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared(std::allocator()); BOOST_ERROR("allocate_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared_noinit(std::allocator(), 6); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared_noinit(std::allocator(), 3); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared_noinit(std::allocator()); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::allocate_shared_noinit(std::allocator()); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - return boost::report_errors(); } diff --git a/test/allocate_shared_array_value_test.cpp b/test/allocate_shared_array_value_test.cpp index c1b8b7c..c6f08f9 100644 --- a/test/allocate_shared_array_value_test.cpp +++ b/test/allocate_shared_array_value_test.cpp @@ -1,15 +1,16 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + -int main() { +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include + +int main() +{ { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, 1); BOOST_TEST(a1[0] == 1); @@ -17,7 +18,6 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1); BOOST_TEST(a1[0] == 1); @@ -25,7 +25,6 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 4, 1); BOOST_TEST(a1[0] == 1); @@ -33,7 +32,6 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 1); BOOST_TEST(a1[0] == 1); @@ -41,6 +39,5 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - return boost::report_errors(); } diff --git a/test/allocate_shared_arrays_test.cpp b/test/allocate_shared_arrays_test.cpp index 9dfc866..7c45e72 100644 --- a/test/allocate_shared_arrays_test.cpp +++ b/test/allocate_shared_arrays_test.cpp @@ -1,15 +1,16 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + -int main() { +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include + +int main() +{ #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, {0, 1}); @@ -18,7 +19,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1 }); BOOST_TEST(a1[0][0] == 0); @@ -26,7 +26,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2, { 0, 1 }); BOOST_TEST(a1[0][0] == 0); @@ -34,7 +33,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), { 0, 1 }); BOOST_TEST(a1[0][0] == 0); @@ -43,6 +41,5 @@ int main() { BOOST_TEST(a1[1][1] == 1); } #endif - return boost::report_errors(); } diff --git a/test/make_shared_array_esft_test.cpp b/test/make_shared_array_esft_test.cpp index a93f760..8429919 100644 --- a/test/make_shared_array_esft_test.cpp +++ b/test/make_shared_array_esft_test.cpp @@ -1,28 +1,25 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include #include -#include +#include class type : public boost::enable_shared_from_this { public: static unsigned int instances; - explicit type() { instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -30,7 +27,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(3); @@ -41,7 +39,6 @@ int main() { BOOST_TEST(type::instances == 3); } } - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(3); @@ -52,6 +49,5 @@ int main() { BOOST_TEST(type::instances == 3); } } - return boost::report_errors(); } diff --git a/test/make_shared_array_noinit_test.cpp b/test/make_shared_array_noinit_test.cpp index 98bd450..4942569 100644 --- a/test/make_shared_array_noinit_test.cpp +++ b/test/make_shared_array_noinit_test.cpp @@ -1,28 +1,25 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include #include #include class type { public: static unsigned int instances; - explicit type() { instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -30,7 +27,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { boost::shared_ptr a1 = boost::make_shared_noinit(3); int* a2 = a1.get(); @@ -38,7 +36,6 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::make_shared_noinit(); int* a2 = a1.get(); @@ -46,19 +43,16 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::make_shared_noinit(2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - { boost::shared_ptr a1 = boost::make_shared_noinit(); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - { boost::shared_ptr a1 = boost::make_shared_noinit(3); const int* a2 = a1.get(); @@ -66,7 +60,6 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::make_shared_noinit(); const int* a2 = a1.get(); @@ -74,20 +67,16 @@ int main() { BOOST_TEST(a2 != 0); BOOST_TEST(size_t(a2) % boost::alignment_of::value == 0); } - { boost::shared_ptr a1 = boost::make_shared_noinit(2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - { boost::shared_ptr a1 = boost::make_shared_noinit(); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(3); type* a2 = a1.get(); @@ -99,8 +88,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(); type* a2 = a1.get(); @@ -112,8 +99,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(2); BOOST_TEST(a1.get() != 0); @@ -122,8 +107,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(); BOOST_TEST(a1.get() != 0); @@ -132,8 +115,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(3); const type* a2 = a1.get(); @@ -144,8 +125,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(); const type* a2 = a1.get(); @@ -156,8 +135,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(2); BOOST_TEST(a1.get() != 0); @@ -166,8 +143,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared_noinit(); BOOST_TEST(a1.get() != 0); @@ -176,6 +151,5 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - return boost::report_errors(); } diff --git a/test/make_shared_array_test.cpp b/test/make_shared_array_test.cpp index ebb76c7..de74198 100644 --- a/test/make_shared_array_test.cpp +++ b/test/make_shared_array_test.cpp @@ -1,28 +1,25 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include #include #include class type { public: static unsigned int instances; - explicit type() { instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -30,7 +27,8 @@ private: unsigned int type::instances = 0; -int main() { +int main() +{ { boost::shared_ptr a1 = boost::make_shared(3); int* a2 = a1.get(); @@ -41,7 +39,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::make_shared(); int* a2 = a1.get(); @@ -52,7 +49,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::make_shared(2); BOOST_TEST(a1.get() != 0); @@ -62,7 +58,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - { boost::shared_ptr a1 = boost::make_shared(); BOOST_TEST(a1.get() != 0); @@ -72,7 +67,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - { boost::shared_ptr a1 = boost::make_shared(3); const int* a2 = a1.get(); @@ -83,7 +77,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::make_shared(); const int* a2 = a1.get(); @@ -94,7 +87,6 @@ int main() { BOOST_TEST(a1[1] == 0); BOOST_TEST(a1[2] == 0); } - { boost::shared_ptr a1 = boost::make_shared(2); BOOST_TEST(a1.get() != 0); @@ -104,7 +96,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - { boost::shared_ptr a1 = boost::make_shared(); BOOST_TEST(a1.get() != 0); @@ -114,8 +105,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(3); type* a2 = a1.get(); @@ -127,8 +116,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(); type* a2 = a1.get(); @@ -140,8 +127,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(2); BOOST_TEST(a1.get() != 0); @@ -150,8 +135,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(); BOOST_TEST(a1.get() != 0); @@ -160,8 +143,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(3); const type* a2 = a1.get(); @@ -172,8 +153,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(); const type* a2 = a1.get(); @@ -184,8 +163,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(2); BOOST_TEST(a1.get() != 0); @@ -194,8 +171,6 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); { boost::shared_ptr a1 = boost::make_shared(); BOOST_TEST(a1.get() != 0); @@ -204,6 +179,5 @@ int main() { a1.reset(); BOOST_TEST(type::instances == 0); } - return boost::report_errors(); } diff --git a/test/make_shared_array_throws_test.cpp b/test/make_shared_array_throws_test.cpp index 151ab31..56c7372 100644 --- a/test/make_shared_array_throws_test.cpp +++ b/test/make_shared_array_throws_test.cpp @@ -1,29 +1,26 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include -#include +#include class type { public: static unsigned int instances; - explicit type() { if (instances == 5) { throw true; } instances++; } - ~type() { instances--; } - private: type(const type&); type& operator=(const type&); @@ -31,70 +28,55 @@ private: unsigned int type::instances = 0; -int main() { - BOOST_TEST(type::instances == 0); +int main() +{ try { boost::make_shared(6); BOOST_ERROR("make_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared(3); BOOST_ERROR("make_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared(); BOOST_ERROR("make_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared(); BOOST_ERROR("make_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared_noinit(6); BOOST_ERROR("make_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared_noinit(3); BOOST_ERROR("make_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared_noinit(); BOOST_ERROR("make_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - - BOOST_TEST(type::instances == 0); try { boost::make_shared_noinit(); BOOST_ERROR("make_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } - return boost::report_errors(); } diff --git a/test/make_shared_array_value_test.cpp b/test/make_shared_array_value_test.cpp index f042ede..185605d 100644 --- a/test/make_shared_array_value_test.cpp +++ b/test/make_shared_array_value_test.cpp @@ -1,15 +1,16 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#include -#include +(c) 2012-2015 Glen Joseph Fernandes + -int main() { +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ +#include +#include + +int main() +{ { boost::shared_ptr a1 = boost::make_shared(4, 1); BOOST_TEST(a1[0] == 1); @@ -17,7 +18,6 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - { boost::shared_ptr a1 = boost::make_shared(1); BOOST_TEST(a1[0] == 1); @@ -25,7 +25,6 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - { boost::shared_ptr a1 = boost::make_shared(4, 1); BOOST_TEST(a1[0] == 1); @@ -33,7 +32,6 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - { boost::shared_ptr a1 = boost::make_shared(1); BOOST_TEST(a1[0] == 1); @@ -41,6 +39,5 @@ int main() { BOOST_TEST(a1[2] == 1); BOOST_TEST(a1[3] == 1); } - return boost::report_errors(); } diff --git a/test/make_shared_arrays_test.cpp b/test/make_shared_arrays_test.cpp index b905a83..6c02db7 100644 --- a/test/make_shared_arrays_test.cpp +++ b/test/make_shared_arrays_test.cpp @@ -6,10 +6,11 @@ * Version 1.0. (See accompanying file LICENSE_1_0.txt * or copy at http://boost.org/LICENSE_1_0.txt) */ -#include -#include +#include +#include -int main() { +int main() +{ #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) { boost::shared_ptr a1 = boost::make_shared(2, {0, 1}); @@ -18,7 +19,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { boost::shared_ptr a1 = boost::make_shared({ 0, 1 }); BOOST_TEST(a1[0][0] == 0); @@ -26,7 +26,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { boost::shared_ptr a1 = boost::make_shared(2, { 0, 1 }); BOOST_TEST(a1[0][0] == 0); @@ -34,7 +33,6 @@ int main() { BOOST_TEST(a1[1][0] == 0); BOOST_TEST(a1[1][1] == 1); } - { boost::shared_ptr a1 = boost::make_shared({ 0, 1 }); BOOST_TEST(a1[0][0] == 0); @@ -43,6 +41,5 @@ int main() { BOOST_TEST(a1[1][1] == 1); } #endif - return boost::report_errors(); } From e13beef5dfd9186f17e9ed63fbd6fd96b48b3eb0 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 11 Nov 2015 01:26:15 -0500 Subject: [PATCH 4/9] Fix formatting in headers and tests --- include/boost/smart_ptr/make_unique.hpp | 27 +++++++++---------------- test/make_shared_arrays_test.cpp | 14 ++++++------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/include/boost/smart_ptr/make_unique.hpp b/include/boost/smart_ptr/make_unique.hpp index f1f4a7c..48191b7 100644 --- a/include/boost/smart_ptr/make_unique.hpp +++ b/include/boost/smart_ptr/make_unique.hpp @@ -24,16 +24,13 @@ struct up_if_object { }; template -struct up_if_object { -}; +struct up_if_object { }; template -struct up_if_object { -}; +struct up_if_object { }; template -struct up_if_array { -}; +struct up_if_array { }; template struct up_if_array { @@ -46,8 +43,7 @@ struct up_value { }; template -struct up_element { -}; +struct up_element { }; template struct up_element { @@ -56,8 +52,7 @@ struct up_element { } /* detail */ template -inline typename detail::up_if_object::type -make_unique() +inline typename detail::up_if_object::type make_unique() { return std::unique_ptr(new T()); } @@ -65,7 +60,7 @@ make_unique() #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template inline typename detail::up_if_object::type -make_unique(Args&&... args) + make_unique(Args&&... args) { return std::unique_ptr(new T(std::forward(args)...)); } @@ -73,21 +68,19 @@ make_unique(Args&&... args) template inline typename detail::up_if_object::type -make_unique(typename detail::up_value::type value) + make_unique(typename detail::up_value::type value) { return std::unique_ptr(new T(std::move(value))); } template -inline typename detail::up_if_object::type -make_unique_noinit() +inline typename detail::up_if_object::type make_unique_noinit() { return std::unique_ptr(new T); } template -inline typename detail::up_if_array::type -make_unique(std::size_t n) +inline typename detail::up_if_array::type make_unique(std::size_t n) { return std::unique_ptr(new typename detail::up_element::type[n]()); @@ -95,7 +88,7 @@ make_unique(std::size_t n) template inline typename detail::up_if_array::type -make_unique_noinit(std::size_t n) + make_unique_noinit(std::size_t n) { return std::unique_ptr(new typename detail::up_element::type[n]); diff --git a/test/make_shared_arrays_test.cpp b/test/make_shared_arrays_test.cpp index 6c02db7..7cd067f 100644 --- a/test/make_shared_arrays_test.cpp +++ b/test/make_shared_arrays_test.cpp @@ -1,11 +1,11 @@ /* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ +(c) 2012-2015 Glen Joseph Fernandes + + +Distributed under the Boost Software +License, Version 1.0. +http://boost.org/LICENSE_1_0.txt +*/ #include #include From e26542272dc92606dfe03a5f2249d0ca49100536 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 19 Feb 2016 08:09:25 -0500 Subject: [PATCH 5/9] Use remove_reference in make_unique implementation --- include/boost/smart_ptr/make_unique.hpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/include/boost/smart_ptr/make_unique.hpp b/include/boost/smart_ptr/make_unique.hpp index 48191b7..d054e3d 100644 --- a/include/boost/smart_ptr/make_unique.hpp +++ b/include/boost/smart_ptr/make_unique.hpp @@ -11,10 +11,7 @@ http://boost.org/LICENSE_1_0.txt #include #include - -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include -#endif namespace boost { namespace detail { @@ -38,8 +35,18 @@ struct up_if_array { }; template -struct up_value { - typedef T&& type; +struct up_remove_reference { + typedef T type; +}; + +template +struct up_remove_reference { + typedef T type; +}; + +template +struct up_remove_reference { + typedef T type; }; template @@ -68,7 +75,7 @@ inline typename detail::up_if_object::type template inline typename detail::up_if_object::type - make_unique(typename detail::up_value::type value) + make_unique(typename detail::up_remove_reference::type&& value) { return std::unique_ptr(new T(std::move(value))); } From 6d5f554baa9a148d39796577b6f4f254a353c10b Mon Sep 17 00:00:00 2001 From: Karolin Varner Date: Thu, 17 Dec 2015 12:35:14 +0100 Subject: [PATCH 6/9] Reuse code for plain and shared in ptr cast tests --- test/pointer_cast_test.cpp | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/test/pointer_cast_test.cpp b/test/pointer_cast_test.cpp index bd25dd1..ae036fb 100644 --- a/test/pointer_cast_test.cpp +++ b/test/pointer_cast_test.cpp @@ -104,33 +104,25 @@ bool check_const_pointer_cast(const BasePtr &ptr) const_cast(const_cast(boost::get_pointer(ptr))); } +template +void check_all_casts(const BasePtr &ptr) +{ +#if !defined( BOOST_NO_RTTI ) + BOOST_TEST( check_dynamic_pointer_cast( ptr ) ); +#endif + BOOST_TEST( check_static_pointer_cast( ptr ) ); + BOOST_TEST( check_const_pointer_cast( ptr ) ); +} + } int main() { - { - // Try casts with shared_ptr + boost::shared_ptr boost_shared(new derived); + base *plain = boost_shared.get(); - boost::shared_ptr ptr(new derived); - -#if !defined( BOOST_NO_RTTI ) - BOOST_TEST( check_dynamic_pointer_cast( ptr ) ); -#endif - BOOST_TEST( check_static_pointer_cast( ptr ) ); - BOOST_TEST( check_const_pointer_cast( ptr ) ); - } - - { - // Try casts with raw pointer - - boost::scoped_ptr ptr(new derived); - -#if !defined( BOOST_NO_RTTI ) - BOOST_TEST( check_dynamic_pointer_cast( ptr.get() ) ); -#endif - BOOST_TEST( check_static_pointer_cast( ptr.get() ) ); - BOOST_TEST( check_const_pointer_cast( ptr.get() ) ); - } + check_all_casts(boost_shared); + check_all_casts(plain); return boost::report_errors(); } From 2185c4f005e16073f3f91328ca7bee493b38dd56 Mon Sep 17 00:00:00 2001 From: Karolin Varner Date: Thu, 17 Dec 2015 12:46:41 +0100 Subject: [PATCH 7/9] Fix a documentation typo --- shared_ptr.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared_ptr.htm b/shared_ptr.htm index 5c756f8..1cd0bc4 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -222,7 +222,7 @@ void bad() shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws template<class T, class U> - shared_ptr<T> reinterpet_pointer_cast(shared_ptr<U> const & r); // never throws + shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r); // never throws template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p); From 6b787f1cec04c1022b28e0519073294870ccca99 Mon Sep 17 00:00:00 2001 From: Karolin Varner Date: Thu, 17 Dec 2015 13:47:00 +0100 Subject: [PATCH 8/9] Add overloads for std::shared_ptr to pointer casts --- include/boost/pointer_cast.hpp | 30 ++++++++ pointer_cast.html | 16 +++- test/Jamfile.v2 | 1 + test/cpp11_pointer_cast_test.cpp | 124 +++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 test/cpp11_pointer_cast_test.cpp diff --git a/include/boost/pointer_cast.hpp b/include/boost/pointer_cast.hpp index 6e532eb..3c65cac 100644 --- a/include/boost/pointer_cast.hpp +++ b/include/boost/pointer_cast.hpp @@ -42,4 +42,34 @@ inline T* reinterpret_pointer_cast(U *ptr) } // namespace boost +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + +#include + +namespace boost { + +//static_pointer_cast overload for std::shared_ptr +using std::static_pointer_cast; + +//dynamic_pointer_cast overload for std::shared_ptr +using std::dynamic_pointer_cast; + +//const_pointer_cast overload for std::shared_ptr +using std::const_pointer_cast; + +//reinterpret_pointer_cast overload for std::shared_ptr +template std::shared_ptr reinterpret_pointer_cast(const std::shared_ptr & r ) BOOST_NOEXCEPT +{ + (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) ); + + typedef typename std::shared_ptr::element_type E; + + E * p = reinterpret_cast< E* >( r.get() ); + return std::shared_ptr( r, p ); +} + +} // namespace boost + +#endif // #if !defined( BOOST_NO_CXX11_SMART_PTR ) + #endif //BOOST_POINTER_CAST_HPP diff --git a/pointer_cast.html b/pointer_cast.html index 2ab0859..4e52cf0 100644 --- a/pointer_cast.html +++ b/pointer_cast.html @@ -9,7 +9,7 @@ width="277" align="middle" border="0">pointer_cast

The pointer cast functions (boost::static_pointer_cast boost::dynamic_pointer_cast boost::reinterpret_pointer_cast boost::const_pointer_cast) - provide a way to write generic pointer castings for raw pointers. The functions + provide a way to write generic pointer castings for raw pointers and std::shared_ptr. The functions are defined in boost/pointer_cast.hpp.

There is test/example code in pointer_cast_test.cpp.

Rationale

@@ -23,7 +23,7 @@ template<class T, class U>

Pointer cast functions from boost/pointer_cast.hpp are overloads of boost::static_pointer_cast, boost::dynamic_pointer_cast, boost::reinterpret_pointer_cast and boost::const_pointer_cast - for raw pointers. This way when developing pointer type independent classes, + for raw pointers and std::shared_ptr. This way when developing pointer type independent classes, for example, memory managers or shared memory compatible classes, the same code can be used for raw and smart pointers.

Synopsis

@@ -46,6 +46,18 @@ inline T* const_pointer_cast(U *ptr) template<class T, class U> inline T* reinterpret_pointer_cast(U *ptr) { return reinterpret_cast<T*>(ptr); } + +template<class T, class U> +inline std::shared_ptr<U> static_pointer_cast(std::shared_ptr<T> ptr); + +template<class T, class U> +inline std::shared_ptr<U> dynamic_pointer_cast(std::shared_ptr<T> ptr); + +template<class T, class U> +inline std::shared_ptr<U> const_pointer_cast(std::shared_ptr<T> ptr); + +template<class T, class U> +inline std::shared_ptr<U> reinterpret_pointer_cast(std::shared_ptr<T> ptr); } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d965bfd..6eb4c89 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -29,6 +29,7 @@ import testing ; [ compile-fail shared_ptr_compare_fail.cpp ] [ run shared_ptr_alloc2_test.cpp ] [ run pointer_cast_test.cpp ] + [ run cpp11_pointer_cast_test.cpp ] [ compile pointer_to_other_test.cpp ] [ run auto_ptr_rv_test.cpp ] [ run shared_ptr_alias_test.cpp ] diff --git a/test/cpp11_pointer_cast_test.cpp b/test/cpp11_pointer_cast_test.cpp new file mode 100644 index 0000000..a937708 --- /dev/null +++ b/test/cpp11_pointer_cast_test.cpp @@ -0,0 +1,124 @@ +// +// cpp11_pointer_cast_test.cpp - a test for boost/pointer_cast.hpp with std::shared_ptr +// +// Copyright (c) 2016 Karolin Varner +// +// 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 +#include +#include +#include + +#include + +namespace +{ + +// Let's create these inheritance relationship: +// +// base base2 +// | | +// derived +// | +// derived_derived +// + +class base +{ + public: + virtual ~base(){} + int filler [5]; +}; + +class base2 +{ +public: + + virtual ~base2(){} + int filler [5]; +}; + +class derived + : public base, public base2 +{ + int filler [5]; +}; + +class derived_derived + : public derived +{ + int filler [5]; +}; + +// And now some simple check functions + +#if !defined( BOOST_NO_RTTI ) + +template +bool check_dynamic_pointer_cast(const BasePtr &ptr) +{ + //Check that dynamic_pointer_cast versus dynamic_cast + return + //Correct cast with dynamic_pointer_cast + boost::get_pointer(boost::dynamic_pointer_cast(ptr)) == + //Correct cast with dynamic_cast + dynamic_cast(boost::get_pointer(ptr)) + && + //Incorrect cast with dynamic_pointer_cast + boost::get_pointer(boost::dynamic_pointer_cast(ptr)) == + //Incorrect cast with dynamic_cast + dynamic_cast(boost::get_pointer(ptr)); +} + +#endif + +template +bool check_static_pointer_cast(const BasePtr &ptr) +{ + return + //Cast base -> derived -> base2 using static_pointer_cast + boost::get_pointer( + boost::static_pointer_cast( + boost::static_pointer_cast(ptr))) == + //Now the same with static_cast + static_cast(static_cast(boost::get_pointer(ptr))); +} + +template +bool check_const_pointer_cast(const BasePtr &ptr) +{ + return + //Unconst and const again using const_pointer_cast + boost::get_pointer( + boost::const_pointer_cast + (boost::const_pointer_cast(ptr))) == + //Now the same with const_cast + const_cast(const_cast(boost::get_pointer(ptr))); +} + +template +void check_all_casts(const BasePtr &ptr) +{ +#if !defined( BOOST_NO_RTTI ) + BOOST_TEST( check_dynamic_pointer_cast( ptr ) ); +#endif + BOOST_TEST( check_static_pointer_cast( ptr ) ); + BOOST_TEST( check_const_pointer_cast( ptr ) ); +} + +} + +int main() +{ +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + std::shared_ptr std_shared(new derived); + check_all_casts(std_shared); +#endif + + return boost::report_errors(); +} + From ce52fb10450c44c12ae9cd5560b5c88c3b3ea798 Mon Sep 17 00:00:00 2001 From: Karolin Varner Date: Thu, 17 Dec 2015 15:32:30 +0100 Subject: [PATCH 9/9] pointer_casts with move semantics for unique_ptr --- include/boost/pointer_cast.hpp | 48 ++++++++++++ pointer_cast.html | 67 ++++++++++++++++- test/cpp11_pointer_cast_test.cpp | 122 ++++++++++++++++++++++++++++--- 3 files changed, 222 insertions(+), 15 deletions(-) diff --git a/include/boost/pointer_cast.hpp b/include/boost/pointer_cast.hpp index 3c65cac..6a5af8b 100644 --- a/include/boost/pointer_cast.hpp +++ b/include/boost/pointer_cast.hpp @@ -7,6 +7,8 @@ // ////////////////////////////////////////////////////////////////////////////// +#include + #ifndef BOOST_POINTER_CAST_HPP #define BOOST_POINTER_CAST_HPP @@ -44,10 +46,27 @@ inline T* reinterpret_pointer_cast(U *ptr) #if !defined( BOOST_NO_CXX11_SMART_PTR ) +#include + +#include +#include +#include + #include namespace boost { +namespace detail { + +template +void assert_safe_moving_upcast() { + BOOST_STATIC_ASSERT_MSG( !(boost::is_base_of::value && !boost::is_pod::value && !boost::has_virtual_destructor::value) + , "Upcast from a non-POD child to a base without virtual destructor is unsafe, because the child's destructor " + "will not be called when the base pointer is deleted. Consider using shared_ptr for such types."); +} + +} + //static_pointer_cast overload for std::shared_ptr using std::static_pointer_cast; @@ -68,6 +87,35 @@ template std::shared_ptr reinterpret_pointer_cast(const std return std::shared_ptr( r, p ); } +//static_pointer_cast overload for std::unique_ptr +template std::unique_ptr static_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT +{ + detail::assert_safe_moving_upcast(); + return std::unique_ptr( static_cast( r.release() ) ); +} + +//dynamic_pointer_cast overload for std::unique_ptr +template std::unique_ptr dynamic_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT +{ + detail::assert_safe_moving_upcast(); + + T * p = dynamic_cast( r.get() ); + if( p ) r.release(); + return std::unique_ptr( p ); +} + +//const_pointer_cast overload for std::unique_ptr +template std::unique_ptr const_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT +{ + return std::unique_ptr( const_cast( r.release() ) ); +} + +//reinterpret_pointer_cast overload for std::unique_ptr +template std::unique_ptr reinterpret_pointer_cast( std::unique_ptr && r ) BOOST_NOEXCEPT +{ + return std::unique_ptr( reinterpret_cast( r.release() ) ); +} + } // namespace boost #endif // #if !defined( BOOST_NO_CXX11_SMART_PTR ) diff --git a/pointer_cast.html b/pointer_cast.html index 4e52cf0..f0c7fa2 100644 --- a/pointer_cast.html +++ b/pointer_cast.html @@ -9,7 +9,7 @@ width="277" align="middle" border="0">pointer_cast

The pointer cast functions (boost::static_pointer_cast boost::dynamic_pointer_cast boost::reinterpret_pointer_cast boost::const_pointer_cast) - provide a way to write generic pointer castings for raw pointers and std::shared_ptr. The functions + provide a way to write generic pointer castings for raw pointers, std::shared_ptr and std::unique_ptr. The functions are defined in boost/pointer_cast.hpp.

There is test/example code in pointer_cast_test.cpp.

Rationale

@@ -23,7 +23,7 @@ template<class T, class U>

Pointer cast functions from boost/pointer_cast.hpp are overloads of boost::static_pointer_cast, boost::dynamic_pointer_cast, boost::reinterpret_pointer_cast and boost::const_pointer_cast - for raw pointers and std::shared_ptr. This way when developing pointer type independent classes, + for raw pointers, std::shared_ptr and std::unique_ptr. This way when developing pointer type independent classes, for example, memory managers or shared memory compatible classes, the same code can be used for raw and smart pointers.

Synopsis

@@ -58,12 +58,71 @@ inline std::shared_ptr<U> const_pointer_cast(std::shared_ptr<T> ptr) template<class T, class U> inline std::shared_ptr<U> reinterpret_pointer_cast(std::shared_ptr<T> ptr); + +template<class T, class U> +inline std::unique_ptr<U> static_pointer_cast(std::unique_ptr<T> &&ptr); + +template<class T, class U> +inline std::unique_ptr<U> dynamic_pointer_cast(std::unique_ptr<T> &&ptr); + +template<class T, class U> +inline std::unique_ptr<U> const_pointer_cast(std::unique_ptr<T> &&ptr); + +template<class T, class U> +inline std::unique_ptr<U> reinterpret_pointer_cast(std::unique_ptr<T> &&ptr); } // namespace boost -

As you can see from the above synopsis, the pointer cast functions are just - wrappers around standard C++ cast operators.

+

As you can see from the above synopsis, the pointer cast functions for raw pointers are just + wrappers around standard C++ cast operators.

+ +

Memory Safety

+

It is possible to write unsafe code, when upcasting to a base type without virtual destructor. + Consider the following example:

+
+#include <memory>
+#include <utility>
+#include <boost/pointer_cast.hpp>
+#include <boost/make_unique.hpp>
+
+int destructed = 0;
+
+struct base {
+  ~base() {
+    // ...
+  }
+};
+
+struct child : base {
+  virtual ~child() {
+    destructed++;
+  }
+}
+
+int main() {
+  {
+    std::unique_ptr tmp = boost::make_unique();
+    std::unique_ptr sink = boost::static_pointer_cast( std::move(tmp) );
+  }
+
+  // child::~child was never called
+  assert(destructed == 0);
+
+  return 0;
+}
+
+

In this example, the child destructor child::~child was never called, because the child* in tmp + was downcast to a base* and moved into sink. The destructor of tmp did essentially nothing, because + it contained nullptr during destruction; sink deleted the pointer, but since base::~base is non-virtual + the child destructor was never called.

+

boost::static_pointer_cast and boost::dynamic_pointer_cast for std::unique_ptr prevent the above scenario + by raising a compiler error when such a cast is detected.

+

The overloads for std::shared_ptr and boost::shared_ptr are not prone to this problem, since they internally + always store the original pointer with the original type.

+

The plain pointer casts are in principle also prone to that problem, but it is assumed that raw pointers + are non-owning, so no checking is performed.

+

Example

diff --git a/test/cpp11_pointer_cast_test.cpp b/test/cpp11_pointer_cast_test.cpp
index a937708..a9361c3 100644
--- a/test/cpp11_pointer_cast_test.cpp
+++ b/test/cpp11_pointer_cast_test.cpp
@@ -1,5 +1,5 @@
 //
-//  cpp11_pointer_cast_test.cpp - a test for boost/pointer_cast.hpp with std::shared_ptr
+//  cpp11_pointer_cast_test.cpp - a test for boost/pointer_cast.hpp with std::shared_ptr and std::unique_ptr
 //
 //  Copyright (c) 2016 Karolin Varner
 //
@@ -8,12 +8,28 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 
-#include 
 #include 
+
+#include 
 #include 
 #include 
+#include 
 
 #include 
+#include 
+#include 
+
+#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) \
+ || defined( BOOST_NO_CXX11_HDR_FUNCTIONAL ) \
+ || defined( BOOST_NO_CXX11_HDR_UTILITY ) \
+ || defined( BOOST_NO_CXX11_LAMBDAS ) \
+ || defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+// We expect all the features or none of the features to be
+// available, since we should be on C++11
+int main() { return 0; }
+
+#else
 
 namespace
 {
@@ -43,7 +59,7 @@ public:
 };
 
 class derived
-   : public base, public base2 
+   : public base, public base2
 {
     int filler [5];
 };
@@ -66,7 +82,7 @@ bool check_dynamic_pointer_cast(const BasePtr &ptr)
    //Correct cast with dynamic_pointer_cast
    boost::get_pointer(boost::dynamic_pointer_cast(ptr)) ==
       //Correct cast with dynamic_cast
-      dynamic_cast(boost::get_pointer(ptr)) 
+      dynamic_cast(boost::get_pointer(ptr))
    &&
    //Incorrect cast with dynamic_pointer_cast
    boost::get_pointer(boost::dynamic_pointer_cast(ptr)) ==
@@ -91,7 +107,7 @@ bool check_static_pointer_cast(const BasePtr &ptr)
 template 
 bool check_const_pointer_cast(const BasePtr &ptr)
 {
-   return   
+   return
    //Unconst and const again using const_pointer_cast
    boost::get_pointer(
       boost::const_pointer_cast
@@ -101,7 +117,7 @@ bool check_const_pointer_cast(const BasePtr &ptr)
 }
 
 template 
-void check_all_casts(const BasePtr &ptr)
+void check_all_copy_casts(const BasePtr &ptr)
 {
 #if !defined( BOOST_NO_RTTI )
    BOOST_TEST( check_dynamic_pointer_cast( ptr ) );
@@ -110,15 +126,99 @@ void check_all_casts(const BasePtr &ptr)
    BOOST_TEST( check_const_pointer_cast( ptr ) );
 }
 
+
+#if !defined( BOOST_NO_RTTI )
+
+template 
+bool check_dynamic_moving_pointer_cast(std::function f)
+{
+   BasePtr smart1 = f(), smart2 = f();
+   derived* expect1 = dynamic_cast(boost::get_pointer(smart1));
+   derived_derived* expect2 = dynamic_cast(boost::get_pointer(smart2));
+   //Check that dynamic_pointer_cast versus dynamic_cast
+   return
+   //Correct cast with dynamic_pointer_cast
+   boost::get_pointer(boost::dynamic_pointer_cast( std::move(smart1) )) == expect1
+   &&
+   //Incorrect cast with dynamic_pointer_cast
+   boost::get_pointer(boost::dynamic_pointer_cast( std::move(smart2) )) == expect2;
+}
+
+#endif
+
+template 
+bool check_static_moving_pointer_cast(std::function f)
+{
+   BasePtr smart = f();
+   base2 *expect = static_cast(static_cast(boost::get_pointer(smart)));
+
+   return
+   //Cast base -> derived -> base2 using static_pointer_cast
+   boost::get_pointer(
+            boost::static_pointer_cast(
+               boost::static_pointer_cast( std::move(smart) ))) ==
+   //Now the same with static_cast
+   expect;
+}
+
+template 
+bool check_const_moving_pointer_cast(std::function f)
+{
+   BasePtr smart = f();
+   const base *expect = const_cast(const_cast(boost::get_pointer(smart)));
+   return
+   //Unconst and const again using const_pointer_cast
+   boost::get_pointer(
+      boost::const_pointer_cast
+         (boost::const_pointer_cast( std::move(smart) ))) ==
+   //Now the same with const_cast
+   expect;
+}
+
+template 
+void check_all_moving_casts(std::function f) {
+#if !defined( BOOST_NO_RTTI )
+   BOOST_TEST( check_dynamic_moving_pointer_cast( f ) );
+#endif
+   BOOST_TEST( check_static_moving_pointer_cast( f ) );
+   BOOST_TEST( check_const_moving_pointer_cast( f ) );
+}
+
 }
 
 int main()
 {
-#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
    std::shared_ptr std_shared(new derived);
-   check_all_casts(std_shared);
-#endif
+   boost::shared_ptr boost_shared(new derived);
+   base *plain = boost_shared.get();
 
-   return boost::report_errors();
+   // plain & boost::shared_ptr moving pointer_cast checks; there
+   // is no specific handleing for those types at the moment; this
+   // test just makes sure they won't break when std::move() is used
+   // in generic code
+
+   check_all_moving_casts>([&boost_shared]() {
+       return boost_shared;
+   });
+
+   check_all_moving_casts([plain]() {
+       return plain;
+   });
+
+   // std::shared_ptr casts
+
+   check_all_copy_casts(std_shared);
+   check_all_moving_casts>([&std_shared]() {
+       return std_shared;
+   });
+
+   // std::unique_ptr casts
+
+   check_all_moving_casts>([]() {
+       return std::unique_ptr(new derived);
+   });
+
+    return boost::report_errors();
 }
-
+#endif