diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:24:46 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:25:39 +0900 |
commit | 4fadd968fa12130524c8380f33fcfe25d4de79e5 (patch) | |
tree | fd26a490cd15388d42fc6652b3c5c13012e7f93e /libs/smart_ptr/test | |
parent | b5c87084afaef42b2d058f68091be31988a6a874 (diff) | |
download | boost-4fadd968fa12130524c8380f33fcfe25d4de79e5.tar.gz boost-4fadd968fa12130524c8380f33fcfe25d4de79e5.tar.bz2 boost-4fadd968fa12130524c8380f33fcfe25d4de79e5.zip |
Imported Upstream version 1.65.0upstream/1.65.0
Change-Id: Icf8400b375482cb11bcf77440a6934ba360d6ba4
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'libs/smart_ptr/test')
59 files changed, 8537 insertions, 279 deletions
diff --git a/libs/smart_ptr/test/Jamfile b/libs/smart_ptr/test/Jamfile new file mode 100644 index 0000000000..bab6fa8698 --- /dev/null +++ b/libs/smart_ptr/test/Jamfile @@ -0,0 +1,261 @@ +# Boost.SmartPtr Library test Jamfile +# +# Copyright (c) 2003-2017 Peter Dimov +# Copyright (c) 2003 Dave Abrahams +# +# 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) + +# bring in rules for testing +import testing ; + +run smart_ptr_test.cpp ; +run shared_ptr_basic_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ; +run shared_ptr_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ; +run weak_ptr_test.cpp ; +run weak_ptr_move_test.cpp ; +run shared_from_this_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ; +run get_deleter_test.cpp ; +run intrusive_ptr_test.cpp ; +run intrusive_ptr_move_test.cpp ; +run intrusive_ref_counter_test.cpp ; +run atomic_count_test.cpp ; +run lw_mutex_test.cpp ; +compile-fail shared_ptr_assign_fail.cpp ; +compile-fail shared_ptr_delete_fail.cpp ; +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 ; +run shared_ptr_rv_test.cpp ; +run shared_ptr_rv_pointer_cast_test.cpp ; +run shared_ptr_move_test.cpp ; +run shared_ptr_alias_move_test.cpp ; +run shared_ptr_reinterpret_pointer_cast_test.cpp ; +compile-fail shared_ptr_pv_fail.cpp ; +run sp_unary_addr_test.cpp ; +compile-fail scoped_ptr_eq_fail.cpp ; +compile-fail scoped_array_eq_fail.cpp ; +run esft_regtest.cpp ; +run yield_k_test.cpp ; +run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ; +run spinlock_test.cpp ; +run spinlock_try_test.cpp ; +run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ; +run spinlock_pool_test.cpp ; +run make_shared_test.cpp ; +run make_shared_move_emulation_test.cpp ; +run make_shared_perfect_forwarding_test.cpp ; +run shared_ptr_convertible_test.cpp ; +run wp_convertible_test.cpp ; +run ip_convertible_test.cpp ; +run allocate_shared_test.cpp ; +run sp_atomic_test.cpp ; +run esft_void_test.cpp ; +run esft_second_ptr_test.cpp ; +run make_shared_esft_test.cpp ; +run allocate_shared_esft_test.cpp ; +run sp_recursive_assign_test.cpp ; +run sp_recursive_assign2_test.cpp ; +run sp_recursive_assign_rv_test.cpp ; +run sp_recursive_assign2_rv_test.cpp ; +compile-fail auto_ptr_lv_fail.cpp ; +run atomic_count_test2.cpp ; +run sp_typeinfo_test.cpp ; +compile make_shared_fp_test.cpp ; +run sp_hash_test.cpp ; +run get_deleter_array_test.cpp ; +run ip_hash_test.cpp ; +run owner_less_test.cpp ; +run sp_unique_ptr_test.cpp ; +run sp_array_test.cpp ; +compile sp_array_cv_test.cpp ; +run sp_convertible_test.cpp ; +run sp_array_n_test.cpp ; +run sp_array_cast_test.cpp ; +run sp_zero_compare_test.cpp ; +run sp_nullptr_test.cpp ; +run sa_nullptr_test.cpp ; +run shared_ptr_alloc3_test.cpp ; +run shared_ptr_alloc11_test.cpp ; +run shared_ptr_alloc_construct11_test.cpp ; +run allocate_shared_alloc11_test.cpp ; +run allocate_shared_construct11_test.cpp ; +run sp_interlocked_test.cpp ; + +compile-fail array_fail_spa_sp_c.cpp ; +compile-fail array_fail_sp_spa_c.cpp ; +compile-fail array_fail_spa_spa_c.cpp ; +compile-fail array_fail_spa_wp_c.cpp ; +compile-fail array_fail_sp_wpa_c.cpp ; +compile-fail array_fail_spa_wpa_c.cpp ; +compile-fail array_fail_wpa_wp_c.cpp ; +compile-fail array_fail_wp_wpa_c.cpp ; +compile-fail array_fail_wpa_wpa_c.cpp ; +compile-fail array_fail_ap_spa_c.cpp ; +compile-fail array_fail_upa_sp_c.cpp ; +compile-fail array_fail_up_spa_c.cpp ; + +compile-fail array_fail_spa_sp_mc.cpp ; +compile-fail array_fail_sp_spa_mc.cpp ; +compile-fail array_fail_spa_spa_mc.cpp ; +compile-fail array_fail_spa_wp_mc.cpp ; +compile-fail array_fail_sp_wpa_mc.cpp ; +compile-fail array_fail_spa_wpa_mc.cpp ; +compile-fail array_fail_wpa_wp_mc.cpp ; +compile-fail array_fail_wp_wpa_mc.cpp ; +compile-fail array_fail_wpa_wpa_mc.cpp ; +compile-fail array_fail_ap_spa_mc.cpp ; +compile-fail array_fail_upa_sp_mc.cpp ; +compile-fail array_fail_up_spa_mc.cpp ; + +compile-fail array_fail_spa_sp_a.cpp ; +compile-fail array_fail_sp_spa_a.cpp ; +compile-fail array_fail_spa_spa_a.cpp ; +compile-fail array_fail_spa_wp_a.cpp ; +compile-fail array_fail_sp_wpa_a.cpp ; +compile-fail array_fail_spa_wpa_a.cpp ; +compile-fail array_fail_wpa_wp_a.cpp ; +compile-fail array_fail_wp_wpa_a.cpp ; +compile-fail array_fail_wpa_wpa_a.cpp ; +compile-fail array_fail_ap_spa_a.cpp ; +compile-fail array_fail_upa_sp_a.cpp ; +compile-fail array_fail_up_spa_a.cpp ; + +compile-fail array_fail_spa_sp_ma.cpp ; +compile-fail array_fail_sp_spa_ma.cpp ; +compile-fail array_fail_spa_spa_ma.cpp ; +compile-fail array_fail_spa_wp_ma.cpp ; +compile-fail array_fail_sp_wpa_ma.cpp ; +compile-fail array_fail_spa_wpa_ma.cpp ; +compile-fail array_fail_wpa_wp_ma.cpp ; +compile-fail array_fail_wp_wpa_ma.cpp ; +compile-fail array_fail_wpa_wpa_ma.cpp ; +compile-fail array_fail_ap_spa_ma.cpp ; +compile-fail array_fail_upa_sp_ma.cpp ; +compile-fail array_fail_up_spa_ma.cpp ; + +compile-fail array_fail_dereference.cpp ; +compile-fail array_fail_member_access.cpp ; +compile-fail array_fail_array_access.cpp ; + +run make_shared_array_test.cpp ; +run make_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ; +run make_shared_array_throws_test.cpp ; +run make_shared_array_esft_test.cpp ; +run make_shared_array_noinit_test.cpp ; +run make_shared_array_value_test.cpp ; +run allocate_shared_array_test.cpp ; +run allocate_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ; +run allocate_shared_array_throws_test.cpp ; +run allocate_shared_array_esft_test.cpp ; +run allocate_shared_array_noinit_test.cpp ; +run allocate_shared_array_value_test.cpp ; +run allocate_shared_array_construct_test.cpp ; + +run make_unique_test.cpp ; +run make_unique_args_test.cpp ; +run make_unique_value_test.cpp ; +run make_unique_noinit_test.cpp ; +run make_unique_throws_test.cpp ; +run make_unique_array_test.cpp ; +run make_unique_array_noinit_test.cpp ; +run make_unique_array_throws_test.cpp ; + +run shared_from_raw_test.cpp ; +run shared_from_raw_test2.cpp ; +run shared_from_raw_test3.cpp ; +run shared_from_raw_test4.cpp ; +run shared_from_raw_test5.cpp ; +run shared_from_raw_test6.cpp ; + +run weak_from_raw_test.cpp ; +run weak_from_raw_test2.cpp ; +run weak_from_raw_test3.cpp ; +run weak_from_raw_test4.cpp ; +run weak_from_raw_test5.cpp ; + +compile sp_explicit_inst_test.cpp ; + +run weak_from_this_test.cpp ; +run weak_from_this_test2.cpp ; + +run sp_bml_unique_ptr_test.cpp ; + +run sp_hash_test2.cpp ; +run sp_hash_test3.cpp ; + +run pointer_cast_test2.cpp ; + +compile-fail pointer_cast_st_fail.cpp ; +compile-fail pointer_cast_st_fail2.cpp ; +compile-fail pointer_cast_st_fail3.cpp ; + +compile-fail pointer_cast_co_fail.cpp ; +compile-fail pointer_cast_co_fail2.cpp ; +compile-fail pointer_cast_co_fail3.cpp ; + +compile-fail pointer_cast_dy_fail.cpp ; +compile-fail pointer_cast_dy_fail2.cpp ; +compile-fail pointer_cast_dy_fail3.cpp ; + +run sp_nothrow_test.cpp ; + +compile make_shared_msvc_test.cpp ; + +compile lwm_win32_cs_test.cpp ; + +run atomic_sp_test.cpp ; + +run sp_constexpr_test.cpp ; +run sp_constexpr_test2.cpp ; + +run atomic_sp_constexpr_test.cpp ; + +run shared_ptr_fn_test.cpp ; + +run get_deleter_test2.cpp ; +run get_deleter_test3.cpp ; +run get_deleter_array_test2.cpp ; +run get_deleter_array_test3.cpp ; + +run sp_convertible_test2.cpp ; + +run local_sp_test.cpp ; +run lsp_array_test.cpp ; +run lsp_array_n_test.cpp ; +run lsp_array_cv_test.cpp ; +run lsp_array_cast_test.cpp ; + +run get_local_deleter_test.cpp ; +run get_local_deleter_test2.cpp ; +run get_local_deleter_test3.cpp ; +run get_local_deleter_array_test.cpp ; +run get_local_deleter_array_test2.cpp ; + +run make_local_shared_test.cpp ; +run make_local_shared_esft_test.cpp ; +run allocate_local_shared_test.cpp ; +run allocate_local_shared_esft_test.cpp ; + +run make_local_shared_array_test.cpp ; +run make_local_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ; +run make_local_shared_array_throws_test.cpp ; +run make_local_shared_array_esft_test.cpp ; +run make_local_shared_array_noinit_test.cpp ; +run make_local_shared_array_value_test.cpp ; +run allocate_local_shared_array_test.cpp ; +run allocate_local_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ; +run allocate_local_shared_array_throws_test.cpp ; +run allocate_local_shared_array_esft_test.cpp ; +run allocate_local_shared_array_noinit_test.cpp ; +run allocate_local_shared_array_value_test.cpp ; +run allocate_local_shared_array_construct_test.cpp ; + +run local_sp_fn_test.cpp ; +run lsp_convertible_test.cpp ; +run lsp_convertible_test2.cpp ; diff --git a/libs/smart_ptr/test/Jamfile.v2 b/libs/smart_ptr/test/Jamfile.v2 deleted file mode 100644 index 528fe06069..0000000000 --- a/libs/smart_ptr/test/Jamfile.v2 +++ /dev/null @@ -1,212 +0,0 @@ -# Boost.SmartPtr Library test Jamfile -# -# Copyright (c) 2003-2013 Peter Dimov -# Copyright (c) 2003 Dave Abrahams -# -# 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) - -# bring in rules for testing -import testing ; - -{ - test-suite "smart_ptr" - : [ run smart_ptr_test.cpp ] - [ run shared_ptr_basic_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ] - [ run shared_ptr_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ] - [ run weak_ptr_test.cpp ] - [ run weak_ptr_move_test.cpp ] - [ run shared_from_this_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ] - [ run get_deleter_test.cpp ] - [ run intrusive_ptr_test.cpp ] - [ run intrusive_ptr_move_test.cpp ] - [ run intrusive_ref_counter_test.cpp ] - [ run atomic_count_test.cpp ] - [ run lw_mutex_test.cpp ] - [ compile-fail shared_ptr_assign_fail.cpp ] - [ compile-fail shared_ptr_delete_fail.cpp ] - [ 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 ] - [ run shared_ptr_rv_test.cpp ] - [ run shared_ptr_rv_pointer_cast_test.cpp ] - [ run shared_ptr_move_test.cpp ] - [ run shared_ptr_alias_move_test.cpp ] - [ run shared_ptr_reinterpret_pointer_cast_test.cpp ] - [ compile-fail shared_ptr_pv_fail.cpp ] - [ run sp_unary_addr_test.cpp ] - [ compile-fail scoped_ptr_eq_fail.cpp ] - [ compile-fail scoped_array_eq_fail.cpp ] - [ run esft_regtest.cpp ] - [ run yield_k_test.cpp ] - [ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ] - [ run spinlock_test.cpp ] - [ run spinlock_try_test.cpp ] - [ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ] - [ run spinlock_pool_test.cpp ] - [ run make_shared_test.cpp ] - [ run make_shared_move_emulation_test.cpp ] - [ run make_shared_perfect_forwarding_test.cpp ] - [ run shared_ptr_convertible_test.cpp ] - [ run wp_convertible_test.cpp ] - [ run ip_convertible_test.cpp ] - [ run allocate_shared_test.cpp ] - [ run sp_atomic_test.cpp ] - [ run esft_void_test.cpp ] - [ run esft_second_ptr_test.cpp ] - [ run make_shared_esft_test.cpp ] - [ run allocate_shared_esft_test.cpp ] - [ run sp_recursive_assign_test.cpp ] - [ run sp_recursive_assign2_test.cpp ] - [ run sp_recursive_assign_rv_test.cpp ] - [ run sp_recursive_assign2_rv_test.cpp ] - [ compile-fail auto_ptr_lv_fail.cpp ] - [ run atomic_count_test2.cpp ] - [ run sp_typeinfo_test.cpp ] - [ compile make_shared_fp_test.cpp ] - [ run sp_hash_test.cpp ] - [ run get_deleter_array_test.cpp ] - [ run ip_hash_test.cpp ] - [ run owner_less_test.cpp ] - [ run sp_unique_ptr_test.cpp ] - [ run sp_array_test.cpp ] - [ compile sp_array_cv_test.cpp ] - [ run sp_convertible_test.cpp ] - [ run sp_array_n_test.cpp ] - [ run sp_array_cast_test.cpp ] - [ run sp_zero_compare_test.cpp ] - [ run sp_nullptr_test.cpp ] - [ run sa_nullptr_test.cpp ] - [ run shared_ptr_alloc3_test.cpp ] - [ run shared_ptr_alloc11_test.cpp ] - [ run shared_ptr_alloc_construct11_test.cpp ] - [ run allocate_shared_alloc11_test.cpp ] - [ run allocate_shared_construct11_test.cpp ] - [ run sp_interlocked_test.cpp ] - - [ compile-fail array_fail_spa_sp_c.cpp ] - [ compile-fail array_fail_sp_spa_c.cpp ] - [ compile-fail array_fail_spa_spa_c.cpp ] - [ compile-fail array_fail_spa_wp_c.cpp ] - [ compile-fail array_fail_sp_wpa_c.cpp ] - [ compile-fail array_fail_spa_wpa_c.cpp ] - [ compile-fail array_fail_wpa_wp_c.cpp ] - [ compile-fail array_fail_wp_wpa_c.cpp ] - [ compile-fail array_fail_wpa_wpa_c.cpp ] - [ compile-fail array_fail_ap_spa_c.cpp ] - [ compile-fail array_fail_upa_sp_c.cpp ] - [ compile-fail array_fail_up_spa_c.cpp ] - - [ compile-fail array_fail_spa_sp_mc.cpp ] - [ compile-fail array_fail_sp_spa_mc.cpp ] - [ compile-fail array_fail_spa_spa_mc.cpp ] - [ compile-fail array_fail_spa_wp_mc.cpp ] - [ compile-fail array_fail_sp_wpa_mc.cpp ] - [ compile-fail array_fail_spa_wpa_mc.cpp ] - [ compile-fail array_fail_wpa_wp_mc.cpp ] - [ compile-fail array_fail_wp_wpa_mc.cpp ] - [ compile-fail array_fail_wpa_wpa_mc.cpp ] - [ compile-fail array_fail_ap_spa_mc.cpp ] - [ compile-fail array_fail_upa_sp_mc.cpp ] - [ compile-fail array_fail_up_spa_mc.cpp ] - - [ compile-fail array_fail_spa_sp_a.cpp ] - [ compile-fail array_fail_sp_spa_a.cpp ] - [ compile-fail array_fail_spa_spa_a.cpp ] - [ compile-fail array_fail_spa_wp_a.cpp ] - [ compile-fail array_fail_sp_wpa_a.cpp ] - [ compile-fail array_fail_spa_wpa_a.cpp ] - [ compile-fail array_fail_wpa_wp_a.cpp ] - [ compile-fail array_fail_wp_wpa_a.cpp ] - [ compile-fail array_fail_wpa_wpa_a.cpp ] - [ compile-fail array_fail_ap_spa_a.cpp ] - [ compile-fail array_fail_upa_sp_a.cpp ] - [ compile-fail array_fail_up_spa_a.cpp ] - - [ compile-fail array_fail_spa_sp_ma.cpp ] - [ compile-fail array_fail_sp_spa_ma.cpp ] - [ compile-fail array_fail_spa_spa_ma.cpp ] - [ compile-fail array_fail_spa_wp_ma.cpp ] - [ compile-fail array_fail_sp_wpa_ma.cpp ] - [ compile-fail array_fail_spa_wpa_ma.cpp ] - [ compile-fail array_fail_wpa_wp_ma.cpp ] - [ compile-fail array_fail_wp_wpa_ma.cpp ] - [ compile-fail array_fail_wpa_wpa_ma.cpp ] - [ compile-fail array_fail_ap_spa_ma.cpp ] - [ compile-fail array_fail_upa_sp_ma.cpp ] - [ compile-fail array_fail_up_spa_ma.cpp ] - - [ compile-fail array_fail_dereference.cpp ] - [ compile-fail array_fail_member_access.cpp ] - [ compile-fail array_fail_array_access.cpp ] - - [ run make_shared_array_test.cpp ] - [ run make_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ] - [ run make_shared_array_throws_test.cpp ] - [ run make_shared_array_esft_test.cpp ] - [ run make_shared_array_noinit_test.cpp ] - [ run make_shared_array_value_test.cpp ] - [ run allocate_shared_array_test.cpp ] - [ run allocate_shared_arrays_test.cpp : : : <toolset>gcc-4.6.3_0x:<cxxflags>-fno-deduce-init-list ] - [ run allocate_shared_array_throws_test.cpp ] - [ run allocate_shared_array_esft_test.cpp ] - [ run allocate_shared_array_noinit_test.cpp ] - [ run allocate_shared_array_value_test.cpp ] - [ run allocate_shared_array_construct_test.cpp ] - - [ run make_unique_test.cpp ] - [ run make_unique_args_test.cpp ] - [ run make_unique_value_test.cpp ] - [ run make_unique_noinit_test.cpp ] - [ run make_unique_throws_test.cpp ] - [ run make_unique_array_test.cpp ] - [ run make_unique_array_noinit_test.cpp ] - [ run make_unique_array_throws_test.cpp ] - - [ run shared_from_raw_test.cpp ] - [ run shared_from_raw_test2.cpp ] - [ run shared_from_raw_test3.cpp ] - [ run shared_from_raw_test4.cpp ] - [ run shared_from_raw_test5.cpp ] - [ run shared_from_raw_test6.cpp ] - - [ run weak_from_raw_test.cpp ] - [ run weak_from_raw_test2.cpp ] - [ run weak_from_raw_test3.cpp ] - [ run weak_from_raw_test4.cpp ] - [ run weak_from_raw_test5.cpp ] - - [ compile sp_explicit_inst_test.cpp ] - - [ run weak_from_this_test.cpp ] - [ run weak_from_this_test2.cpp ] - - [ run sp_bml_unique_ptr_test.cpp ] - - [ run sp_hash_test2.cpp ] - [ run sp_hash_test3.cpp ] - - [ run pointer_cast_test2.cpp ] - - [ compile-fail pointer_cast_st_fail.cpp ] - [ compile-fail pointer_cast_st_fail2.cpp ] - [ compile-fail pointer_cast_st_fail3.cpp ] - - [ compile-fail pointer_cast_co_fail.cpp ] - [ compile-fail pointer_cast_co_fail2.cpp ] - [ compile-fail pointer_cast_co_fail3.cpp ] - - [ compile-fail pointer_cast_dy_fail.cpp ] - [ compile-fail pointer_cast_dy_fail2.cpp ] - [ compile-fail pointer_cast_dy_fail3.cpp ] - - [ run sp_nothrow_test.cpp ] - - [ compile make_shared_msvc_test.cpp ] - ; -} diff --git a/libs/smart_ptr/test/allocate_local_shared_array_construct_test.cpp b/libs/smart_ptr/test/allocate_local_shared_array_construct_test.cpp new file mode 100644 index 0000000000..0f8bc1b8af --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_array_construct_test.cpp @@ -0,0 +1,165 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_ALLOCATOR) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +struct allow { }; + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } + + template<class U> + void construct(U* ptr) { + ::new(static_cast<void*>(ptr)) U(allow()); + } + + template<class U> + void destroy(U* ptr) { + ptr->~U(); + } + +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +class type { +public: + static unsigned instances; + + explicit type(allow) { + ++instances; + } + + ~type() { + --instances; + } + +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned type::instances = 0; + +int main() +{ + { + boost::local_shared_ptr<type[]> result = + boost::allocate_local_shared<type[]>(creator<type>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[3]> result = + boost::allocate_local_shared<type[3]>(creator<type>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[][2]> result = + boost::allocate_local_shared<type[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[2][2]> result = + boost::allocate_local_shared<type[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[]> result = + boost::allocate_local_shared<const type[]>(creator<>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[3]> result = + boost::allocate_local_shared<const type[3]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[][2]> result = + boost::allocate_local_shared<const type[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[2][2]> result = + boost::allocate_local_shared<const type[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_array_esft_test.cpp b/libs/smart_ptr/test/allocate_local_shared_array_esft_test.cpp new file mode 100644 index 0000000000..7138745b9c --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_array_esft_test.cpp @@ -0,0 +1,103 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/enable_shared_from_this.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +class type + : public boost::enable_shared_from_this<type> { +public: + static unsigned instances; + + type() { + ++instances; + } + + ~type() { + --instances; + } + +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned type::instances = 0; + +int main() +{ + BOOST_TEST(type::instances == 0); + { + boost::local_shared_ptr<type[]> result = + boost::allocate_local_shared<type[]>(creator<type>(), 3); + try { + result[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + BOOST_TEST(type::instances == 0); + { + boost::local_shared_ptr<type[]> result = + boost::allocate_local_shared_noinit<type[]>(creator<>(), 3); + try { + result[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_array_noinit_test.cpp b/libs/smart_ptr/test/allocate_local_shared_array_noinit_test.cpp new file mode 100644 index 0000000000..e2e16194f5 --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_array_noinit_test.cpp @@ -0,0 +1,254 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/align/is_aligned.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/smart_ptr/weak_ptr.hpp> +#include <boost/type_traits/alignment_of.hpp> + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +class type { +public: + static unsigned instances; + + type() + : value_(0.0) { + ++instances; + } + + ~type() { + --instances; + } + + void set(long double value) { + value_ = value; + } + + long double get() const { + return value_; + } + +private: + type(const type&); + type& operator=(const type&); + + long double value_; +}; + +unsigned type::instances = 0; + +int main() +{ + { + boost::local_shared_ptr<int[]> result = + boost::allocate_local_shared_noinit<int[]>(creator<int>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<int[3]> result = + boost::allocate_local_shared_noinit<int[3]>(creator<int>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<int[][2]> result = + boost::allocate_local_shared_noinit<int[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<int[2][2]> result = + boost::allocate_local_shared_noinit<int[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[]> result = + boost::allocate_local_shared_noinit<const int[]>(creator<>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[3]> result = + boost::allocate_local_shared_noinit<const int[3]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[][2]> result = + boost::allocate_local_shared_noinit<const int[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[2][2]> result = + boost::allocate_local_shared_noinit<const int[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<type[]> result = + boost::allocate_local_shared_noinit<type[]>(creator<type>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[3]> result = + boost::allocate_local_shared_noinit<type[3]>(creator<type>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[3]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[][2]> result = + boost::allocate_local_shared_noinit<type[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<type[][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[2][2]> result = + boost::allocate_local_shared_noinit<type[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<type[2][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[]> result = + boost::allocate_local_shared_noinit<const type[]>(creator<>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<const type[]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[3]> result = + boost::allocate_local_shared_noinit<const type[3]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<const type[3]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[][2]> result = + boost::allocate_local_shared_noinit<const + type[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<const type[][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[2][2]> result = + boost::allocate_local_shared_noinit<const type[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<const type[2][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_array_test.cpp b/libs/smart_ptr/test/allocate_local_shared_array_test.cpp new file mode 100644 index 0000000000..34f3d42f25 --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_array_test.cpp @@ -0,0 +1,275 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/align/is_aligned.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/smart_ptr/weak_ptr.hpp> +#include <boost/type_traits/alignment_of.hpp> + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +class type { +public: + static unsigned instances; + + type() + : value_(0.0) { + ++instances; + } + + ~type() { + --instances; + } + + void set(long double value) { + value_ = value; + } + + long double get() const { + return value_; + } + +private: + type(const type&); + type& operator=(const type&); + + long double value_; +}; + +unsigned type::instances = 0; + +int main() +{ + { + boost::local_shared_ptr<int[]> result = + boost::allocate_local_shared<int[]>(creator<int>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<int[3]> result = + boost::allocate_local_shared<int[3]>(creator<int>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<int[][2]> result = + boost::allocate_local_shared<int[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<int[2][2]> result = + boost::allocate_local_shared<int[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<const int[]> result = + boost::allocate_local_shared<const int[]>(creator<>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<const int[3]> result = + boost::allocate_local_shared<const int[3]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<const int[][2]> result = + boost::allocate_local_shared<const int[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<const int[2][2]> result = + boost::allocate_local_shared<const int[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<type[]> result = + boost::allocate_local_shared<type[]>(creator<type>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[]> w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[3]> result = + boost::allocate_local_shared<type[3]>(creator<type>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[3]> w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[][2]> result = + boost::allocate_local_shared<type[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[2][2]> result = + boost::allocate_local_shared<type[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[]> result = + boost::allocate_local_shared<const type[]>(creator<>(), 3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[3]> result = + boost::allocate_local_shared<const type[3]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[][2]> result = + boost::allocate_local_shared<const type[][2]>(creator<>(), 2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[2][2]> result = + boost::allocate_local_shared<const type[2][2]>(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_array_throws_test.cpp b/libs/smart_ptr/test/allocate_local_shared_array_throws_test.cpp new file mode 100644 index 0000000000..78ae6b6af2 --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_array_throws_test.cpp @@ -0,0 +1,130 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +class type { +public: + static unsigned instances; + + type() { + if (instances == 5) { + throw true; + } + ++instances; + } + + ~type() { + --instances; + } + +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned type::instances = 0; + +int main() +{ + try { + boost::allocate_local_shared<type[]>(creator<type>(), 6); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared<type[][2]>(creator<type>(), 3); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared<type[6]>(creator<>()); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared<type[3][2]>(creator<>()); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit<type[]>(creator<>(), 6); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit<type[][2]>(creator<>(), 3); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit<type[6]>(creator<>()); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit<type[3][2]>(creator<>()); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_array_value_test.cpp b/libs/smart_ptr/test/allocate_local_shared_array_value_test.cpp new file mode 100644 index 0000000000..7d9c35f082 --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_array_value_test.cpp @@ -0,0 +1,92 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +int main() +{ + { + boost::local_shared_ptr<int[]> result = + boost::allocate_local_shared<int[]>(creator<int>(), 4, 1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + { + boost::local_shared_ptr<int[4]> result = + boost::allocate_local_shared<int[4]>(creator<int>(), 1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + { + boost::local_shared_ptr<const int[]> result = + boost::allocate_local_shared<const int[]>(creator<>(), 4, 1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + { + boost::local_shared_ptr<const int[4]> result = + boost::allocate_local_shared<const int[4]>(creator<>(), 1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_arrays_test.cpp b/libs/smart_ptr/test/allocate_local_shared_arrays_test.cpp new file mode 100644 index 0000000000..d45a686174 --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_arrays_test.cpp @@ -0,0 +1,93 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +template<class T = void> +struct creator { + typedef T value_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator() { } + + template<class U> + creator(const creator<U>&) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template<class T, class U> +inline bool +operator==(const creator<T>&, const creator<U>&) +{ + return true; +} + +template<class T, class U> +inline bool +operator!=(const creator<T>&, const creator<U>&) +{ + return false; +} + +int main() +{ + { + boost::local_shared_ptr<int[][2]> result = + boost::allocate_local_shared<int[][2]>(creator<int>(), 2, {0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + { + boost::local_shared_ptr<int[2][2]> result = + boost::allocate_local_shared<int[2][2]>(creator<int>(), {0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + { + boost::local_shared_ptr<const int[][2]> result = + boost::allocate_local_shared<const int[][2]>(creator<>(), 2, {0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + { + boost::local_shared_ptr<const int[2][2]> result = + boost::allocate_local_shared<const int[2][2]>(creator<>(), {0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_esft_test.cpp b/libs/smart_ptr/test/allocate_local_shared_esft_test.cpp new file mode 100644 index 0000000000..65349c5357 --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_esft_test.cpp @@ -0,0 +1,298 @@ +// allocate_local_shared_esft_test.cpp +// +// Copyright 2007-2009, 2017 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 <boost/config.hpp> + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) + +int main() +{ +} + +#else + +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <memory> + +class X: public boost::enable_shared_from_this<X> +{ +private: + + X( X const & ); + X & operator=( X const & ); + +public: + + static int instances; + + explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +int main() +{ + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>() ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared_noinit< X >( std::allocator<void>() ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + { + boost::shared_ptr< X > px = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + BOOST_TEST_EQ( X::instances, 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST_EQ( px, qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST_EQ( X::instances, 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST_EQ( X::instances, 0 ); + + return boost::report_errors(); +} + +#endif diff --git a/libs/smart_ptr/test/allocate_local_shared_test.cpp b/libs/smart_ptr/test/allocate_local_shared_test.cpp new file mode 100644 index 0000000000..fa53dc06cd --- /dev/null +++ b/libs/smart_ptr/test/allocate_local_shared_test.cpp @@ -0,0 +1,235 @@ +// allocate_local_shared_test.cpp +// +// Copyright 2007-2009, 2017 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 <boost/config.hpp> + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) + +int main() +{ +} + +#else + +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <cstddef> + +class X +{ +private: + + X( X const & ); + X & operator=( X const & ); + + void * operator new( std::size_t n ) + { + // lack of this definition causes link errors on Comeau C++ + BOOST_ERROR( "private X::new called" ); + return ::operator new( n ); + } + + void operator delete( void * p ) + { + // lack of this definition causes link errors on MSVC + BOOST_ERROR( "private X::delete called" ); + ::operator delete( p ); + } + +public: + + static int instances; + + int v; + + explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +int main() +{ + { + boost::local_shared_ptr< int > pi = boost::allocate_local_shared< int >( std::allocator<int>() ); + + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( *pi == 0 ); + } + + { + boost::local_shared_ptr< int > pi = boost::allocate_local_shared_noinit< int >( std::allocator<int>() ); + + BOOST_TEST( pi.get() != 0 ); + } + + { + boost::local_shared_ptr< int > pi = boost::allocate_local_shared< int >( std::allocator<int>(), 5 ); + + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( *pi == 5 ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>() ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 0 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared_noinit< X >( std::allocator<void>() ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 0 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3+4 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3+4+5 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6+7 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::allocate_local_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + return boost::report_errors(); +} + +#endif diff --git a/libs/smart_ptr/test/allocate_shared_array_construct_test.cpp b/libs/smart_ptr/test/allocate_shared_array_construct_test.cpp index 669e8130b2..ef0dc95897 100644 --- a/libs/smart_ptr/test/allocate_shared_array_construct_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_array_construct_test.cpp @@ -5,13 +5,14 @@ Copyright 2012-2015 Glen Joseph Fernandes Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_ALLOCATOR) #include <boost/core/lightweight_test.hpp> #include <boost/smart_ptr/make_shared.hpp> -#if !defined(BOOST_NO_CXX11_ALLOCATOR) struct allow { }; -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -100,7 +101,7 @@ int main() } { boost::shared_ptr<type[][2]> result = - boost::allocate_shared<type[][2]>(creator<type>(), 2); + boost::allocate_shared<type[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(type::instances == 4); @@ -109,7 +110,7 @@ int main() } { boost::shared_ptr<type[2][2]> result = - boost::allocate_shared<type[2][2]>(creator<type>()); + boost::allocate_shared<type[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(type::instances == 4); @@ -118,7 +119,7 @@ int main() } { boost::shared_ptr<const type[]> result = - boost::allocate_shared<const type[]>(creator<type>(), 3); + boost::allocate_shared<const type[]>(creator<>(), 3); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(type::instances == 3); @@ -127,7 +128,7 @@ int main() } { boost::shared_ptr<const type[3]> result = - boost::allocate_shared<const type[3]>(creator<type>()); + boost::allocate_shared<const type[3]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(type::instances == 3); @@ -136,7 +137,7 @@ int main() } { boost::shared_ptr<const type[][2]> result = - boost::allocate_shared<const type[][2]>(creator<type>(), 2); + boost::allocate_shared<const type[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(type::instances == 4); @@ -145,7 +146,7 @@ int main() } { boost::shared_ptr<const type[2][2]> result = - boost::allocate_shared<const type[2][2]>(creator<type>()); + boost::allocate_shared<const type[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(type::instances == 4); diff --git a/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp b/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp index 0399c1a2f2..1e0afaf616 100644 --- a/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_array_esft_test.cpp @@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/smart_ptr/enable_shared_from_this.hpp> #include <boost/smart_ptr/make_shared.hpp> -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -82,7 +82,7 @@ int main() BOOST_TEST(type::instances == 0); { boost::shared_ptr<type[]> result = - boost::allocate_shared_noinit<type[]>(creator<type>(), 3); + boost::allocate_shared_noinit<type[]>(creator<>(), 3); try { result[0].shared_from_this(); BOOST_ERROR("shared_from_this did not throw"); diff --git a/libs/smart_ptr/test/allocate_shared_array_noinit_test.cpp b/libs/smart_ptr/test/allocate_shared_array_noinit_test.cpp index f30ee170a5..910d8f73bd 100644 --- a/libs/smart_ptr/test/allocate_shared_array_noinit_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_array_noinit_test.cpp @@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/smart_ptr/weak_ptr.hpp> #include <boost/type_traits/alignment_of.hpp> -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -98,7 +98,7 @@ int main() } { boost::shared_ptr<int[][2]> result = - boost::allocate_shared_noinit<int[][2]>(creator<int>(), 2); + boost::allocate_shared_noinit<int[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -106,7 +106,7 @@ int main() } { boost::shared_ptr<int[2][2]> result = - boost::allocate_shared_noinit<int[2][2]>(creator<int>()); + boost::allocate_shared_noinit<int[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -114,8 +114,7 @@ int main() } { boost::shared_ptr<const int[]> result = - boost::allocate_shared_noinit<const - int[]>(creator<int>(), 3); + boost::allocate_shared_noinit<const int[]>(creator<>(), 3); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -123,7 +122,7 @@ int main() } { boost::shared_ptr<const int[3]> result = - boost::allocate_shared_noinit<const int[3]>(creator<int>()); + boost::allocate_shared_noinit<const int[3]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -131,8 +130,7 @@ int main() } { boost::shared_ptr<const int[][2]> result = - boost::allocate_shared_noinit<const - int[][2]>(creator<int>(), 2); + boost::allocate_shared_noinit<const int[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -140,8 +138,7 @@ int main() } { boost::shared_ptr<const int[2][2]> result = - boost::allocate_shared_noinit<const - int[2][2]>(creator<int>()); + boost::allocate_shared_noinit<const int[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -173,7 +170,7 @@ int main() } { boost::shared_ptr<type[][2]> result = - boost::allocate_shared_noinit<type[][2]>(creator<type>(), 2); + boost::allocate_shared_noinit<type[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -185,7 +182,7 @@ int main() } { boost::shared_ptr<type[2][2]> result = - boost::allocate_shared_noinit<type[2][2]>(creator<type>()); + boost::allocate_shared_noinit<type[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -197,8 +194,7 @@ int main() } { boost::shared_ptr<const type[]> result = - boost::allocate_shared_noinit<const - type[]>(creator<type>(), 3); + boost::allocate_shared_noinit<const type[]>(creator<>(), 3); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -210,8 +206,7 @@ int main() } { boost::shared_ptr<const type[3]> result = - boost::allocate_shared_noinit<const - type[3]>(creator<type>()); + boost::allocate_shared_noinit<const type[3]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -224,7 +219,7 @@ int main() { boost::shared_ptr<const type[][2]> result = boost::allocate_shared_noinit<const - type[][2]>(creator<type>(), 2); + type[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -236,8 +231,7 @@ int main() } { boost::shared_ptr<const type[2][2]> result = - boost::allocate_shared_noinit<const - type[2][2]>(creator<type>()); + boost::allocate_shared_noinit<const type[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), diff --git a/libs/smart_ptr/test/allocate_shared_array_test.cpp b/libs/smart_ptr/test/allocate_shared_array_test.cpp index 03696313cf..d2854f9c46 100644 --- a/libs/smart_ptr/test/allocate_shared_array_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_array_test.cpp @@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/smart_ptr/weak_ptr.hpp> #include <boost/type_traits/alignment_of.hpp> -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -104,7 +104,7 @@ int main() } { boost::shared_ptr<int[][2]> result = - boost::allocate_shared<int[][2]>(creator<int>(), 2); + boost::allocate_shared<int[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -116,7 +116,7 @@ int main() } { boost::shared_ptr<int[2][2]> result = - boost::allocate_shared<int[2][2]>(creator<int>()); + boost::allocate_shared<int[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -128,7 +128,7 @@ int main() } { boost::shared_ptr<const int[]> result = - boost::allocate_shared<const int[]>(creator<int>(), 3); + boost::allocate_shared<const int[]>(creator<>(), 3); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -139,7 +139,7 @@ int main() } { boost::shared_ptr<const int[3]> result = - boost::allocate_shared<const int[3]>(creator<int>()); + boost::allocate_shared<const int[3]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -150,7 +150,7 @@ int main() } { boost::shared_ptr<const int[][2]> result = - boost::allocate_shared<const int[][2]>(creator<int>(), 2); + boost::allocate_shared<const int[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -162,7 +162,7 @@ int main() } { boost::shared_ptr<const int[2][2]> result = - boost::allocate_shared<const int[2][2]>(creator<int>()); + boost::allocate_shared<const int[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -198,7 +198,7 @@ int main() } { boost::shared_ptr<type[][2]> result = - boost::allocate_shared<type[][2]>(creator<type>(), 2); + boost::allocate_shared<type[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -209,7 +209,7 @@ int main() } { boost::shared_ptr<type[2][2]> result = - boost::allocate_shared<type[2][2]>(creator<type>()); + boost::allocate_shared<type[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -220,7 +220,7 @@ int main() } { boost::shared_ptr<const type[]> result = - boost::allocate_shared<const type[]>(creator<type>(), 3); + boost::allocate_shared<const type[]>(creator<>(), 3); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -231,7 +231,7 @@ int main() } { boost::shared_ptr<const type[3]> result = - boost::allocate_shared<const type[3]>(creator<type>()); + boost::allocate_shared<const type[3]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -242,7 +242,7 @@ int main() } { boost::shared_ptr<const type[][2]> result = - boost::allocate_shared<const type[][2]>(creator<type>(), 2); + boost::allocate_shared<const type[][2]>(creator<>(), 2); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), @@ -253,7 +253,7 @@ int main() } { boost::shared_ptr<const type[2][2]> result = - boost::allocate_shared<const type[2][2]>(creator<type>()); + boost::allocate_shared<const type[2][2]>(creator<>()); BOOST_TEST(result.get() != 0); BOOST_TEST(result.use_count() == 1); BOOST_TEST(boost::alignment::is_aligned(result.get(), diff --git a/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp b/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp index 9857d1835b..dd674bbc82 100644 --- a/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_array_throws_test.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/core/lightweight_test.hpp> #include <boost/smart_ptr/make_shared.hpp> -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -82,37 +82,37 @@ int main() BOOST_TEST(type::instances == 0); } try { - boost::allocate_shared<type[6]>(creator<type>()); + boost::allocate_shared<type[6]>(creator<>()); BOOST_ERROR("allocate_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } try { - boost::allocate_shared<type[3][2]>(creator<type>()); + boost::allocate_shared<type[3][2]>(creator<>()); BOOST_ERROR("allocate_shared did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } try { - boost::allocate_shared_noinit<type[]>(creator<type>(), 6); + boost::allocate_shared_noinit<type[]>(creator<>(), 6); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } try { - boost::allocate_shared_noinit<type[][2]>(creator<type>(), 3); + boost::allocate_shared_noinit<type[][2]>(creator<>(), 3); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } try { - boost::allocate_shared_noinit<type[6]>(creator<type>()); + boost::allocate_shared_noinit<type[6]>(creator<>()); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); } try { - boost::allocate_shared_noinit<type[3][2]>(creator<type>()); + boost::allocate_shared_noinit<type[3][2]>(creator<>()); BOOST_ERROR("allocate_shared_noinit did not throw"); } catch (...) { BOOST_TEST(type::instances == 0); diff --git a/libs/smart_ptr/test/allocate_shared_array_value_test.cpp b/libs/smart_ptr/test/allocate_shared_array_value_test.cpp index 485c477811..c0d67b9edd 100644 --- a/libs/smart_ptr/test/allocate_shared_array_value_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_array_value_test.cpp @@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0. #include <boost/core/lightweight_test.hpp> #include <boost/smart_ptr/make_shared.hpp> -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -65,7 +65,7 @@ int main() } { boost::shared_ptr<const int[]> result = - boost::allocate_shared<const int[]>(creator<int>(), 4, 1); + boost::allocate_shared<const int[]>(creator<>(), 4, 1); BOOST_TEST(result[0] == 1); BOOST_TEST(result[1] == 1); BOOST_TEST(result[2] == 1); @@ -73,7 +73,7 @@ int main() } { boost::shared_ptr<const int[4]> result = - boost::allocate_shared<const int[4]>(creator<int>(), 1); + boost::allocate_shared<const int[4]>(creator<>(), 1); BOOST_TEST(result[0] == 1); BOOST_TEST(result[1] == 1); BOOST_TEST(result[2] == 1); diff --git a/libs/smart_ptr/test/allocate_shared_arrays_test.cpp b/libs/smart_ptr/test/allocate_shared_arrays_test.cpp index a088a223b6..a23930c794 100644 --- a/libs/smart_ptr/test/allocate_shared_arrays_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_arrays_test.cpp @@ -5,11 +5,12 @@ Copyright 2012-2015 Glen Joseph Fernandes Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) #include <boost/core/lightweight_test.hpp> #include <boost/smart_ptr/make_shared.hpp> -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) -template<class T> +template<class T = void> struct creator { typedef T value_type; @@ -66,8 +67,7 @@ int main() } { boost::shared_ptr<const int[][2]> result = - boost::allocate_shared<const - int[][2]>(creator<int>(), 2, {0, 1}); + boost::allocate_shared<const int[][2]>(creator<>(), 2, {0, 1}); BOOST_TEST(result[0][0] == 0); BOOST_TEST(result[0][1] == 1); BOOST_TEST(result[1][0] == 0); @@ -75,8 +75,7 @@ int main() } { boost::shared_ptr<const int[2][2]> result = - boost::allocate_shared<const - int[2][2]>(creator<int>(), {0, 1}); + boost::allocate_shared<const int[2][2]>(creator<>(), {0, 1}); BOOST_TEST(result[0][0] == 0); BOOST_TEST(result[0][1] == 1); BOOST_TEST(result[1][0] == 0); diff --git a/libs/smart_ptr/test/allocate_shared_esft_test.cpp b/libs/smart_ptr/test/allocate_shared_esft_test.cpp index 2bb8ccc9a3..7902313dda 100644 --- a/libs/smart_ptr/test/allocate_shared_esft_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_esft_test.cpp @@ -63,6 +63,28 @@ int main() BOOST_TEST( X::instances == 0 ); { + boost::shared_ptr< X > px = boost::allocate_shared_noinit< X >( std::allocator<void>() ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1 ); BOOST_TEST( X::instances == 1 ); diff --git a/libs/smart_ptr/test/allocate_shared_test.cpp b/libs/smart_ptr/test/allocate_shared_test.cpp index bdae793c2f..31dcc7bb36 100644 --- a/libs/smart_ptr/test/allocate_shared_test.cpp +++ b/libs/smart_ptr/test/allocate_shared_test.cpp @@ -62,6 +62,12 @@ int main() } { + boost::shared_ptr< int > pi = boost::allocate_shared_noinit< int >( std::allocator<int>() ); + + BOOST_TEST( pi.get() != 0 ); + } + + { boost::shared_ptr< int > pi = boost::allocate_shared< int >( std::allocator<int>(), 5 ); BOOST_TEST( pi.get() != 0 ); @@ -84,6 +90,19 @@ int main() } { + boost::shared_ptr< X > pi = boost::allocate_shared_noinit< X >( std::allocator<void>() ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi->v == 0 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { boost::shared_ptr< X > pi = boost::allocate_shared< X >( std::allocator<void>(), 1 ); boost::weak_ptr<X> wp( pi ); diff --git a/libs/smart_ptr/test/atomic_sp_constexpr_test.cpp b/libs/smart_ptr/test/atomic_sp_constexpr_test.cpp new file mode 100644 index 0000000000..d81822d8e9 --- /dev/null +++ b/libs/smart_ptr/test/atomic_sp_constexpr_test.cpp @@ -0,0 +1,72 @@ +// +// atomic_sp_constexpr_test.cpp +// +// Copyright 2017 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 <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#define HAVE_CONSTEXPR_INIT + +#if defined( BOOST_NO_CXX11_CONSTEXPR ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if defined(__clang__) && defined( BOOST_NO_CXX14_CONSTEXPR ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if defined( _LIBCPP_VERSION ) && ( _LIBCPP_VERSION < 5000 ) +// in libc++, atomic_flag has a non-constexpr constructor from bool +# undef HAVE_CONSTEXPR_INIT +#endif + +#if !defined( HAVE_CONSTEXPR_INIT ) || defined( BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX ) + +int main() +{ +} + +#else + +#include <boost/smart_ptr/atomic_shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct X +{ +}; + +struct Z +{ + Z(); +}; + +static Z z; + +static boost::atomic_shared_ptr<X> p1; + +Z::Z() +{ + p1 = boost::shared_ptr<X>( new X ); +} + +int main() +{ + boost::shared_ptr<X> p2 = p1; + + BOOST_TEST( p2.get() != 0 ); + BOOST_TEST_EQ( p2.use_count(), 2 ); + + return boost::report_errors(); +} + +#endif // #if defined( BOOST_NO_CXX11_CONSEXPR ) diff --git a/libs/smart_ptr/test/atomic_sp_test.cpp b/libs/smart_ptr/test/atomic_sp_test.cpp new file mode 100644 index 0000000000..1b0b83987b --- /dev/null +++ b/libs/smart_ptr/test/atomic_sp_test.cpp @@ -0,0 +1,325 @@ +#include <boost/config.hpp> + +// atomic_sp_test.cpp +// +// Copyright 2008, 2017 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 <boost/smart_ptr/atomic_shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/memory_order.hpp> + +// + +struct X +{ +}; + +#define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) ) + +int main() +{ + // default constructor + + { + boost::atomic_shared_ptr<X> apx; + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( p2.get(), (X*)0 ); + BOOST_TEST_EQ( p2.use_count(), 0 ); + } + + // shared_ptr constructor + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // shared_ptr assignment + + { + boost::shared_ptr<X> px0( new X ); + boost::atomic_shared_ptr<X> apx( px0 ); + + boost::shared_ptr<X> px( new X ); + apx = px; + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // load, w/ mo + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> p2 = apx.load( boost::memory_order_acquire ); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // operator shared_ptr + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> p2 = apx; + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // store + + { + boost::shared_ptr<X> px0( new X ); + boost::atomic_shared_ptr<X> apx( px0 ); + + boost::shared_ptr<X> px( new X ); + apx.store( px ); + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // store, w/ mo + + { + boost::shared_ptr<X> px0( new X ); + boost::atomic_shared_ptr<X> apx( px0 ); + + boost::shared_ptr<X> px( new X ); + apx.store( px, boost::memory_order_release ); + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // exchange + + { + boost::shared_ptr<X> px0( new X ); + boost::atomic_shared_ptr<X> apx( px0 ); + + boost::shared_ptr<X> px( new X ); + boost::shared_ptr<X> p1 = apx.exchange( px ); + + BOOST_TEST_EQ( px0, p1 ); + BOOST_TEST_EQ( px0.use_count(), 2 ); + BOOST_TEST_EQ( p1.use_count(), 2 ); + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // exchange, w/ mo + + { + boost::shared_ptr<X> px0( new X ); + boost::atomic_shared_ptr<X> apx( px0 ); + + boost::shared_ptr<X> px( new X ); + boost::shared_ptr<X> p1 = apx.exchange( px, boost::memory_order_acq_rel ); + + BOOST_TEST_EQ( px0, p1 ); + BOOST_TEST_EQ( px0.use_count(), 2 ); + BOOST_TEST_EQ( p1.use_count(), 2 ); + + boost::shared_ptr<X> p2 = apx.load(); + + BOOST_TEST_EQ( px, p2 ); + BOOST_TEST_EQ( px.use_count(), 3 ); + BOOST_TEST_EQ( p2.use_count(), 3 ); + } + + // compare_exchange_weak + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> px2( new X ); + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_weak( cmp, px2 ); + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_weak( cmp, px2 ); + BOOST_TEST( r ); + BOOST_TEST_SP_EQ( apx.load(), px2 ); + } + + // compare_exchange_weak, w/ mo + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> px2( new X ); + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_weak( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_weak( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + BOOST_TEST( r ); + BOOST_TEST_SP_EQ( apx.load(), px2 ); + } + + // compare_exchange_weak, rv + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>() ); + + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>() ); + + BOOST_TEST( r ); + BOOST_TEST( apx.load().get() == 0 ); + BOOST_TEST( apx.load().use_count() == 0 ); + } + + // compare_exchange_weak, rv, w/ mo + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + + BOOST_TEST( r ); + BOOST_TEST( apx.load().get() == 0 ); + BOOST_TEST( apx.load().use_count() == 0 ); + } + + // compare_exchange_strong + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> px2( new X ); + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_strong( cmp, px2 ); + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_strong( cmp, px2 ); + BOOST_TEST( r ); + BOOST_TEST_SP_EQ( apx.load(), px2 ); + } + + // compare_exchange_strong, w/ mo + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> px2( new X ); + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_strong( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_strong( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + BOOST_TEST( r ); + BOOST_TEST_SP_EQ( apx.load(), px2 ); + } + + // compare_exchange_strong, rv + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>() ); + + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>() ); + + BOOST_TEST( r ); + BOOST_TEST( apx.load().get() == 0 ); + BOOST_TEST( apx.load().use_count() == 0 ); + } + + // compare_exchange_strong, rv, w/ mo + + { + boost::shared_ptr<X> px( new X ); + boost::atomic_shared_ptr<X> apx( px ); + + boost::shared_ptr<X> cmp; + + bool r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + + BOOST_TEST( !r ); + BOOST_TEST_SP_EQ( apx.load(), px ); + BOOST_TEST_SP_EQ( cmp, px ); + + r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst ); + + BOOST_TEST( r ); + BOOST_TEST( apx.load().get() == 0 ); + BOOST_TEST( apx.load().use_count() == 0 ); + } + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/get_deleter_array_test2.cpp b/libs/smart_ptr/test/get_deleter_array_test2.cpp new file mode 100644 index 0000000000..473aac21bb --- /dev/null +++ b/libs/smart_ptr/test/get_deleter_array_test2.cpp @@ -0,0 +1,151 @@ +// +// get_deleter_array_test2.cpp +// +// Copyright 2002, 2011, 2017 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 <boost/shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ + int data; + + deleter(): data(0) + { + } + + void operator()(void *) + { + BOOST_TEST(data == 17041); + } +}; + +struct deleter2 +{ +}; + +struct X +{ +}; + +int main() +{ + { + boost::shared_ptr<X[]> p; + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::shared_ptr<X[1]> p; + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::shared_ptr<X[]> p(new X[1]); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::shared_ptr<X[1]> p(new X[1]); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + X x[1]; + boost::shared_ptr<X[]> p(x, deleter()); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + + deleter * q = boost::get_deleter<deleter>(p); + + BOOST_TEST(q != 0); + BOOST_TEST(q->data == 0); + + q->data = 17041; + + deleter const * r = boost::get_deleter<deleter const>(p); + + BOOST_TEST(r == q); + BOOST_TEST(r->data == 17041); + } + + { + X x[1]; + boost::shared_ptr<X[1]> p(x, deleter()); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + + deleter * q = boost::get_deleter<deleter>(p); + + BOOST_TEST(q != 0); + BOOST_TEST(q->data == 0); + + q->data = 17041; + + deleter const * r = boost::get_deleter<deleter const>(p); + + BOOST_TEST(r == q); + BOOST_TEST(r->data == 17041); + } + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/get_deleter_array_test3.cpp b/libs/smart_ptr/test/get_deleter_array_test3.cpp new file mode 100644 index 0000000000..7a33eeac68 --- /dev/null +++ b/libs/smart_ptr/test/get_deleter_array_test3.cpp @@ -0,0 +1,62 @@ +// +// get_deleter_test3.cpp +// +// Copyright 2002, 2017 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 <boost/shared_ptr.hpp> +#include <boost/make_shared.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ +}; + +struct deleter2; + +struct X +{ +}; + +int main() +{ + { + boost::shared_ptr<X[]> p = boost::make_shared<X[]>( 1 ); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::shared_ptr<X[1]> p = boost::make_shared<X[1]>(); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + return boost::report_errors(); +} + +struct deleter2 +{ +}; diff --git a/libs/smart_ptr/test/get_deleter_test2.cpp b/libs/smart_ptr/test/get_deleter_test2.cpp new file mode 100644 index 0000000000..4ddc65e5f1 --- /dev/null +++ b/libs/smart_ptr/test/get_deleter_test2.cpp @@ -0,0 +1,37 @@ +// +// get_deleter_test2.cpp +// +// Copyright 2017 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 <boost/shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter; + +struct X +{ +}; + +static void test_get_deleter( boost::shared_ptr<X> const & p ) +{ + BOOST_TEST( boost::get_deleter<deleter>( p ) != 0 ); +} + +struct deleter +{ + void operator()( X const * p ) { delete p; } +}; + +int main() +{ + boost::shared_ptr<X> p( new X, deleter() ); + + test_get_deleter( p ); + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/get_deleter_test3.cpp b/libs/smart_ptr/test/get_deleter_test3.cpp new file mode 100644 index 0000000000..c42643b3c8 --- /dev/null +++ b/libs/smart_ptr/test/get_deleter_test3.cpp @@ -0,0 +1,47 @@ +// +// get_deleter_test3.cpp +// +// Copyright 2002, 2017 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 <boost/shared_ptr.hpp> +#include <boost/make_shared.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ +}; + +struct deleter2; + +struct X +{ +}; + +int main() +{ + { + boost::shared_ptr<X> p = boost::make_shared<X>(); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + return boost::report_errors(); +} + +struct deleter2 +{ +}; diff --git a/libs/smart_ptr/test/get_local_deleter_array_test.cpp b/libs/smart_ptr/test/get_local_deleter_array_test.cpp new file mode 100644 index 0000000000..3a8351bca2 --- /dev/null +++ b/libs/smart_ptr/test/get_local_deleter_array_test.cpp @@ -0,0 +1,151 @@ +// +// get_local_deleter_array_test2.cpp +// +// Copyright 2002, 2011, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ + int data; + + deleter(): data(0) + { + } + + void operator()(void *) + { + BOOST_TEST(data == 17041); + } +}; + +struct deleter2 +{ +}; + +struct X +{ +}; + +int main() +{ + { + boost::local_shared_ptr<X[]> p; + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::local_shared_ptr<X[1]> p; + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::local_shared_ptr<X[]> p(new X[1]); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::local_shared_ptr<X[1]> p(new X[1]); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + X x[1]; + boost::local_shared_ptr<X[]> p(x, deleter()); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + + deleter * q = boost::get_deleter<deleter>(p); + + BOOST_TEST(q != 0); + BOOST_TEST(q->data == 0); + + q->data = 17041; + + deleter const * r = boost::get_deleter<deleter const>(p); + + BOOST_TEST(r == q); + BOOST_TEST(r->data == 17041); + } + + { + X x[1]; + boost::local_shared_ptr<X[1]> p(x, deleter()); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + + deleter * q = boost::get_deleter<deleter>(p); + + BOOST_TEST(q != 0); + BOOST_TEST(q->data == 0); + + q->data = 17041; + + deleter const * r = boost::get_deleter<deleter const>(p); + + BOOST_TEST(r == q); + BOOST_TEST(r->data == 17041); + } + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/get_local_deleter_array_test2.cpp b/libs/smart_ptr/test/get_local_deleter_array_test2.cpp new file mode 100644 index 0000000000..999fffe746 --- /dev/null +++ b/libs/smart_ptr/test/get_local_deleter_array_test2.cpp @@ -0,0 +1,74 @@ +// +// get_local_deleter_test2.cpp +// +// Copyright 2002, 2017 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 <boost/config.hpp> + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) + +int main() +{ +} + +#else + +#include <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ +}; + +struct deleter2; + +struct X +{ +}; + +int main() +{ + { + boost::local_shared_ptr<X[]> p = boost::make_local_shared<X[]>( 1 ); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::local_shared_ptr<X[1]> p = boost::make_local_shared<X[1]>(); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + return boost::report_errors(); +} + +struct deleter2 +{ +}; + +#endif diff --git a/libs/smart_ptr/test/get_local_deleter_test.cpp b/libs/smart_ptr/test/get_local_deleter_test.cpp new file mode 100644 index 0000000000..8c45af72c6 --- /dev/null +++ b/libs/smart_ptr/test/get_local_deleter_test.cpp @@ -0,0 +1,95 @@ +// +// get_local_deleter_test.cpp +// +// Copyright 2002, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ + int data; + + deleter(): data(0) + { + } + + void operator()(void *) + { + BOOST_TEST(data == 17041); + } +}; + +struct deleter2 +{ +}; + +struct X +{ +}; + +int main() +{ + { + boost::local_shared_ptr<X> p; + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + boost::local_shared_ptr<X> p(new X); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + { + X x; + boost::local_shared_ptr<X> p(&x, deleter()); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + + deleter * q = boost::get_deleter<deleter>(p); + + BOOST_TEST(q != 0); + BOOST_TEST(q->data == 0); + + q->data = 17041; + + deleter const * r = boost::get_deleter<deleter const>(p); + + BOOST_TEST(r == q); + BOOST_TEST(r->data == 17041); + } + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/get_local_deleter_test2.cpp b/libs/smart_ptr/test/get_local_deleter_test2.cpp new file mode 100644 index 0000000000..a0023a9660 --- /dev/null +++ b/libs/smart_ptr/test/get_local_deleter_test2.cpp @@ -0,0 +1,43 @@ +// +// get_local_deleter_test2.cpp +// +// Copyright 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter; + +struct X +{ +}; + +static void test_lsp_get_deleter( boost::local_shared_ptr<X> const & p ) +{ + BOOST_TEST( boost::get_deleter<deleter>( p ) != 0 ); +} + +static void test_sp_get_deleter( boost::shared_ptr<X> const & p ) +{ + BOOST_TEST( boost::get_deleter<deleter>( p ) != 0 ); +} + +struct deleter +{ + void operator()( X const * p ) { delete p; } +}; + +int main() +{ + boost::local_shared_ptr<X> p( new X, deleter() ); + + test_lsp_get_deleter( p ); + test_sp_get_deleter( p ); + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/get_local_deleter_test3.cpp b/libs/smart_ptr/test/get_local_deleter_test3.cpp new file mode 100644 index 0000000000..655c7fc3ff --- /dev/null +++ b/libs/smart_ptr/test/get_local_deleter_test3.cpp @@ -0,0 +1,59 @@ +// +// get_local_deleter_test3.cpp +// +// Copyright 2002, 2017 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 <boost/config.hpp> + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) + +int main() +{ +} + +#else + +#include <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/core/lightweight_test.hpp> + +struct deleter +{ +}; + +struct deleter2; + +struct X +{ +}; + +int main() +{ + { + boost::local_shared_ptr<X> p = boost::make_local_shared<X>(); + + BOOST_TEST(boost::get_deleter<void>(p) == 0); + BOOST_TEST(boost::get_deleter<void const>(p) == 0); + BOOST_TEST(boost::get_deleter<int>(p) == 0); + BOOST_TEST(boost::get_deleter<int const>(p) == 0); + BOOST_TEST(boost::get_deleter<X>(p) == 0); + BOOST_TEST(boost::get_deleter<X const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter const>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2>(p) == 0); + BOOST_TEST(boost::get_deleter<deleter2 const>(p) == 0); + } + + return boost::report_errors(); +} + +struct deleter2 +{ +}; + +#endif diff --git a/libs/smart_ptr/test/local_sp_fn_test.cpp b/libs/smart_ptr/test/local_sp_fn_test.cpp new file mode 100644 index 0000000000..f2a355af50 --- /dev/null +++ b/libs/smart_ptr/test/local_sp_fn_test.cpp @@ -0,0 +1,43 @@ +// +// local_sp_fn_test.cpp +// +// Copyright 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +static void f() +{ +} + +struct null_deleter +{ + template<class Y> void operator()( Y* ) {} +}; + +int main() +{ + boost::local_shared_ptr<void()> pf( f, null_deleter() ); + + BOOST_TEST( pf.get() == f ); + BOOST_TEST_EQ( pf.local_use_count(), 1 ); + BOOST_TEST( boost::get_deleter<null_deleter>( pf ) != 0 ); + + boost::weak_ptr<void()> wp( pf ); + + BOOST_TEST( wp.lock().get() == f ); + BOOST_TEST_EQ( wp.use_count(), 1 ); + + pf.reset(); + + BOOST_TEST( wp.lock().get() == 0 ); + BOOST_TEST_EQ( wp.use_count(), 0 ); + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/local_sp_test.cpp b/libs/smart_ptr/test/local_sp_test.cpp new file mode 100644 index 0000000000..dc0e316ef3 --- /dev/null +++ b/libs/smart_ptr/test/local_sp_test.cpp @@ -0,0 +1,2531 @@ +// +// local_sp_test.cpp +// +// Copyright 2002, 2003, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/smart_ptr/weak_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +struct X +{ + static long instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + +private: + + X( X const & ); + X & operator=( X const & ); +}; + +long X::instances = 0; + +class incomplete; + +// default constructor + +static void default_constructor() +{ + { + boost::local_shared_ptr<int> p; + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + + { + boost::local_shared_ptr<void> p; + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + + { + boost::local_shared_ptr<incomplete> p; + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::local_shared_ptr<X> p; + + BOOST_TEST( X::instances == 0 ); + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } +} + +// nullptr_constructor + +static void nullptr_constructor() +{ +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + { + boost::local_shared_ptr<int> p( nullptr ); + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + + { + boost::local_shared_ptr<void> p( nullptr ); + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + + { + boost::local_shared_ptr<incomplete> p( nullptr ); + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::local_shared_ptr<X> p( nullptr ); + + BOOST_TEST( X::instances == 0 ); + + + BOOST_TEST_EQ( p.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p.local_use_count(), 0 ); + } + +#endif +} + +// pointer constructor + +template<class T, class U> static void pc0_test_() +{ + boost::local_shared_ptr<T> p( static_cast<U*>( 0 ) ); + + BOOST_TEST( p? false: true ); + BOOST_TEST( !p ); + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.local_use_count() == 1 ); +} + +template<class T> static void pc0_test() +{ + pc0_test_<T, T>(); + pc0_test_<T const, T const>(); + pc0_test_<T volatile, T volatile>(); + pc0_test_<T const volatile, T const volatile>(); + + pc0_test_<T const, T>(); + pc0_test_<T volatile, T>(); + pc0_test_<T const volatile, T>(); + + pc0_test_<void, T>(); + pc0_test_<void const, T>(); + pc0_test_<void volatile, T>(); + pc0_test_<void const volatile, T>(); +} + +template<class T, class U> static void pc1_test_() +{ + boost::local_shared_ptr<T> p( new U() ); + + BOOST_TEST( p? true: false ); + BOOST_TEST( !!p ); + BOOST_TEST( p.get() != 0 ); + BOOST_TEST( p.local_use_count() == 1 ); +} + +template<class T> static void pc1_test() +{ + pc1_test_<T, T>(); + pc1_test_<T const, T const>(); + pc1_test_<T volatile, T volatile>(); + pc1_test_<T const volatile, T const volatile>(); + + pc1_test_<T const, T>(); + pc1_test_<T volatile, T>(); + pc1_test_<T const volatile, T>(); + + pc1_test_<void, T>(); + pc1_test_<void const, T>(); + pc1_test_<void volatile, T>(); + pc1_test_<void const volatile, T>(); +} + +static void pointer_constructor() +{ + pc0_test<int>(); + pc0_test<X>(); + + pc1_test<int>(); + + BOOST_TEST( X::instances == 0 ); + + pc1_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// deleter constructor + +int m = 0; + +void deleter2( int * p ) +{ + BOOST_TEST( p == &m ); + ++*p; +} + +template<class T> static void deleter2_test_() +{ + { + m = 0; + boost::local_shared_ptr<T> p( &m, deleter2 ); + + BOOST_TEST( p? true: false ); + BOOST_TEST( !!p ); + BOOST_TEST( p.get() == &m ); + BOOST_TEST( p.local_use_count() == 1 ); + } + + BOOST_TEST( m == 1 ); +} + +static void deleter_constructor() +{ + deleter2_test_<int>(); + deleter2_test_<int const>(); + deleter2_test_<int volatile>(); + deleter2_test_<int const volatile>(); + + deleter2_test_<void>(); + deleter2_test_<void const>(); + deleter2_test_<void volatile>(); + deleter2_test_<void const volatile>(); +} + +// nullptr_deleter_constructor + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +void deleter3( boost::detail::sp_nullptr_t ) +{ + ++m; +} + +template<class T> static void deleter3_test_() +{ + { + m = 0; + boost::local_shared_ptr<T> p( nullptr, deleter3 ); + + BOOST_TEST( !p ); + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.local_use_count() == 1 ); + } + + BOOST_TEST( m == 1 ); +} + +static void nullptr_deleter_constructor() +{ + deleter3_test_<int>(); + deleter3_test_<int const>(); + deleter3_test_<int volatile>(); + deleter3_test_<int const volatile>(); + + deleter3_test_<void>(); + deleter3_test_<void const>(); + deleter3_test_<void volatile>(); + deleter3_test_<void const volatile>(); +} + +#else + +static void nullptr_deleter_constructor() +{ +} + +#endif + +// allocator constructor + +template<class T> static void allocator_test_() +{ + { + m = 0; + boost::local_shared_ptr<T> p( &m, deleter2, std::allocator<void>() ); + + BOOST_TEST( p? true: false ); + BOOST_TEST( !!p ); + BOOST_TEST( p.get() == &m ); + BOOST_TEST( p.local_use_count() == 1 ); + } + + BOOST_TEST( m == 1 ); +} + +static void allocator_constructor() +{ + allocator_test_<int>(); + allocator_test_<int const>(); + allocator_test_<int volatile>(); + allocator_test_<int const volatile>(); + + allocator_test_<void>(); + allocator_test_<void const>(); + allocator_test_<void volatile>(); + allocator_test_<void const volatile>(); +} + +// nullptr_allocator_constructor + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template<class T> static void allocator3_test_() +{ + { + m = 0; + boost::local_shared_ptr<T> p( nullptr, deleter3, std::allocator<void>() ); + + BOOST_TEST( !p ); + BOOST_TEST( p.get() == 0 ); + BOOST_TEST( p.local_use_count() == 1 ); + } + + BOOST_TEST( m == 1 ); +} + +static void nullptr_allocator_constructor() +{ + allocator3_test_<int>(); + allocator3_test_<int const>(); + allocator3_test_<int volatile>(); + allocator3_test_<int const volatile>(); + + allocator3_test_<void>(); + allocator3_test_<void const>(); + allocator3_test_<void volatile>(); + allocator3_test_<void const volatile>(); +} + +#else + +static void nullptr_allocator_constructor() +{ +} + +#endif + +// copy constructor + +template<class T> static void empty_copy_test() +{ + boost::local_shared_ptr<T> p1; + + BOOST_TEST_EQ( p1.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p1.local_use_count(), 0 ); + + boost::local_shared_ptr<T> p2( p1 ); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( p1 ); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( p1 ); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( p3 ); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_copy( boost::local_shared_ptr<U> const & p1 ) +{ + long k = p1.local_use_count(); + + { + boost::local_shared_ptr<T> p2( p1 ); + + BOOST_TEST( p2.get() == p1.get() ); + BOOST_TEST( p2.local_use_count() == p1.local_use_count() ); + BOOST_TEST( p2.local_use_count() == k + 1 ); + } + + BOOST_TEST( p1.local_use_count() == k ); +} + +template<class T> static void null_copy_test() +{ + boost::local_shared_ptr<T> p1( static_cast<T*>(0) ); + + test_nonempty_copy<T>( p1 ); + test_nonempty_copy<T const>( p1 ); + test_nonempty_copy<T volatile>( p1 ); + test_nonempty_copy<T const volatile>( p1 ); + test_nonempty_copy<void>( p1 ); + test_nonempty_copy<void const>( p1 ); + test_nonempty_copy<void volatile>( p1 ); + test_nonempty_copy<void const volatile>( p1 ); +} + +template<class T> static void new_copy_test() +{ + boost::local_shared_ptr<T> p1( new T() ); + + test_nonempty_copy<T>( p1 ); + test_nonempty_copy<T const>( p1 ); + test_nonempty_copy<T volatile>( p1 ); + test_nonempty_copy<T const volatile>( p1 ); + test_nonempty_copy<void>( p1 ); + test_nonempty_copy<void const>( p1 ); + test_nonempty_copy<void volatile>( p1 ); + test_nonempty_copy<void const volatile>( p1 ); +} + +static void copy_constructor() +{ + empty_copy_test<int>(); + empty_copy_test<incomplete>(); + empty_copy_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_copy_test<int>(); + null_copy_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_copy_test<int>(); + new_copy_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// move constructor + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template<class T> static void empty_move_test() +{ + boost::local_shared_ptr<T> p2(( boost::local_shared_ptr<T>() )); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3(( boost::local_shared_ptr<T>() )); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4(( boost::local_shared_ptr<T>() )); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( std::move(p3) ); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_move( boost::local_shared_ptr<U> && p1 ) +{ + U* q = p1.get(); + long k = p1.local_use_count(); + + boost::local_shared_ptr<T> p2( std::move(p1) ); + + BOOST_TEST( p2.get() == q ); + BOOST_TEST( p2.local_use_count() == k ); + + BOOST_TEST( p1.get() == 0 ); + BOOST_TEST( p1.local_use_count() == 0 ); +} + +template<class T> static void null_move_test() +{ + test_nonempty_move<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<T const>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<T volatile>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<T const volatile>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<void>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<void const>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<void volatile>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move<void const volatile>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_move_test() +{ + test_nonempty_move<T>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<T const>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<T volatile>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<T const volatile>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<void>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<void const>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<void volatile>( boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move<void const volatile>( boost::local_shared_ptr<T>( new T() ) ); +} + +static void move_constructor() +{ + empty_move_test<int>(); + empty_move_test<incomplete>(); + empty_move_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_move_test<int>(); + null_move_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_move_test<int>(); + new_move_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +#else + +static void move_constructor() +{ +} + +#endif + +// aliasing constructor + +template<class T, class U> void test_aliasing_( boost::local_shared_ptr<T> const & p1, U * p2 ) +{ + boost::local_shared_ptr<U> p3( p1, p2 ); + + BOOST_TEST( p3.get() == p2 ); + BOOST_TEST( p3.local_use_count() == p1.local_use_count() ); + BOOST_TEST( !p3.owner_before( p1 ) && !p1.owner_before( p3 ) ); +} + +template<class T, class U> void test_01_aliasing_() +{ + U u; + boost::local_shared_ptr<T> p1; + + test_aliasing_( p1, &u ); +} + +template<class T, class U> void test_01_aliasing() +{ + test_01_aliasing_<T, U>(); + test_01_aliasing_<T const, U>(); + test_01_aliasing_<T volatile, U>(); + test_01_aliasing_<T const volatile, U>(); + + test_01_aliasing_<T, U volatile>(); + test_01_aliasing_<T const, U volatile>(); + test_01_aliasing_<T volatile, U volatile>(); + test_01_aliasing_<T const volatile, U volatile>(); +} + +template<class T, class U> void test_10_aliasing_() +{ + boost::local_shared_ptr<T> p1( new T() ); + test_aliasing_( p1, static_cast<U*>(0) ); +} + +template<class T, class U> void test_10_aliasing() +{ + test_10_aliasing_<T, U>(); + test_10_aliasing_<T const, U>(); + test_10_aliasing_<T volatile, U>(); + test_10_aliasing_<T const volatile, U>(); + + test_10_aliasing_<T, U const>(); + test_10_aliasing_<T const, U const>(); + test_10_aliasing_<T volatile, U const>(); + test_10_aliasing_<T const volatile, U const>(); + + test_10_aliasing_<T, U volatile>(); + test_10_aliasing_<T const, U volatile>(); + test_10_aliasing_<T volatile, U volatile>(); + test_10_aliasing_<T const volatile, U volatile>(); + + test_10_aliasing_<T, U const volatile>(); + test_10_aliasing_<T const, U const volatile>(); + test_10_aliasing_<T volatile, U const volatile>(); + test_10_aliasing_<T const volatile, U const volatile>(); +} + +template<class T, class U> void test_11_aliasing_() +{ + U u; + boost::local_shared_ptr<T> p1( new T() ); + + test_aliasing_( p1, &u ); +} + +template<class T, class U> void test_11_aliasing() +{ + test_11_aliasing_<T, U>(); + test_11_aliasing_<T const, U>(); + test_11_aliasing_<T volatile, U>(); + test_11_aliasing_<T const volatile, U>(); + + test_11_aliasing_<T, U volatile>(); + test_11_aliasing_<T const, U volatile>(); + test_11_aliasing_<T volatile, U volatile>(); + test_11_aliasing_<T const volatile, U volatile>(); +} + +static void aliasing_constructor() +{ + test_01_aliasing<int, int>(); + test_10_aliasing<int, int>(); + test_11_aliasing<int, int>(); + + test_01_aliasing<void, int>(); + + test_10_aliasing<int, void>(); + + test_10_aliasing<int, incomplete>(); + + test_01_aliasing<X, X>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing<X, X>(); + BOOST_TEST( X::instances == 0 ); + + test_11_aliasing<X, X>(); + BOOST_TEST( X::instances == 0 ); + + test_01_aliasing<int, X>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing<int, X>(); + BOOST_TEST( X::instances == 0 ); + + test_11_aliasing<int, X>(); + BOOST_TEST( X::instances == 0 ); + + test_01_aliasing<X, int>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing<X, int>(); + BOOST_TEST( X::instances == 0 ); + + test_11_aliasing<X, int>(); + BOOST_TEST( X::instances == 0 ); + + test_01_aliasing<void, X>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing<X, void>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing<X, incomplete>(); + BOOST_TEST( X::instances == 0 ); +} + +// shared_ptr copy constructor + +template<class T> static void empty_shared_ptr_copy_test() +{ + boost::shared_ptr<T> p1; + + boost::local_shared_ptr<T> p2( p1 ); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( p1 ); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( p1 ); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( p3 ); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_shared_ptr_copy( boost::shared_ptr<U> const & p1 ) +{ + long k = p1.use_count(); + + { + boost::local_shared_ptr<T> p2( p1 ); + + BOOST_TEST( p2.get() == p1.get() ); + BOOST_TEST( p2.local_use_count() == 1 ); + + BOOST_TEST( p1.use_count() == k + 1 ); + } + + BOOST_TEST( p1.use_count() == k ); +} + +template<class T> static void null_shared_ptr_copy_test() +{ + boost::shared_ptr<T> p1( static_cast<T*>(0) ); + + test_nonempty_shared_ptr_copy<T>( p1 ); + test_nonempty_shared_ptr_copy<T const>( p1 ); + test_nonempty_shared_ptr_copy<T volatile>( p1 ); + test_nonempty_shared_ptr_copy<T const volatile>( p1 ); + test_nonempty_shared_ptr_copy<void>( p1 ); + test_nonempty_shared_ptr_copy<void const>( p1 ); + test_nonempty_shared_ptr_copy<void volatile>( p1 ); + test_nonempty_shared_ptr_copy<void const volatile>( p1 ); +} + +template<class T> static void new_shared_ptr_copy_test() +{ + boost::shared_ptr<T> p1( new T() ); + + test_nonempty_shared_ptr_copy<T>( p1 ); + test_nonempty_shared_ptr_copy<T const>( p1 ); + test_nonempty_shared_ptr_copy<T volatile>( p1 ); + test_nonempty_shared_ptr_copy<T const volatile>( p1 ); + test_nonempty_shared_ptr_copy<void>( p1 ); + test_nonempty_shared_ptr_copy<void const>( p1 ); + test_nonempty_shared_ptr_copy<void volatile>( p1 ); + test_nonempty_shared_ptr_copy<void const volatile>( p1 ); +} + +static void shared_ptr_copy_constructor() +{ + empty_shared_ptr_copy_test<int>(); + empty_shared_ptr_copy_test<incomplete>(); + empty_shared_ptr_copy_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_shared_ptr_copy_test<int>(); + null_shared_ptr_copy_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_shared_ptr_copy_test<int>(); + new_shared_ptr_copy_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// shared_ptr_move constructor + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template<class T> static void empty_shared_ptr_move_test() +{ + boost::local_shared_ptr<T> p2(( boost::shared_ptr<T>() )); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3(( boost::shared_ptr<T>() )); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4(( boost::shared_ptr<T>() )); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( std::move(p3) ); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_shared_ptr_move( boost::shared_ptr<U> && p1 ) +{ + U* q = p1.get(); + + boost::local_shared_ptr<T> p2( std::move(p1) ); + + BOOST_TEST( p2.get() == q ); + BOOST_TEST( p2.local_use_count() == 1 ); + + BOOST_TEST( p1.get() == 0 ); + BOOST_TEST( p1.use_count() == 0 ); +} + +template<class T> static void null_shared_ptr_move_test() +{ + test_nonempty_shared_ptr_move<T>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<T const>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<T volatile>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<T const volatile>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<void>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<void const>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<void volatile>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move<void const volatile>( boost::shared_ptr<T>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_shared_ptr_move_test() +{ + test_nonempty_shared_ptr_move<T>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<T const>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<T volatile>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<T const volatile>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<void>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<void const>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<void volatile>( boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move<void const volatile>( boost::shared_ptr<T>( new T() ) ); +} + +static void shared_ptr_move_constructor() +{ + empty_shared_ptr_move_test<int>(); + empty_shared_ptr_move_test<incomplete>(); + empty_shared_ptr_move_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_shared_ptr_move_test<int>(); + null_shared_ptr_move_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_shared_ptr_move_test<int>(); + new_shared_ptr_move_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +#else + +static void shared_ptr_move_constructor() +{ +} + +#endif + +// unique_ptr_constructor + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template<class T, class U> static void test_null_unique_ptr( std::unique_ptr<U> && p1 ) +{ + boost::local_shared_ptr<T> p2( std::move( p1 ) ); + + BOOST_TEST( p1.get() == 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2.local_use_count() == 0 ); +} + +template<class T> static void null_unique_ptr_test() +{ + test_null_unique_ptr<T>( std::unique_ptr<T>() ); + + test_null_unique_ptr<T const>( std::unique_ptr<T>() ); + test_null_unique_ptr<T volatile>( std::unique_ptr<T>() ); + test_null_unique_ptr<T const volatile>( std::unique_ptr<T>() ); + + test_null_unique_ptr<T const>( std::unique_ptr<T const>() ); + test_null_unique_ptr<T volatile>( std::unique_ptr<T volatile>() ); + test_null_unique_ptr<T const volatile>( std::unique_ptr<T const volatile>() ); + + test_null_unique_ptr<void>( std::unique_ptr<T>() ); + + test_null_unique_ptr<void const>( std::unique_ptr<T>() ); + test_null_unique_ptr<void volatile>( std::unique_ptr<T>() ); + test_null_unique_ptr<void const volatile>( std::unique_ptr<T>() ); + + test_null_unique_ptr<void const>( std::unique_ptr<T const>() ); + test_null_unique_ptr<void volatile>( std::unique_ptr<T volatile>() ); + test_null_unique_ptr<void const volatile>( std::unique_ptr<T const volatile>() ); +} + +template<class T, class U, class D> static void test_nonempty_unique_ptr( std::unique_ptr<U, D> && p1 ) +{ + U * q = p1.get(); + + boost::local_shared_ptr<T> p2( std::move(p1) ); + + BOOST_TEST( p2.get() == q ); + BOOST_TEST( p2.local_use_count() == 1 ); + + BOOST_TEST( p1.get() == 0 ); +} + +template<class T> static void new_unique_ptr_test() +{ + test_nonempty_unique_ptr<T>( std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr<T const>( std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr<T volatile>( std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr<T const volatile>( std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr<T const>( std::unique_ptr<T const>( new T() ) ); + test_nonempty_unique_ptr<T volatile>( std::unique_ptr<T volatile>( new T() ) ); + test_nonempty_unique_ptr<T const volatile>( std::unique_ptr<T const volatile>( new T() ) ); + + test_nonempty_unique_ptr<void>( std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr<void const>( std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr<void volatile>( std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr<void const volatile>( std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr<void const>( std::unique_ptr<T const>( new T() ) ); + test_nonempty_unique_ptr<void volatile>( std::unique_ptr<T volatile>( new T() ) ); + test_nonempty_unique_ptr<void const volatile>( std::unique_ptr<T const volatile>( new T() ) ); +} + +template<class T> static void test_deleter_unique_ptr() +{ + m = 0; + + test_nonempty_unique_ptr<T>( std::unique_ptr<int, void(*)(int*)>( &m, deleter2 ) ); + + BOOST_TEST( m == 1 ); +} + +template<class T> static void deleter_unique_ptr_test() +{ + test_deleter_unique_ptr<T>(); + test_deleter_unique_ptr<T const>(); + test_deleter_unique_ptr<T volatile>(); + test_deleter_unique_ptr<T const volatile>(); +} + +static void unique_ptr_constructor() +{ + null_unique_ptr_test<int>(); + null_unique_ptr_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_unique_ptr_test<int>(); + new_unique_ptr_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + deleter_unique_ptr_test<int>(); + deleter_unique_ptr_test<void>(); +} + +#else + +static void unique_ptr_constructor() +{ +} + +#endif + +// copy assignment + +template<class T> static void empty_copy_assign_test() +{ + boost::local_shared_ptr<T> p1; + + BOOST_TEST_EQ( p1.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p1.local_use_count(), 0 ); + + boost::local_shared_ptr<T> p2; + + p2 = p1; + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3; + + p3 = p1; + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4; + + p4 = p1; + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5; + + p5 = p3; + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T> static void empty_copy_assign_test_() +{ + boost::local_shared_ptr<T> p1; + + BOOST_TEST_EQ( p1.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p1.local_use_count(), 0 ); + + boost::local_shared_ptr<T> p2( static_cast<T*>(0) ); + + p2 = p1; + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( static_cast<T const*>(0) ); + + p3 = p1; + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( static_cast<T*>(0) ); + + p4 = p1; + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( static_cast<T const*>(0) ); + + p5 = p3; + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_copy_assign( boost::local_shared_ptr<T> p2, boost::local_shared_ptr<U> const & p1 ) +{ + long k = p1.local_use_count(); + + p2 = p1; + + BOOST_TEST( p2.get() == p1.get() ); + BOOST_TEST( p2.local_use_count() == p1.local_use_count() ); + BOOST_TEST( p2.local_use_count() == k + 1 ); + + p2.reset(); + + BOOST_TEST( p1.local_use_count() == k ); +} + +template<class T> static void null_copy_assign_test() +{ + boost::local_shared_ptr<T> p1( static_cast<T*>(0) ); + + test_nonempty_copy_assign( boost::local_shared_ptr<T>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T volatile>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const volatile>(), p1 ); + + test_nonempty_copy_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), p1 ); + + test_nonempty_copy_assign( boost::local_shared_ptr<void>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<void const>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<void volatile>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<void const volatile>(), p1 ); +} + +template<class T> static void new_copy_assign_test() +{ + boost::local_shared_ptr<T> p1( new T() ); + + test_nonempty_copy_assign( boost::local_shared_ptr<T>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T volatile>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const volatile>(), p1 ); + + test_nonempty_copy_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), p1 ); + + test_nonempty_copy_assign( boost::local_shared_ptr<T>( new T() ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const>( new T const() ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), p1 ); + + test_nonempty_copy_assign( boost::local_shared_ptr<void>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<void const>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<void volatile>(), p1 ); + test_nonempty_copy_assign( boost::local_shared_ptr<void const volatile>(), p1 ); +} + +static void copy_assignment() +{ + empty_copy_assign_test<incomplete>(); + empty_copy_assign_test<int>(); + empty_copy_assign_test_<int>(); + empty_copy_assign_test<X>(); + empty_copy_assign_test_<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_copy_assign_test<int>(); + null_copy_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_copy_assign_test<int>(); + new_copy_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// move assignment + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template<class T> static void empty_move_assign_test() +{ + boost::local_shared_ptr<T> p2; + + p2 = boost::local_shared_ptr<T>(); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3; + + p3 = boost::local_shared_ptr<T>(); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4; + + p4 = boost::local_shared_ptr<T>(); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5; + + p5 = std::move( p3 ); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T> static void empty_move_assign_test_() +{ + boost::local_shared_ptr<T> p2( static_cast<T*>(0) ); + + p2 = boost::local_shared_ptr<T>(); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( static_cast<T const*>(0) ); + + p3 = boost::local_shared_ptr<T>(); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( static_cast<T*>(0) ); + + p4 = boost::local_shared_ptr<T>(); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( static_cast<T const*>(0) ); + + p5 = std::move( p3 ); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_move_assign( boost::local_shared_ptr<T> p2, boost::local_shared_ptr<U> && p1 ) +{ + U* q = p1.get(); + long k = p1.local_use_count(); + + p2 = std::move( p1 ); + + BOOST_TEST( p2.get() == q ); + BOOST_TEST( p2.local_use_count() == k ); + + BOOST_TEST( p1.get() == 0 ); + BOOST_TEST( p1.local_use_count() == 0 ); +} + +template<class T> static void null_move_assign_test() +{ + test_nonempty_move_assign( boost::local_shared_ptr<T>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T volatile>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const volatile>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + + test_nonempty_move_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + + test_nonempty_move_assign( boost::local_shared_ptr<void>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<void const>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<void volatile>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_move_assign( boost::local_shared_ptr<void const volatile>(), boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_move_assign_test() +{ + test_nonempty_move_assign( boost::local_shared_ptr<T>(), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const>(), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T volatile>(), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const volatile>(), boost::local_shared_ptr<T>( new T() ) ); + + test_nonempty_move_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), boost::local_shared_ptr<T>( new T() ) ); + + test_nonempty_move_assign( boost::local_shared_ptr<T>( new T() ), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const>( new T const() ), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), boost::local_shared_ptr<T>( new T() ) ); + + test_nonempty_move_assign( boost::local_shared_ptr<void>(), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<void const>(), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<void volatile>(), boost::local_shared_ptr<T>( new T() ) ); + test_nonempty_move_assign( boost::local_shared_ptr<void const volatile>(), boost::local_shared_ptr<T>( new T() ) ); +} + +static void move_assignment() +{ + empty_move_assign_test<incomplete>(); + empty_move_assign_test<int>(); + empty_move_assign_test_<int>(); + empty_move_assign_test<X>(); + empty_move_assign_test_<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_move_assign_test<int>(); + null_move_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_move_assign_test<int>(); + new_move_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +#else + +static void move_assignment() +{ +} + +#endif + +// nullptr assignment + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + +template<class T> static void test_nullptr_assign( boost::local_shared_ptr<T> p1 ) +{ + p1 = nullptr; + + BOOST_TEST( p1.get() == 0 ); + BOOST_TEST( p1.local_use_count() == 0 ); +} + +template<class T> static void empty_nullptr_assign_test() +{ + test_nullptr_assign( boost::local_shared_ptr<T>() ); + test_nullptr_assign( boost::local_shared_ptr<T const>() ); + test_nullptr_assign( boost::local_shared_ptr<T volatile>() ); + test_nullptr_assign( boost::local_shared_ptr<T const volatile>() ); +} + +template<class T> static void null_nullptr_assign_test() +{ + test_nullptr_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_nullptr_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ) ); + test_nullptr_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ) ); + test_nullptr_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ) ); +} + +template<class T> static void new_nullptr_assign_test() +{ + test_nullptr_assign( boost::local_shared_ptr<T>( new T() ) ); + test_nullptr_assign( boost::local_shared_ptr<T const>( new T const() ) ); + test_nullptr_assign( boost::local_shared_ptr<T volatile>( new T volatile() ) ); + test_nullptr_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ) ); +} + +static void nullptr_assignment() +{ + empty_nullptr_assign_test<incomplete>(); + empty_nullptr_assign_test<void>(); + empty_nullptr_assign_test<int>(); + empty_nullptr_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_nullptr_assign_test<int>(); + null_nullptr_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_nullptr_assign_test<int>(); + new_nullptr_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +#else + +static void nullptr_assignment() +{ +} + +#endif + +// default_reset + +template<class T> static void test_default_reset( boost::local_shared_ptr<T> p1 ) +{ + p1.reset(); + + BOOST_TEST( p1.get() == 0 ); + BOOST_TEST( p1.local_use_count() == 0 ); +} + +template<class T> static void empty_default_reset_test() +{ + test_default_reset( boost::local_shared_ptr<T>() ); + test_default_reset( boost::local_shared_ptr<T const>() ); + test_default_reset( boost::local_shared_ptr<T volatile>() ); + test_default_reset( boost::local_shared_ptr<T const volatile>() ); +} + +template<class T> static void null_default_reset_test() +{ + test_default_reset( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_default_reset( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ) ); + test_default_reset( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ) ); + test_default_reset( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ) ); +} + +template<class T> static void new_default_reset_test() +{ + test_default_reset( boost::local_shared_ptr<T>( new T() ) ); + test_default_reset( boost::local_shared_ptr<T const>( new T const() ) ); + test_default_reset( boost::local_shared_ptr<T volatile>( new T volatile() ) ); + test_default_reset( boost::local_shared_ptr<T const volatile>( new T const volatile() ) ); +} + +static void default_reset() +{ + empty_default_reset_test<incomplete>(); + empty_default_reset_test<void>(); + empty_default_reset_test<int>(); + empty_default_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_default_reset_test<int>(); + null_default_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_default_reset_test<int>(); + new_default_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// shared_ptr copy assignment + +template<class T> static void empty_shared_ptr_copy_assign_test() +{ + boost::shared_ptr<T> sp1; + + BOOST_TEST_EQ( sp1.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( sp1.use_count(), 0 ); + + boost::local_shared_ptr<T> p2; + + p2 = sp1; + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3; + + p3 = sp1; + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4; + + p4 = sp1; + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::shared_ptr<T const> sp2( sp1 ); + boost::local_shared_ptr<void const> p5; + + p5 = sp2; + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T> static void empty_shared_ptr_copy_assign_test_() +{ + boost::shared_ptr<T> sp1; + + BOOST_TEST_EQ( sp1.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( sp1.use_count(), 0 ); + + boost::local_shared_ptr<T> p2( static_cast<T*>(0) ); + + p2 = sp1; + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( static_cast<T const*>(0) ); + + p3 = sp1; + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( static_cast<T*>(0) ); + + p4 = sp1; + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::shared_ptr<T const> sp2( sp1 ); + boost::local_shared_ptr<void const> p5( static_cast<T const*>(0) ); + + p5 = sp2; + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T> p2, boost::shared_ptr<U> const & p1 ) +{ + long k = p1.use_count(); + + p2 = p1; + + BOOST_TEST( p2.get() == p1.get() ); + BOOST_TEST( p2.local_use_count() == 1 ); + BOOST_TEST( p1.use_count() == k + 1 ); + + p2.reset(); + + BOOST_TEST( p1.use_count() == k ); +} + +template<class T> static void null_shared_ptr_copy_assign_test() +{ + boost::shared_ptr<T> p1( static_cast<T*>(0) ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T volatile>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const volatile>(), p1 ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), p1 ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void const>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void volatile>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void const volatile>(), p1 ); +} + +template<class T> static void new_shared_ptr_copy_assign_test() +{ + boost::shared_ptr<T> p1( new T() ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T volatile>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const volatile>(), p1 ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), p1 ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T>( new T() ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const>( new T const() ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), p1 ); + + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void const>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void volatile>(), p1 ); + test_nonempty_shared_ptr_copy_assign( boost::local_shared_ptr<void const volatile>(), p1 ); +} + +static void shared_ptr_copy_assignment() +{ + empty_shared_ptr_copy_assign_test<incomplete>(); + empty_shared_ptr_copy_assign_test<int>(); + empty_shared_ptr_copy_assign_test_<int>(); + empty_shared_ptr_copy_assign_test<X>(); + empty_shared_ptr_copy_assign_test_<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_shared_ptr_copy_assign_test<int>(); + null_shared_ptr_copy_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_shared_ptr_copy_assign_test<int>(); + new_shared_ptr_copy_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// shared_ptr_move assignment + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template<class T> static void empty_shared_ptr_move_assign_test() +{ + boost::local_shared_ptr<T> p2; + + p2 = boost::shared_ptr<T>(); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3; + + p3 = boost::shared_ptr<T>(); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4; + + p4 = boost::shared_ptr<T>(); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5; + + p5 = boost::shared_ptr<T const>(); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T> static void empty_shared_ptr_move_assign_test_() +{ + boost::local_shared_ptr<T> p2( static_cast<T*>(0) ); + + p2 = boost::shared_ptr<T>(); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( static_cast<T const*>(0) ); + + p3 = boost::shared_ptr<T>(); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( static_cast<T*>(0) ); + + p4 = boost::shared_ptr<T>(); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( static_cast<T const*>(0) ); + + p5 = boost::shared_ptr<T const>(); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U> static void test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T> p2, boost::shared_ptr<U> && p1 ) +{ + U* q = p1.get(); + long k = p1.use_count(); + + p2 = std::move( p1 ); + + BOOST_TEST_EQ( p2.get(), q ); + BOOST_TEST_EQ( p2.local_use_count(), 1 ); + + BOOST_TEST( p1.get() == 0 ); + BOOST_TEST( p1.use_count() == 0 ); + + boost::shared_ptr<T> p3( p2 ); + + BOOST_TEST_EQ( p3.get(), q ); + BOOST_TEST_EQ( p3.use_count(), k + 1 ); +} + +template<class T> static void null_shared_ptr_move_assign_test() +{ + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T volatile>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const volatile>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void const>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void volatile>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void const volatile>(), boost::shared_ptr<T>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_shared_ptr_move_assign_test() +{ + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T>(), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const>(), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T volatile>(), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const volatile>(), boost::shared_ptr<T>( new T() ) ); + + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), boost::shared_ptr<T>( new T() ) ); + + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T>( new T() ), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const>( new T const() ), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), boost::shared_ptr<T>( new T() ) ); + + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void>(), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void const>(), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void volatile>(), boost::shared_ptr<T>( new T() ) ); + test_nonempty_shared_ptr_move_assign( boost::local_shared_ptr<void const volatile>(), boost::shared_ptr<T>( new T() ) ); +} + +static void shared_ptr_move_assignment() +{ + empty_shared_ptr_move_assign_test<incomplete>(); + empty_shared_ptr_move_assign_test<int>(); + empty_shared_ptr_move_assign_test_<int>(); + empty_shared_ptr_move_assign_test<X>(); + empty_shared_ptr_move_assign_test_<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_shared_ptr_move_assign_test<int>(); + null_shared_ptr_move_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_shared_ptr_move_assign_test<int>(); + new_shared_ptr_move_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +#else + +static void shared_ptr_move_assignment() +{ +} + +#endif + +// unique_ptr assignment + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_SMART_PTR ) + +template<class T> static void empty_unique_ptr_assign_test() +{ + boost::local_shared_ptr<T> p2; + + p2 = std::unique_ptr<T>(); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3; + + p3 = std::unique_ptr<T>(); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4; + + p4 = std::unique_ptr<T>(); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5; + + p5 = std::unique_ptr<T const>(); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T> static void empty_unique_ptr_assign_test_() +{ + boost::local_shared_ptr<T> p2( static_cast<T*>(0) ); + + p2 = std::unique_ptr<T>(); + + BOOST_TEST_EQ( p2.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p2.local_use_count(), 0 ); + + boost::local_shared_ptr<T const> p3( static_cast<T const*>(0) ); + + p3 = std::unique_ptr<T>(); + + BOOST_TEST_EQ( p3.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p3.local_use_count(), 0 ); + + boost::local_shared_ptr<void> p4( static_cast<T*>(0) ); + + p4 = std::unique_ptr<T>(); + + BOOST_TEST_EQ( p4.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p4.local_use_count(), 0 ); + + boost::local_shared_ptr<void const> p5( static_cast<T const*>(0) ); + + p5 = std::unique_ptr<T const>(); + + BOOST_TEST_EQ( p5.get(), static_cast<void*>(0) ); + BOOST_TEST_EQ( p5.local_use_count(), 0 ); +} + +template<class T, class U, class D> static void test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T> p2, std::unique_ptr<U, D> && p1 ) +{ + U* q = p1.get(); + + p2 = std::move( p1 ); + + BOOST_TEST_EQ( p2.get(), q ); + BOOST_TEST_EQ( p2.local_use_count(), 1 ); + + BOOST_TEST( p1.get() == 0 ); +} + +template<class T> static void new_unique_ptr_assign_test() +{ + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>(), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>(), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>(), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>(), std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( new T() ), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( new T const() ), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), std::unique_ptr<T>( new T() ) ); + + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void>(), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const>(), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void volatile>(), std::unique_ptr<T>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const volatile>(), std::unique_ptr<T>( new T() ) ); +} + +template<class T> static void del_unique_ptr_assign_test() +{ + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( static_cast<T*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( static_cast<T const*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( static_cast<T volatile*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( static_cast<T const volatile*>(0) ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T>( new T() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const>( new T const() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T volatile>( new T volatile() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<T const volatile>( new T const volatile() ), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); + test_nonempty_unique_ptr_assign( boost::local_shared_ptr<void const volatile>(), std::unique_ptr<T, boost::checked_deleter<T>>( new T() ) ); +} + +static void unique_ptr_assignment() +{ + empty_unique_ptr_assign_test<int>(); + empty_unique_ptr_assign_test_<int>(); + empty_unique_ptr_assign_test<X>(); + empty_unique_ptr_assign_test_<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_unique_ptr_assign_test<int>(); + new_unique_ptr_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + del_unique_ptr_assign_test<int>(); + del_unique_ptr_assign_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +#else + +static void unique_ptr_assignment() +{ +} + +#endif + +// pointer reset + +template<class T, class U> static void test_pointer_reset( boost::local_shared_ptr<U> p2 ) +{ + T * q = new T(); + + p2.reset( q ); + + BOOST_TEST_EQ( p2.get(), q ); + BOOST_TEST_EQ( p2.local_use_count(), 1 ); +} + +template<class T> static void empty_pointer_reset_test() +{ + test_pointer_reset<T>( boost::local_shared_ptr<T>() ); + test_pointer_reset<T>( boost::local_shared_ptr<T const>() ); + test_pointer_reset<T>( boost::local_shared_ptr<T volatile>() ); + test_pointer_reset<T>( boost::local_shared_ptr<T const volatile>() ); + + test_pointer_reset<T>( boost::local_shared_ptr<void>() ); + test_pointer_reset<T>( boost::local_shared_ptr<void const>() ); + test_pointer_reset<T>( boost::local_shared_ptr<void volatile>() ); + test_pointer_reset<T>( boost::local_shared_ptr<void const volatile>() ); +} + +template<class T> static void null_pointer_reset_test() +{ + test_pointer_reset<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_pointer_reset<T>( boost::local_shared_ptr<T const>( static_cast<T*>(0) ) ); + test_pointer_reset<T>( boost::local_shared_ptr<T volatile>( static_cast<T*>(0) ) ); + test_pointer_reset<T>( boost::local_shared_ptr<T const volatile>( static_cast<T*>(0) ) ); + + test_pointer_reset<T>( boost::local_shared_ptr<void>( static_cast<T*>(0) ) ); + test_pointer_reset<T>( boost::local_shared_ptr<void const>( static_cast<T*>(0) ) ); + test_pointer_reset<T>( boost::local_shared_ptr<void volatile>( static_cast<T*>(0) ) ); + test_pointer_reset<T>( boost::local_shared_ptr<void const volatile>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_pointer_reset_test() +{ + test_pointer_reset<T>( boost::local_shared_ptr<T>( new T() ) ); + test_pointer_reset<T>( boost::local_shared_ptr<T const>( new T() ) ); + test_pointer_reset<T>( boost::local_shared_ptr<T volatile>( new T() ) ); + test_pointer_reset<T>( boost::local_shared_ptr<T const volatile>( new T() ) ); + + test_pointer_reset<T>( boost::local_shared_ptr<void>( new T() ) ); + test_pointer_reset<T>( boost::local_shared_ptr<void const>( new T() ) ); + test_pointer_reset<T>( boost::local_shared_ptr<void volatile>( new T() ) ); + test_pointer_reset<T>( boost::local_shared_ptr<void const volatile>( new T() ) ); +} + +static void pointer_reset() +{ + empty_pointer_reset_test<int>(); + empty_pointer_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_pointer_reset_test<int>(); + null_pointer_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_pointer_reset_test<int>(); + new_pointer_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// deleter reset + +template<class T> class deleter +{ +private: + + bool * called_; + +public: + + explicit deleter( bool * called ): called_( called ) {} + void operator()( T * p ) { *called_ = true; delete p; } +}; + +template<class T, class U> static void test_deleter_reset( boost::local_shared_ptr<U> p2 ) +{ + T * q = new T(); + + bool called = false; + + p2.reset( q, deleter<T>( &called ) ); + + BOOST_TEST_EQ( p2.get(), q ); + BOOST_TEST_EQ( p2.local_use_count(), 1 ); + + boost::shared_ptr<U> p3( p2 ); + + BOOST_TEST( boost::get_deleter< deleter<T> >( p3 ) != 0 ); + + p3.reset(); + BOOST_TEST( !called ); + + p2.reset(); + BOOST_TEST( called ); +} + +template<class T> static void empty_deleter_reset_test() +{ + test_deleter_reset<T>( boost::local_shared_ptr<T>() ); + test_deleter_reset<T>( boost::local_shared_ptr<T const>() ); + test_deleter_reset<T>( boost::local_shared_ptr<T volatile>() ); + test_deleter_reset<T>( boost::local_shared_ptr<T const volatile>() ); + + test_deleter_reset<T>( boost::local_shared_ptr<void>() ); + test_deleter_reset<T>( boost::local_shared_ptr<void const>() ); + test_deleter_reset<T>( boost::local_shared_ptr<void volatile>() ); + test_deleter_reset<T>( boost::local_shared_ptr<void const volatile>() ); +} + +template<class T> static void null_deleter_reset_test() +{ + test_deleter_reset<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_deleter_reset<T>( boost::local_shared_ptr<T const>( static_cast<T*>(0) ) ); + test_deleter_reset<T>( boost::local_shared_ptr<T volatile>( static_cast<T*>(0) ) ); + test_deleter_reset<T>( boost::local_shared_ptr<T const volatile>( static_cast<T*>(0) ) ); + + test_deleter_reset<T>( boost::local_shared_ptr<void>( static_cast<T*>(0) ) ); + test_deleter_reset<T>( boost::local_shared_ptr<void const>( static_cast<T*>(0) ) ); + test_deleter_reset<T>( boost::local_shared_ptr<void volatile>( static_cast<T*>(0) ) ); + test_deleter_reset<T>( boost::local_shared_ptr<void const volatile>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_deleter_reset_test() +{ + test_deleter_reset<T>( boost::local_shared_ptr<T>( new T() ) ); + test_deleter_reset<T>( boost::local_shared_ptr<T const>( new T() ) ); + test_deleter_reset<T>( boost::local_shared_ptr<T volatile>( new T() ) ); + test_deleter_reset<T>( boost::local_shared_ptr<T const volatile>( new T() ) ); + + test_deleter_reset<T>( boost::local_shared_ptr<void>( new T() ) ); + test_deleter_reset<T>( boost::local_shared_ptr<void const>( new T() ) ); + test_deleter_reset<T>( boost::local_shared_ptr<void volatile>( new T() ) ); + test_deleter_reset<T>( boost::local_shared_ptr<void const volatile>( new T() ) ); +} + +static void deleter_reset() +{ + empty_deleter_reset_test<int>(); + empty_deleter_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_deleter_reset_test<int>(); + null_deleter_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_deleter_reset_test<int>(); + new_deleter_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// allocator reset + +template<class T, class U> static void test_allocator_reset( boost::local_shared_ptr<U> p2 ) +{ + T * q = new T(); + + bool called = false; + + p2.reset( q, deleter<T>( &called ), std::allocator<T>() ); + + BOOST_TEST_EQ( p2.get(), q ); + BOOST_TEST_EQ( p2.local_use_count(), 1 ); + + boost::shared_ptr<U> p3( p2 ); + + BOOST_TEST( boost::get_deleter< deleter<T> >( p3 ) != 0 ); + + p3.reset(); + BOOST_TEST( !called ); + + p2.reset(); + BOOST_TEST( called ); +} + +template<class T> static void empty_allocator_reset_test() +{ + test_allocator_reset<T>( boost::local_shared_ptr<T>() ); + test_allocator_reset<T>( boost::local_shared_ptr<T const>() ); + test_allocator_reset<T>( boost::local_shared_ptr<T volatile>() ); + test_allocator_reset<T>( boost::local_shared_ptr<T const volatile>() ); + + test_allocator_reset<T>( boost::local_shared_ptr<void>() ); + test_allocator_reset<T>( boost::local_shared_ptr<void const>() ); + test_allocator_reset<T>( boost::local_shared_ptr<void volatile>() ); + test_allocator_reset<T>( boost::local_shared_ptr<void const volatile>() ); +} + +template<class T> static void null_allocator_reset_test() +{ + test_allocator_reset<T>( boost::local_shared_ptr<T>( static_cast<T*>(0) ) ); + test_allocator_reset<T>( boost::local_shared_ptr<T const>( static_cast<T*>(0) ) ); + test_allocator_reset<T>( boost::local_shared_ptr<T volatile>( static_cast<T*>(0) ) ); + test_allocator_reset<T>( boost::local_shared_ptr<T const volatile>( static_cast<T*>(0) ) ); + + test_allocator_reset<T>( boost::local_shared_ptr<void>( static_cast<T*>(0) ) ); + test_allocator_reset<T>( boost::local_shared_ptr<void const>( static_cast<T*>(0) ) ); + test_allocator_reset<T>( boost::local_shared_ptr<void volatile>( static_cast<T*>(0) ) ); + test_allocator_reset<T>( boost::local_shared_ptr<void const volatile>( static_cast<T*>(0) ) ); +} + +template<class T> static void new_allocator_reset_test() +{ + test_allocator_reset<T>( boost::local_shared_ptr<T>( new T() ) ); + test_allocator_reset<T>( boost::local_shared_ptr<T const>( new T() ) ); + test_allocator_reset<T>( boost::local_shared_ptr<T volatile>( new T() ) ); + test_allocator_reset<T>( boost::local_shared_ptr<T const volatile>( new T() ) ); + + test_allocator_reset<T>( boost::local_shared_ptr<void>( new T() ) ); + test_allocator_reset<T>( boost::local_shared_ptr<void const>( new T() ) ); + test_allocator_reset<T>( boost::local_shared_ptr<void volatile>( new T() ) ); + test_allocator_reset<T>( boost::local_shared_ptr<void const volatile>( new T() ) ); +} + +static void allocator_reset() +{ + empty_allocator_reset_test<int>(); + empty_allocator_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + null_allocator_reset_test<int>(); + null_allocator_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_allocator_reset_test<int>(); + new_allocator_reset_test<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// aliasing reset + +struct null_deleter +{ + void operator()( void const volatile* ) {} +}; + +template<class T, class U> void test_aliasing_reset_( boost::local_shared_ptr<T> const & p1, U * p2 ) +{ + boost::local_shared_ptr<U> p3( static_cast<U*>(0), null_deleter() ); + + p3.reset( p1, p2 ); + + BOOST_TEST( p3.get() == p2 ); + BOOST_TEST( p3.local_use_count() == p1.local_use_count() ); + BOOST_TEST( !p3.owner_before( p1 ) && !p1.owner_before( p3 ) ); +} + +template<class T, class U> void test_01_aliasing_reset_() +{ + U u; + boost::local_shared_ptr<T> p1; + + test_aliasing_reset_( p1, &u ); +} + +template<class T, class U> void test_01_aliasing_reset() +{ + test_01_aliasing_reset_<T, U>(); + test_01_aliasing_reset_<T const, U>(); + test_01_aliasing_reset_<T volatile, U>(); + test_01_aliasing_reset_<T const volatile, U>(); + + test_01_aliasing_reset_<T, U volatile>(); + test_01_aliasing_reset_<T const, U volatile>(); + test_01_aliasing_reset_<T volatile, U volatile>(); + test_01_aliasing_reset_<T const volatile, U volatile>(); +} + +template<class T, class U> void test_10_aliasing_reset_() +{ + boost::local_shared_ptr<T> p1( new T() ); + test_aliasing_reset_( p1, static_cast<U*>(0) ); +} + +template<class T, class U> void test_10_aliasing_reset() +{ + test_10_aliasing_reset_<T, U>(); + test_10_aliasing_reset_<T const, U>(); + test_10_aliasing_reset_<T volatile, U>(); + test_10_aliasing_reset_<T const volatile, U>(); + + test_10_aliasing_reset_<T, U const>(); + test_10_aliasing_reset_<T const, U const>(); + test_10_aliasing_reset_<T volatile, U const>(); + test_10_aliasing_reset_<T const volatile, U const>(); + + test_10_aliasing_reset_<T, U volatile>(); + test_10_aliasing_reset_<T const, U volatile>(); + test_10_aliasing_reset_<T volatile, U volatile>(); + test_10_aliasing_reset_<T const volatile, U volatile>(); + + test_10_aliasing_reset_<T, U const volatile>(); + test_10_aliasing_reset_<T const, U const volatile>(); + test_10_aliasing_reset_<T volatile, U const volatile>(); + test_10_aliasing_reset_<T const volatile, U const volatile>(); +} + +template<class T, class U> void test_11_aliasing_reset_() +{ + U u; + boost::local_shared_ptr<T> p1( new T() ); + + test_aliasing_reset_( p1, &u ); +} + +template<class T, class U> void test_11_aliasing_reset() +{ + test_11_aliasing_reset_<T, U>(); + test_11_aliasing_reset_<T const, U>(); + test_11_aliasing_reset_<T volatile, U>(); + test_11_aliasing_reset_<T const volatile, U>(); + + test_11_aliasing_reset_<T, U volatile>(); + test_11_aliasing_reset_<T const, U volatile>(); + test_11_aliasing_reset_<T volatile, U volatile>(); + test_11_aliasing_reset_<T const volatile, U volatile>(); +} + +static void aliasing_reset() +{ + test_01_aliasing_reset<int, int>(); + test_10_aliasing_reset<int, int>(); + test_11_aliasing_reset<int, int>(); + + test_01_aliasing_reset<void, int>(); + + test_10_aliasing_reset<int, void>(); + + test_10_aliasing_reset<int, incomplete>(); + + test_01_aliasing_reset<X, X>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing_reset<X, X>(); + BOOST_TEST( X::instances == 0 ); + + test_11_aliasing_reset<X, X>(); + BOOST_TEST( X::instances == 0 ); + + test_01_aliasing_reset<int, X>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing_reset<int, X>(); + BOOST_TEST( X::instances == 0 ); + + test_11_aliasing_reset<int, X>(); + BOOST_TEST( X::instances == 0 ); + + test_01_aliasing_reset<X, int>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing_reset<X, int>(); + BOOST_TEST( X::instances == 0 ); + + test_11_aliasing_reset<X, int>(); + BOOST_TEST( X::instances == 0 ); + + test_01_aliasing_reset<void, X>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing_reset<X, void>(); + BOOST_TEST( X::instances == 0 ); + + test_10_aliasing_reset<X, incomplete>(); + BOOST_TEST( X::instances == 0 ); +} + +// element access + +template<class T> static void empty_element_access_() +{ + boost::local_shared_ptr<T> p1; + + BOOST_TEST_EQ( p1.operator->(), static_cast<T*>(0) ); + BOOST_TEST_EQ( p1.get(), static_cast<T*>(0) ); + BOOST_TEST( p1? false: true ); + BOOST_TEST( !p1 ); + BOOST_TEST_EQ( p1.local_use_count(), 0 ); +} + +template<class T> static void empty_element_access() +{ + empty_element_access_<T>(); + empty_element_access_<T const>(); + empty_element_access_<T volatile>(); + empty_element_access_<T const volatile>(); +} + +template<class T> static void new_element_access_() +{ + { + T * p0 = new T(); + boost::local_shared_ptr<T> p1( p0 ); + + BOOST_TEST_EQ( p1.operator->(), p0 ); + BOOST_TEST_EQ( p1.get(), p0 ); + BOOST_TEST_EQ( &*p1, p0 ); + BOOST_TEST( p1? true: false ); + BOOST_TEST_NOT( !p1 ); + BOOST_TEST_EQ( p1.local_use_count(), 1 ); + } + + { + T * p0 = new T[3](); + boost::local_shared_ptr<T[]> p1( p0 ); + + BOOST_TEST_EQ( p1.get(), p0 ); + + BOOST_TEST_EQ( &p1[0], &p0[0] ); + BOOST_TEST_EQ( &p1[1], &p0[1] ); + BOOST_TEST_EQ( &p1[2], &p0[2] ); + + BOOST_TEST( p1? true: false ); + BOOST_TEST_NOT( !p1 ); + BOOST_TEST_EQ( p1.local_use_count(), 1 ); + } + + { + T * p0 = new T[3](); + boost::local_shared_ptr<T[3]> p1( p0 ); + + BOOST_TEST_EQ( p1.get(), p0 ); + + BOOST_TEST_EQ( &p1[0], &p0[0] ); + BOOST_TEST_EQ( &p1[1], &p0[1] ); + BOOST_TEST_EQ( &p1[2], &p0[2] ); + + BOOST_TEST( p1? true: false ); + BOOST_TEST_NOT( !p1 ); + BOOST_TEST_EQ( p1.local_use_count(), 1 ); + } +} + +template<class T> static void new_element_access() +{ + new_element_access_<T>(); + new_element_access_<T const>(); + new_element_access_<T volatile>(); + new_element_access_<T const volatile>(); +} + +static void element_access() +{ + empty_element_access<int>(); + empty_element_access<X>(); + + BOOST_TEST( X::instances == 0 ); + + empty_element_access<incomplete>(); + empty_element_access<void>(); + + new_element_access<int>(); + new_element_access<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// shared_ptr conversion + +template<class T, class U> static void empty_shared_ptr_conversion_() +{ + boost::local_shared_ptr<T> p1; + boost::shared_ptr<U> p2( p1 ); + + BOOST_TEST_EQ( p2.get(), static_cast<U*>(0) ); + BOOST_TEST_EQ( p2.use_count(), 0 ); +} + +template<class T> static void empty_shared_ptr_conversion() +{ + empty_shared_ptr_conversion_<T, T>(); + empty_shared_ptr_conversion_<T, T const>(); + empty_shared_ptr_conversion_<T, T volatile>(); + empty_shared_ptr_conversion_<T, T const volatile>(); + + empty_shared_ptr_conversion_<T const, T const>(); + empty_shared_ptr_conversion_<T volatile, T volatile>(); + empty_shared_ptr_conversion_<T const volatile, T const volatile>(); + + empty_shared_ptr_conversion_<T, void>(); + empty_shared_ptr_conversion_<T, void const>(); + empty_shared_ptr_conversion_<T, void volatile>(); + empty_shared_ptr_conversion_<T, void const volatile>(); + + empty_shared_ptr_conversion_<T const, void const>(); + empty_shared_ptr_conversion_<T volatile, void volatile>(); + empty_shared_ptr_conversion_<T const volatile, void const volatile>(); +} + +template<class T, class U> static void new_shared_ptr_conversion_() +{ + boost::local_shared_ptr<T> p1( new T() ); + boost::shared_ptr<U> p2( p1 ); + + BOOST_TEST_EQ( p2.get(), p1.get() ); + BOOST_TEST_EQ( p2.use_count(), 2 ); + + boost::shared_ptr<U> p3( p1 ); + + BOOST_TEST_EQ( p3.get(), p1.get() ); + BOOST_TEST_EQ( p3.use_count(), 3 ); + BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); + + BOOST_TEST_EQ( p1.local_use_count(), 1 ); + + p1.reset(); + + BOOST_TEST_EQ( p2.use_count(), 2 ); + BOOST_TEST_EQ( p3.use_count(), 2 ); +} + +template<class T> static void new_shared_ptr_conversion() +{ + new_shared_ptr_conversion_<T, T>(); + new_shared_ptr_conversion_<T, T const>(); + new_shared_ptr_conversion_<T, T volatile>(); + new_shared_ptr_conversion_<T, T const volatile>(); + + new_shared_ptr_conversion_<T const, T const>(); + new_shared_ptr_conversion_<T volatile, T volatile>(); + new_shared_ptr_conversion_<T const volatile, T const volatile>(); + + new_shared_ptr_conversion_<T, void>(); + new_shared_ptr_conversion_<T, void const>(); + new_shared_ptr_conversion_<T, void volatile>(); + new_shared_ptr_conversion_<T, void const volatile>(); + + new_shared_ptr_conversion_<T const, void const>(); + new_shared_ptr_conversion_<T volatile, void volatile>(); + new_shared_ptr_conversion_<T const volatile, void const volatile>(); +} + +static void shared_ptr_conversion() +{ + empty_shared_ptr_conversion<void>(); + empty_shared_ptr_conversion<incomplete>(); + empty_shared_ptr_conversion<int>(); + empty_shared_ptr_conversion<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_shared_ptr_conversion<int>(); + new_shared_ptr_conversion<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// weak_ptr conversion + +template<class T, class U> static void empty_weak_ptr_conversion_() +{ + boost::local_shared_ptr<T> p1; + boost::weak_ptr<U> p2( p1 ); + + BOOST_TEST_EQ( p2.lock().get(), static_cast<U*>(0) ); + BOOST_TEST_EQ( p2.use_count(), 0 ); +} + +template<class T> static void empty_weak_ptr_conversion() +{ + empty_weak_ptr_conversion_<T, T>(); + empty_weak_ptr_conversion_<T, T const>(); + empty_weak_ptr_conversion_<T, T volatile>(); + empty_weak_ptr_conversion_<T, T const volatile>(); + + empty_weak_ptr_conversion_<T const, T const>(); + empty_weak_ptr_conversion_<T volatile, T volatile>(); + empty_weak_ptr_conversion_<T const volatile, T const volatile>(); + + empty_weak_ptr_conversion_<T, void>(); + empty_weak_ptr_conversion_<T, void const>(); + empty_weak_ptr_conversion_<T, void volatile>(); + empty_weak_ptr_conversion_<T, void const volatile>(); + + empty_weak_ptr_conversion_<T const, void const>(); + empty_weak_ptr_conversion_<T volatile, void volatile>(); + empty_weak_ptr_conversion_<T const volatile, void const volatile>(); +} + +template<class T, class U> static void new_weak_ptr_conversion_() +{ + boost::local_shared_ptr<T> p1( new T() ); + boost::weak_ptr<U> p2( p1 ); + + BOOST_TEST_EQ( p2.lock().get(), p1.get() ); + BOOST_TEST_EQ( p2.use_count(), 1 ); + + boost::weak_ptr<U> p3( p1 ); + + BOOST_TEST_EQ( p3.lock().get(), p1.get() ); + BOOST_TEST_EQ( p3.use_count(), 1 ); + BOOST_TEST( !(p2 < p3) && !(p3 < p2) ); + + BOOST_TEST_EQ( p1.local_use_count(), 1 ); + + p1.reset(); + + BOOST_TEST_EQ( p2.use_count(), 0 ); + BOOST_TEST_EQ( p3.use_count(), 0 ); +} + +template<class T> static void new_weak_ptr_conversion() +{ + new_weak_ptr_conversion_<T, T>(); + new_weak_ptr_conversion_<T, T const>(); + new_weak_ptr_conversion_<T, T volatile>(); + new_weak_ptr_conversion_<T, T const volatile>(); + + new_weak_ptr_conversion_<T const, T const>(); + new_weak_ptr_conversion_<T volatile, T volatile>(); + new_weak_ptr_conversion_<T const volatile, T const volatile>(); + + new_weak_ptr_conversion_<T, void>(); + new_weak_ptr_conversion_<T, void const>(); + new_weak_ptr_conversion_<T, void volatile>(); + new_weak_ptr_conversion_<T, void const volatile>(); + + new_weak_ptr_conversion_<T const, void const>(); + new_weak_ptr_conversion_<T volatile, void volatile>(); + new_weak_ptr_conversion_<T const volatile, void const volatile>(); +} + +static void weak_ptr_conversion() +{ + empty_weak_ptr_conversion<void>(); + empty_weak_ptr_conversion<incomplete>(); + empty_weak_ptr_conversion<int>(); + empty_weak_ptr_conversion<X>(); + + BOOST_TEST( X::instances == 0 ); + + new_weak_ptr_conversion<int>(); + new_weak_ptr_conversion<X>(); + + BOOST_TEST( X::instances == 0 ); +} + +// main + +int main() +{ + default_constructor(); + nullptr_constructor(); + pointer_constructor(); + deleter_constructor(); + copy_constructor(); + move_constructor(); + aliasing_constructor(); + nullptr_deleter_constructor(); + allocator_constructor(); + nullptr_allocator_constructor(); + shared_ptr_copy_constructor(); + shared_ptr_move_constructor(); + unique_ptr_constructor(); + + copy_assignment(); + move_assignment(); + nullptr_assignment(); + shared_ptr_copy_assignment(); + shared_ptr_move_assignment(); + unique_ptr_assignment(); + + default_reset(); + pointer_reset(); + deleter_reset(); + allocator_reset(); + aliasing_reset(); + + element_access(); + shared_ptr_conversion(); + weak_ptr_conversion(); + // swap_test(); + // owner_before_test(); + // equal_test(); + // operator< ? + // casts + // get_pointer + // operator<< + // hash + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/lsp_array_cast_test.cpp b/libs/smart_ptr/test/lsp_array_cast_test.cpp new file mode 100644 index 0000000000..183cddc01d --- /dev/null +++ b/libs/smart_ptr/test/lsp_array_cast_test.cpp @@ -0,0 +1,202 @@ +// +// lsp_array_cast_test.cpp +// +// Copyright 2012, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct X +{ +}; + +void static_cast_test() +{ + { + boost::local_shared_ptr<void> pv; + + boost::local_shared_ptr<int[]> pi = boost::static_pointer_cast<int[]>( pv ); + BOOST_TEST( pi.get() == 0 ); + + boost::local_shared_ptr<int[3]> pi2 = boost::static_pointer_cast<int[3]>( pv ); + BOOST_TEST( pi2.get() == 0 ); + + boost::local_shared_ptr<X[]> px = boost::static_pointer_cast<X[]>( pv ); + BOOST_TEST( px.get() == 0 ); + + boost::local_shared_ptr<X[5]> px2 = boost::static_pointer_cast<X[5]>( pv ); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::local_shared_ptr<int[]> pi( new int[2] ); + boost::local_shared_ptr<void> pv( pi ); + + boost::local_shared_ptr<int[]> pi2 = boost::static_pointer_cast<int[]>( pv ); + BOOST_TEST(pi.get() == pi2.get()); + BOOST_TEST(!(pi < pi2 || pi2 < pi)); + + boost::local_shared_ptr<int[2]> pi3 = boost::static_pointer_cast<int[2]>( pv ); + BOOST_TEST(pi.get() == pi3.get()); + BOOST_TEST(!(pi < pi3 || pi3 < pi)); + + boost::local_shared_ptr<void> pv2( pi3 ); + + boost::local_shared_ptr<int[]> pi4 = boost::static_pointer_cast<int[]>( pv2 ); + BOOST_TEST(pi.get() == pi4.get()); + BOOST_TEST(!(pi < pi4 || pi4 < pi)); + } + + { + boost::local_shared_ptr<X[]> px( new X[4] ); + boost::local_shared_ptr<void> pv( px ); + + boost::local_shared_ptr<X[]> px2 = boost::static_pointer_cast<X[]>( pv ); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + + boost::local_shared_ptr<X[4]> px3 = boost::static_pointer_cast<X[4]>( pv ); + BOOST_TEST(px.get() == px3.get()); + BOOST_TEST(!(px < px3 || px3 < px)); + + boost::local_shared_ptr<void> pv2( px3 ); + + boost::local_shared_ptr<X[]> px4 = boost::static_pointer_cast<X[]>( pv2 ); + BOOST_TEST(px.get() == px4.get()); + BOOST_TEST(!(px < px4 || px4 < px)); + } +} + +void const_cast_test() +{ + { + boost::local_shared_ptr<int const volatile[]> px; + + boost::local_shared_ptr<int[]> px2 = boost::const_pointer_cast<int[]>(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::local_shared_ptr<int const volatile[2]> px; + + boost::local_shared_ptr<int[2]> px2 = boost::const_pointer_cast<int[2]>(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::local_shared_ptr<X const volatile[]> px; + + boost::local_shared_ptr<X[]> px2 = boost::const_pointer_cast<X[]>(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::local_shared_ptr<X const volatile[5]> px; + + boost::local_shared_ptr<X[5]> px2 = boost::const_pointer_cast<X[5]>(px); + BOOST_TEST( px2.get() == 0 ); + } + + { + boost::local_shared_ptr<int const volatile[]> px( new int[3] ); + + boost::local_shared_ptr<int[]> px2 = boost::const_pointer_cast<int[]>(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } + + { + boost::local_shared_ptr<int const volatile[3]> px( new int[3] ); + + boost::local_shared_ptr<int[3]> px2 = boost::const_pointer_cast<int[3]>(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } + + { + boost::local_shared_ptr<X const volatile[]> px( new X[4] ); + + boost::local_shared_ptr<X[]> px2 = boost::const_pointer_cast<X[]>(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } + + { + boost::local_shared_ptr<X const volatile[4]> px( new X[4] ); + + boost::local_shared_ptr<X[4]> px2 = boost::const_pointer_cast<X[4]>(px); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + } +} + +void reinterpret_cast_test() +{ + { + boost::local_shared_ptr<int[]> pi; + BOOST_TEST( pi.get() == 0 ); + + boost::local_shared_ptr<int[3]> pi2 = boost::reinterpret_pointer_cast<int[3]>( pi ); + BOOST_TEST( pi2.get() == 0 ); + + boost::local_shared_ptr<int[6]> pi3 = boost::reinterpret_pointer_cast<int[6]>( pi2 ); + BOOST_TEST( pi3.get() == 0 ); + } + + { + boost::local_shared_ptr<X[]> px; + BOOST_TEST( px.get() == 0 ); + + boost::local_shared_ptr<X[5]> px2 = boost::reinterpret_pointer_cast<X[5]>( px ); + BOOST_TEST( px2.get() == 0 ); + + boost::local_shared_ptr<X[9]> px3 = boost::reinterpret_pointer_cast<X[9]>( px2 ); + BOOST_TEST( px3.get() == 0 ); + } + + { + boost::local_shared_ptr<int[]> pi( new int[2] ); + + boost::local_shared_ptr<int[2]> pi2 = boost::reinterpret_pointer_cast<int[2]>( pi ); + BOOST_TEST(pi.get() == pi2.get()); + BOOST_TEST(!(pi < pi2 || pi2 < pi)); + + boost::local_shared_ptr<int[1]> pi3 = boost::reinterpret_pointer_cast<int[1]>( pi2 ); + BOOST_TEST(pi.get() == pi3.get()); + BOOST_TEST(!(pi < pi3 || pi3 < pi)); + + boost::local_shared_ptr<int[]> pi4 = boost::reinterpret_pointer_cast<int[]>( pi3 ); + BOOST_TEST(pi.get() == pi4.get()); + BOOST_TEST(!(pi < pi4 || pi4 < pi)); + } + + { + boost::local_shared_ptr<X[]> px( new X[4] ); + + boost::local_shared_ptr<X[7]> px2 = boost::reinterpret_pointer_cast<X[7]>( px ); + BOOST_TEST(px.get() == px2.get()); + BOOST_TEST(!(px < px2 || px2 < px)); + + boost::local_shared_ptr<X[4]> px3 = boost::reinterpret_pointer_cast<X[4]>( px2 ); + BOOST_TEST(px.get() == px3.get()); + BOOST_TEST(!(px < px3 || px3 < px)); + + boost::local_shared_ptr<X[]> px4 = boost::reinterpret_pointer_cast<X[]>( px3 ); + BOOST_TEST(px.get() == px4.get()); + BOOST_TEST(!(px < px4 || px4 < px)); + } +} + +int main() +{ + static_cast_test(); + const_cast_test(); + reinterpret_cast_test(); + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/lsp_array_cv_test.cpp b/libs/smart_ptr/test/lsp_array_cv_test.cpp new file mode 100644 index 0000000000..869d2067c5 --- /dev/null +++ b/libs/smart_ptr/test/lsp_array_cv_test.cpp @@ -0,0 +1,60 @@ +// +// lsp_array_cv_test.cpp +// +// Copyright 2012, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> + +struct X +{ +}; + +class B +{ +}; + +class D: public B +{ +}; + +#define TEST_CONV( T, U ) \ + { \ + boost::local_shared_ptr< T > p1; \ + boost::local_shared_ptr< U > p2( p1 ); \ + p2 = p1; \ + boost::local_shared_ptr< U > p3 = boost::local_shared_ptr< T >(); \ + p3 = boost::local_shared_ptr< T >(); \ + } + +#define TEST_CV_TRUE( T, U ) \ + TEST_CONV( T, U ) \ + TEST_CONV( T, const U ) \ + TEST_CONV( T, volatile U ) \ + TEST_CONV( T, const volatile U ) \ + TEST_CONV( const T, const U ) \ + TEST_CONV( const T, const volatile U ) \ + TEST_CONV( volatile T, volatile U ) \ + TEST_CONV( volatile T, const volatile U ) \ + TEST_CONV( const volatile T, const volatile U ) + +int main() +{ + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_TRUE( D, B ) + + TEST_CV_TRUE( X[], X[] ) + TEST_CV_TRUE( X[3], X[3] ) + + TEST_CV_TRUE( X[3], X[] ) + + TEST_CV_TRUE( X[], void ) + TEST_CV_TRUE( X[3], void ) + + return 0; +} diff --git a/libs/smart_ptr/test/lsp_array_n_test.cpp b/libs/smart_ptr/test/lsp_array_n_test.cpp new file mode 100644 index 0000000000..a31e264652 --- /dev/null +++ b/libs/smart_ptr/test/lsp_array_n_test.cpp @@ -0,0 +1,248 @@ +// +// lsp_array_n_test.cpp +// +// Copyright 2012, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <memory> +#include <utility> + +class X: public boost::enable_shared_from_this< X > +{ +public: + + static int allocations; + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + + void* operator new[]( std::size_t n ) + { + ++allocations; + return ::operator new[]( n ); + } + + void operator delete[]( void* p ) + { + --allocations; + ::operator delete[]( p ); + } + +private: + + X( X const& ); + X& operator=( X const& ); +}; + +int X::allocations = 0; +int X::instances = 0; + +template< class T> class array_deleter +{ +public: + + static int calls; + + void operator()( T * p ) const + { + ++calls; + delete[] p; + } + +private: + + template< class Y > void operator()( Y * p ) const; +}; + +template< class T > int array_deleter< T >::calls = 0; + +int main() +{ + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + { + boost::local_shared_ptr<X[3]> px; + BOOST_TEST( !px ); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + boost::local_shared_ptr<X[3]> px2( new X[ 3 ] ); + BOOST_TEST( px2 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + { + X & rx = px2[ 0 ]; + BOOST_TEST( &rx == px2.get() ); + } + + boost::local_shared_ptr<X const[3]> px3( px2 ); + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + { + X const & rx = px3[ 1 ]; + BOOST_TEST( &rx == px3.get() + 1 ); + } + + px3.reset(); + px3 = px2; + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + boost::local_shared_ptr<X volatile[3]> px4( px2 ); + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + { + X volatile & rx = px4[ 2 ]; + BOOST_TEST( &rx == px4.get() + 2 ); + } + + px4.reset(); + px4 = px2; + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + boost::local_shared_ptr<void> px5( px2 ); + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + px5.reset(); + px5 = px2; + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + boost::weak_ptr<X[3]> wp( px ); + BOOST_TEST( wp.lock() == px ); + + boost::weak_ptr<X[3]> wp2( px2 ); + BOOST_TEST( wp2.lock() == px2 ); + + wp2.reset(); + wp2 = px2; + BOOST_TEST( wp2.lock() == px2 ); + + boost::weak_ptr<X const[3]> wp3( px2 ); + BOOST_TEST( wp3.lock() == px2 ); + + wp3.reset(); + wp3 = px2; + BOOST_TEST( wp3.lock() == px2 ); + + boost::weak_ptr<X volatile[3]> wp4( px2 ); + BOOST_TEST( wp4.lock() == px2 ); + + wp4.reset(); + wp4 = px2; + BOOST_TEST( wp4.lock() == px2 ); + + boost::weak_ptr<void> wp5( px2 ); + BOOST_TEST( wp5.lock() == px2 ); + + wp5.reset(); + wp5 = px2; + BOOST_TEST( wp5.lock() == px2 ); + + px2.reset(); + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + px3.reset(); + px4.reset(); + px5.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + BOOST_TEST( wp2.lock() == 0 ); + BOOST_TEST( wp3.lock() == 0 ); + BOOST_TEST( wp4.lock() == 0 ); + BOOST_TEST( wp5.lock() == 0 ); + } + + { + boost::local_shared_ptr<X[5]> px( new X[ 5 ], array_deleter< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 5 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 1 ); + } + + { + boost::local_shared_ptr<X[6]> px( new X[ 6 ], array_deleter< X >(), std::allocator< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 6 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 2 ); + } + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/lsp_array_test.cpp b/libs/smart_ptr/test/lsp_array_test.cpp new file mode 100644 index 0000000000..77728ea204 --- /dev/null +++ b/libs/smart_ptr/test/lsp_array_test.cpp @@ -0,0 +1,311 @@ +// +// lsp_array_test.cpp +// +// Copyright 2012, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <memory> +#include <utility> + +class X: public boost::enable_shared_from_this< X > +{ +public: + + static int allocations; + static int instances; + + X() + { + ++instances; + } + + ~X() + { + --instances; + } + + void* operator new[]( std::size_t n ) + { + ++allocations; + return ::operator new[]( n ); + } + + void operator delete[]( void* p ) + { + --allocations; + ::operator delete[]( p ); + } + +private: + + X( X const& ); + X& operator=( X const& ); +}; + +int X::allocations = 0; +int X::instances = 0; + +template< class T> class array_deleter +{ +public: + + static int calls; + + void operator()( T * p ) const + { + ++calls; + delete[] p; + } + +private: + + template< class Y > void operator()( Y * p ) const; +}; + +template< class T > int array_deleter< T >::calls = 0; + +int main() +{ + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + { + boost::local_shared_ptr<X[]> px; + BOOST_TEST( !px ); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + boost::local_shared_ptr<X[]> px2( new X[ 3 ] ); + BOOST_TEST( px2 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + { + X & rx = px2[ 0 ]; + BOOST_TEST( &rx == px2.get() ); + } + + boost::local_shared_ptr<X const[]> px3( px2 ); + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + { + X const & rx = px3[ 1 ]; + BOOST_TEST( &rx == px3.get() + 1 ); + } + + px3.reset(); + px3 = px2; + BOOST_TEST( px3 == px2 ); + BOOST_TEST( !( px2 < px3 ) && !( px3 < px2 ) ); + + boost::local_shared_ptr<X volatile[]> px4( px2 ); + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + { + X volatile & rx = px4[ 2 ]; + BOOST_TEST( &rx == px4.get() + 2 ); + } + + px4.reset(); + px4 = px2; + BOOST_TEST( px4 == px2 ); + BOOST_TEST( !( px2 < px4 ) && !( px4 < px2 ) ); + + boost::local_shared_ptr<void> px5( px2 ); + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + px5.reset(); + px5 = px2; + BOOST_TEST( px5 == px2 ); + BOOST_TEST( !( px2 < px5 ) && !( px5 < px2 ) ); + + boost::weak_ptr<X[]> wp( px ); + BOOST_TEST( wp.lock() == px ); + + boost::weak_ptr<X[]> wp2( px2 ); + BOOST_TEST( wp2.lock() == px2 ); + + wp2.reset(); + wp2 = px2; + BOOST_TEST( wp2.lock() == px2 ); + + boost::weak_ptr<X const[]> wp3( px2 ); + BOOST_TEST( wp3.lock() == px2 ); + + wp3.reset(); + wp3 = px2; + BOOST_TEST( wp3.lock() == px2 ); + + boost::weak_ptr<X volatile[]> wp4( px2 ); + BOOST_TEST( wp4.lock() == px2 ); + + wp4.reset(); + wp4 = px2; + BOOST_TEST( wp4.lock() == px2 ); + + boost::weak_ptr<void> wp5( px2 ); + BOOST_TEST( wp5.lock() == px2 ); + + wp5.reset(); + wp5 = px2; + BOOST_TEST( wp5.lock() == px2 ); + + px2.reset(); + + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 3 ); + + px3.reset(); + px4.reset(); + px5.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + + BOOST_TEST( wp2.lock() == 0 ); + BOOST_TEST( wp3.lock() == 0 ); + BOOST_TEST( wp4.lock() == 0 ); + BOOST_TEST( wp5.lock() == 0 ); + } + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + + { + std::unique_ptr<X[]> px( new X[ 4 ] ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + + boost::local_shared_ptr<X[]> px2( std::move( px ) ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + BOOST_TEST( px.get() == 0 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px2.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + } + + { + std::unique_ptr<X[]> px( new X[ 4 ] ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + + boost::local_shared_ptr<X[]> px2; + px2 = std::move( px ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 4 ); + BOOST_TEST( px.get() == 0 ); + + try + { + px2[0].shared_from_this(); + BOOST_ERROR( "px2[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px2[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px2.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + } + +#endif + + { + boost::local_shared_ptr<X[]> px( new X[ 5 ], array_deleter< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 5 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 1 ); + } + + { + boost::local_shared_ptr<X[]> px( new X[ 6 ], array_deleter< X >(), std::allocator< X >() ); + BOOST_TEST( X::allocations == 1 ); + BOOST_TEST( X::instances == 6 ); + + try + { + px[0].shared_from_this(); + BOOST_ERROR( "px[0].shared_from_this() failed to throw" ); + } + catch( boost::bad_weak_ptr const& ) + { + } + catch( ... ) + { + BOOST_ERROR( "px[0].shared_from_this() threw something else than bad_weak_ptr" ); + } + + px.reset(); + + BOOST_TEST( X::allocations == 0 ); + BOOST_TEST( X::instances == 0 ); + BOOST_TEST( array_deleter< X >::calls == 2 ); + } + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/lsp_convertible_test.cpp b/libs/smart_ptr/test/lsp_convertible_test.cpp new file mode 100644 index 0000000000..4f5017a6b8 --- /dev/null +++ b/libs/smart_ptr/test/lsp_convertible_test.cpp @@ -0,0 +1,108 @@ +#include <boost/config.hpp> + +// lsp_convertible_test.cpp +// +// Copyright 2012, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/type_traits/is_convertible.hpp> + +// + +class X; + +class B +{ +}; + +class D: public B +{ +}; + +using boost::is_convertible; + +#define TEST_CV_TRUE_( S1, T, S2, U ) \ + BOOST_TEST(( is_convertible< S1<T>, S2<U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const volatile U> >::value == true )); + +#define TEST_CV_FALSE_( S1, T, S2, U ) \ + BOOST_TEST(( is_convertible< S1<T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const volatile U> >::value == false )); + +using boost::local_shared_ptr; +using boost::shared_ptr; +using boost::weak_ptr; + +#define TEST_CV_TRUE( T, U ) \ + TEST_CV_TRUE_( local_shared_ptr, T, local_shared_ptr, U ) \ + TEST_CV_TRUE_( shared_ptr, T, local_shared_ptr, U ) + +#define TEST_CV_FALSE( T, U ) \ + TEST_CV_FALSE_( local_shared_ptr, T, local_shared_ptr, U ) \ + TEST_CV_FALSE_( shared_ptr, T, local_shared_ptr, U ) + +int main() +{ +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_FALSE( void, X ) + TEST_CV_TRUE( D, B ) + TEST_CV_FALSE( B, D ) + + TEST_CV_TRUE( X[], X[] ) + TEST_CV_FALSE( D[], B[] ) + + TEST_CV_TRUE( X[3], X[3] ) + TEST_CV_FALSE( X[3], X[4] ) + TEST_CV_FALSE( D[3], B[3] ) + + TEST_CV_TRUE( X[3], X[] ) + TEST_CV_FALSE( X[], X[3] ) + + TEST_CV_TRUE( X[], void ) + TEST_CV_FALSE( void, X[] ) + + TEST_CV_TRUE( X[3], void ) + TEST_CV_FALSE( void, X[3] ) + +#endif + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/lsp_convertible_test2.cpp b/libs/smart_ptr/test/lsp_convertible_test2.cpp new file mode 100644 index 0000000000..2104b4e6fc --- /dev/null +++ b/libs/smart_ptr/test/lsp_convertible_test2.cpp @@ -0,0 +1,108 @@ +#include <boost/config.hpp> + +// lsp_convertible_test.cpp +// +// Copyright 2012, 2017 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 <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/type_traits/is_convertible.hpp> + +// + +class X; + +class B +{ +}; + +class D: public B +{ +}; + +using boost::is_convertible; + +#define TEST_CV_TRUE_( S1, T, S2, U ) \ + BOOST_TEST(( is_convertible< S1<T>, S2<U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const volatile U> >::value == true )); + +#define TEST_CV_FALSE_( S1, T, S2, U ) \ + BOOST_TEST(( is_convertible< S1<T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const volatile U> >::value == false )); + +using boost::local_shared_ptr; +using boost::shared_ptr; +using boost::weak_ptr; + +#define TEST_CV_TRUE( T, U ) \ + TEST_CV_TRUE_( local_shared_ptr, T, shared_ptr, U ) \ + TEST_CV_TRUE_( local_shared_ptr, T, weak_ptr, U ) + +#define TEST_CV_FALSE( T, U ) \ + TEST_CV_FALSE_( local_shared_ptr, T, shared_ptr, U ) \ + TEST_CV_FALSE_( local_shared_ptr, T, weak_ptr, U ) + +int main() +{ +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) + + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_FALSE( void, X ) + TEST_CV_TRUE( D, B ) + TEST_CV_FALSE( B, D ) + + TEST_CV_TRUE( X[], X[] ) + TEST_CV_FALSE( D[], B[] ) + + TEST_CV_TRUE( X[3], X[3] ) + TEST_CV_FALSE( X[3], X[4] ) + TEST_CV_FALSE( D[3], B[3] ) + + TEST_CV_TRUE( X[3], X[] ) + TEST_CV_FALSE( X[], X[3] ) + + TEST_CV_TRUE( X[], void ) + TEST_CV_FALSE( void, X[] ) + + TEST_CV_TRUE( X[3], void ) + TEST_CV_FALSE( void, X[3] ) + +#endif + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/lwm_win32_cs_test.cpp b/libs/smart_ptr/test/lwm_win32_cs_test.cpp new file mode 100644 index 0000000000..cd8be86b4e --- /dev/null +++ b/libs/smart_ptr/test/lwm_win32_cs_test.cpp @@ -0,0 +1,18 @@ +// +// lwm_win32_cs_test.cpp +// +// Copyright 2017 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) +// + +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# include <windows.h> +# include <boost/smart_ptr/detail/lwm_win32_cs.hpp> +#endif + +int main() +{ +} diff --git a/libs/smart_ptr/test/make_local_shared_array_esft_test.cpp b/libs/smart_ptr/test/make_local_shared_array_esft_test.cpp new file mode 100644 index 0000000000..5106f39e41 --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_array_esft_test.cpp @@ -0,0 +1,66 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/enable_shared_from_this.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +class type + : public boost::enable_shared_from_this<type> { +public: + static unsigned instances; + + type() { + ++instances; + } + + ~type() { + --instances; + } + +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned type::instances = 0; + +int main() +{ + BOOST_TEST(type::instances == 0); + { + boost::local_shared_ptr<type[]> result = + boost::make_local_shared<type[]>(3); + try { + result[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + BOOST_TEST(type::instances == 0); + { + boost::local_shared_ptr<type[3]> result = + boost::make_local_shared_noinit<type[3]>(); + try { + result[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/make_local_shared_array_noinit_test.cpp b/libs/smart_ptr/test/make_local_shared_array_noinit_test.cpp new file mode 100644 index 0000000000..f4a07a2f64 --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_array_noinit_test.cpp @@ -0,0 +1,216 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/align/is_aligned.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/smart_ptr/weak_ptr.hpp> +#include <boost/type_traits/alignment_of.hpp> + +class type { +public: + static unsigned instances; + + type() + : value_(0.0) { + ++instances; + } + + ~type() { + --instances; + } + + void set(long double value) { + value_ = value; + } + + long double get() const { + return value_; + } + +private: + type(const type&); + type& operator=(const type&); + + long double value_; +}; + +unsigned type::instances = 0; + +int main() +{ + { + boost::local_shared_ptr<int[]> result = + boost::make_local_shared_noinit<int[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<int[3]> result = + boost::make_local_shared_noinit<int[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<int[][2]> result = + boost::make_local_shared_noinit<int[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<int[2][2]> result = + boost::make_local_shared_noinit<int[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[]> result = + boost::make_local_shared_noinit<const int[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[3]> result = + boost::make_local_shared_noinit<const int[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[][2]> result = + boost::make_local_shared_noinit<const int[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<const int[2][2]> result = + boost::make_local_shared_noinit<const int[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + } + { + boost::local_shared_ptr<type[]> result = + boost::make_local_shared_noinit<type[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[3]> result = + boost::make_local_shared_noinit<type[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[3]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[][2]> result = + boost::make_local_shared_noinit<type[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<type[][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[2][2]> result = + boost::make_local_shared_noinit<type[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<type[2][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[]> result = + boost::make_local_shared_noinit<const type[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<const type[]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[3]> result = + boost::make_local_shared_noinit<const type[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<const type[3]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[][2]> result = + boost::make_local_shared_noinit<const type[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<const type[][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[2][2]> result = + boost::make_local_shared_noinit<const type[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr<const type[2][2]> other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/make_local_shared_array_test.cpp b/libs/smart_ptr/test/make_local_shared_array_test.cpp new file mode 100644 index 0000000000..2781763c3e --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_array_test.cpp @@ -0,0 +1,238 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/align/is_aligned.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/smart_ptr/weak_ptr.hpp> +#include <boost/type_traits/alignment_of.hpp> + +class type { +public: + static unsigned instances; + + type() + : value_(0.0) { + ++instances; + } + + ~type() { + --instances; + } + + void set(long double value) { + value_ = value; + } + + long double get() const { + return value_; + } + +private: + type(const type&); + type& operator=(const type&); + + long double value_; +}; + +unsigned type::instances = 0; + +int main() +{ + { + boost::local_shared_ptr<int[]> result = + boost::make_local_shared<int[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<int[3]> result = + boost::make_local_shared<int[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<int[][2]> result = + boost::make_local_shared<int[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<int[2][2]> result = + boost::make_local_shared<int[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<const int[]> result = + boost::make_local_shared<const int[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<const int[3]> result = + boost::make_local_shared<const int[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr<const int[][2]> result = + boost::make_local_shared<const int[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<const int[2][2]> result = + boost::make_local_shared<const int[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<int>::value)); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 0); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 0); + } + { + boost::local_shared_ptr<type[]> result = + boost::make_local_shared<type[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[]> w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[3]> result = + boost::make_local_shared<type[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr<type[3]> w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[][2]> result = + boost::make_local_shared<type[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<type[2][2]> result = + boost::make_local_shared<type[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[]> result = + boost::make_local_shared<const type[]>(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[3]> result = + boost::make_local_shared<const type[3]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[][2]> result = + boost::make_local_shared<const type[][2]>(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr<const type[2][2]> result = + boost::make_local_shared<const type[2][2]>(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of<type>::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/make_local_shared_array_throws_test.cpp b/libs/smart_ptr/test/make_local_shared_array_throws_test.cpp new file mode 100644 index 0000000000..e1841dffaf --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_array_throws_test.cpp @@ -0,0 +1,93 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/detail/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +class type { +public: + static unsigned instances; + + type() { + if (instances == 5) { + throw true; + } + ++instances; + } + + ~type() { + --instances; + } + +private: + type(const type&); + type& operator=(const type&); +}; + +unsigned type::instances = 0; + +int main() +{ + try { + boost::make_local_shared<type[]>(6); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared<type[][2]>(3); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared<type[6]>(); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared<type[3][2]>(); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit<type[]>(6); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit<type[][2]>(3); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit<type[6]>(); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit<type[3][2]>(); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/make_local_shared_array_value_test.cpp b/libs/smart_ptr/test/make_local_shared_array_value_test.cpp new file mode 100644 index 0000000000..ab07460193 --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_array_value_test.cpp @@ -0,0 +1,55 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include <boost/detail/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +int main() +{ + { + boost::local_shared_ptr<int[]> result = + boost::make_local_shared<int[]>(4, 1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + { + boost::local_shared_ptr<int[4]> result = + boost::make_local_shared<int[4]>(1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + { + boost::local_shared_ptr<const int[]> result = + boost::make_local_shared<const int[]>(4, 1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + { + boost::local_shared_ptr<const int[4]> result = + boost::make_local_shared<const int[4]>(1); + BOOST_TEST(result[0] == 1); + BOOST_TEST(result[1] == 1); + BOOST_TEST(result[2] == 1); + BOOST_TEST(result[3] == 1); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/make_local_shared_arrays_test.cpp b/libs/smart_ptr/test/make_local_shared_arrays_test.cpp new file mode 100644 index 0000000000..986b88f697 --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_arrays_test.cpp @@ -0,0 +1,56 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> + +int main() +{ + { + boost::local_shared_ptr<int[][2]> result = + boost::make_local_shared<int[][2]>(2, {0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + { + boost::local_shared_ptr<int[2][2]> result = + boost::make_local_shared<int[2][2]>({0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + { + boost::local_shared_ptr<const int[][2]> result = + boost::make_local_shared<const int[][2]>(2, {0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + { + boost::local_shared_ptr<const int[2][2]> result = + boost::make_local_shared<const int[2][2]>({0, 1}); + BOOST_TEST(result[0][0] == 0); + BOOST_TEST(result[0][1] == 1); + BOOST_TEST(result[1][0] == 0); + BOOST_TEST(result[1][1] == 1); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/libs/smart_ptr/test/make_local_shared_esft_test.cpp b/libs/smart_ptr/test/make_local_shared_esft_test.cpp new file mode 100644 index 0000000000..b5e130eea4 --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_esft_test.cpp @@ -0,0 +1,308 @@ +// make_local_shared_esft_test.cpp +// +// Copyright 2007-2009, 2017 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 <boost/config.hpp> + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) + +int main() +{ +} + +#else + +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> + +class X: public boost::enable_shared_from_this<X> +{ +private: + + X( X const & ); + X & operator=( X const & ); + +public: + + static int instances; + + explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +int main() +{ + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >(); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared_noinit< X >(); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + return boost::report_errors(); +} + +#endif diff --git a/libs/smart_ptr/test/make_local_shared_test.cpp b/libs/smart_ptr/test/make_local_shared_test.cpp new file mode 100644 index 0000000000..e972c0d1bf --- /dev/null +++ b/libs/smart_ptr/test/make_local_shared_test.cpp @@ -0,0 +1,268 @@ +// make_local_shared_test.cpp +// +// Copyright 2007-2009, 2017 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 <boost/config.hpp> + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) + +int main() +{ +} + +#else + +#include <boost/core/lightweight_test.hpp> +#include <boost/smart_ptr/make_local_shared.hpp> +#include <boost/smart_ptr/local_shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <cstddef> + +class X +{ +private: + + X( X const & ); + X & operator=( X const & ); + + void * operator new( std::size_t n ) + { + // lack of this definition causes link errors on Comeau C++ + BOOST_ERROR( "private X::new called" ); + return ::operator new( n ); + } + + void operator delete( void * p ) + { + // lack of this definition causes link errors on MSVC + BOOST_ERROR( "private X::delete called" ); + ::operator delete( p ); + } + +public: + + static int instances; + + int v; + + explicit X( int a1 = 0, int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0, int a8 = 0, int a9 = 0 ): v( a1+a2+a3+a4+a5+a6+a7+a8+a9 ) + { + ++instances; + } + + ~X() + { + --instances; + } +}; + +int X::instances = 0; + +template<class T> static long use_count( boost::local_shared_ptr<T> const & p ) +{ + return boost::shared_ptr<T>( p ).use_count() - 1; +} + +int main() +{ + { + boost::local_shared_ptr< int > pi = boost::make_local_shared< int >(); + + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + + BOOST_TEST( *pi == 0 ); + } + + { + boost::local_shared_ptr< int > pi = boost::make_local_shared_noinit< int >(); + + BOOST_TEST( pi.get() != 0 ); + } + + { + boost::local_shared_ptr< int > pi = boost::make_local_shared< int >( 5 ); + + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + + BOOST_TEST( *pi == 5 ); + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >(); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 0 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared_noinit< X >(); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 0 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3+4 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3+4+5 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6+7 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::local_shared_ptr< X > pi = boost::make_local_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.local_use_count() == 1 ); + BOOST_TEST( use_count( pi ) == 1 ); + BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + return boost::report_errors(); +} + +#endif diff --git a/libs/smart_ptr/test/make_shared_arrays_test.cpp b/libs/smart_ptr/test/make_shared_arrays_test.cpp index 0022e018c7..598b9742bf 100644 --- a/libs/smart_ptr/test/make_shared_arrays_test.cpp +++ b/libs/smart_ptr/test/make_shared_arrays_test.cpp @@ -5,10 +5,11 @@ Copyright 2012-2015 Glen Joseph Fernandes Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) #include <boost/core/lightweight_test.hpp> #include <boost/smart_ptr/make_shared.hpp> -#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) int main() { { diff --git a/libs/smart_ptr/test/make_shared_esft_test.cpp b/libs/smart_ptr/test/make_shared_esft_test.cpp index 1956cbaaad..71b2912211 100644 --- a/libs/smart_ptr/test/make_shared_esft_test.cpp +++ b/libs/smart_ptr/test/make_shared_esft_test.cpp @@ -41,6 +41,30 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >(); + BOOST_TEST( px.use_count() == 1 ); + BOOST_TEST( X::instances == 1 ); + + try + { + boost::shared_ptr< X > qx = px->shared_from_this(); + + BOOST_TEST( px == qx ); + BOOST_TEST( !( px < qx ) && !( qx < px ) ); + + px.reset(); + BOOST_TEST( X::instances == 1 ); + } + catch( boost::bad_weak_ptr const& ) + { + BOOST_ERROR( "px->shared_from_this() failed" ); + } + } + + BOOST_TEST( X::instances == 0 ); + + { + boost::shared_ptr< X > px = boost::make_shared_noinit< X >(); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -63,6 +87,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -85,6 +110,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -107,6 +133,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -129,6 +156,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -151,6 +179,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -173,6 +202,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -195,6 +225,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -217,6 +248,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try @@ -239,6 +271,7 @@ int main() { boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 ); + BOOST_TEST( px.use_count() == 1 ); BOOST_TEST( X::instances == 1 ); try diff --git a/libs/smart_ptr/test/make_shared_test.cpp b/libs/smart_ptr/test/make_shared_test.cpp index 9ebc3fa2e7..9e3cdd3fc7 100644 --- a/libs/smart_ptr/test/make_shared_test.cpp +++ b/libs/smart_ptr/test/make_shared_test.cpp @@ -58,13 +58,24 @@ int main() boost::shared_ptr< int > pi = boost::make_shared< int >(); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); + BOOST_TEST( *pi == 0 ); } { + boost::shared_ptr< int > pi = boost::make_shared_noinit< int >(); + + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); + } + + { boost::shared_ptr< int > pi = boost::make_shared< int >( 5 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); + BOOST_TEST( *pi == 5 ); } @@ -76,6 +87,21 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); + BOOST_TEST( pi->v == 0 ); + + pi.reset(); + + BOOST_TEST( X::instances == 0 ); + } + + { + boost::shared_ptr< X > pi = boost::make_shared_noinit< X >(); + boost::weak_ptr<X> wp( pi ); + + BOOST_TEST( X::instances == 1 ); + BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 0 ); pi.reset(); @@ -89,6 +115,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1 ); pi.reset(); @@ -102,6 +129,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2 ); pi.reset(); @@ -115,6 +143,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3 ); pi.reset(); @@ -128,6 +157,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3+4 ); pi.reset(); @@ -141,6 +171,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3+4+5 ); pi.reset(); @@ -154,6 +185,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3+4+5+6 ); pi.reset(); @@ -167,6 +199,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3+4+5+6+7 ); pi.reset(); @@ -180,6 +213,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8 ); pi.reset(); @@ -193,6 +227,7 @@ int main() BOOST_TEST( X::instances == 1 ); BOOST_TEST( pi.get() != 0 ); + BOOST_TEST( pi.use_count() == 1 ); BOOST_TEST( pi->v == 1+2+3+4+5+6+7+8+9 ); pi.reset(); diff --git a/libs/smart_ptr/test/pointer_cast_test2.cpp b/libs/smart_ptr/test/pointer_cast_test2.cpp index eb28a5dc93..fd1d63e8e8 100644 --- a/libs/smart_ptr/test/pointer_cast_test2.cpp +++ b/libs/smart_ptr/test/pointer_cast_test2.cpp @@ -122,7 +122,7 @@ static void test_const_cast() BOOST_TEST( p2.get() == 0 ); BOOST_TEST_EQ( p3.get(), q1 ); - } + } } struct B2 diff --git a/libs/smart_ptr/test/shared_ptr_alloc_construct11_test.cpp b/libs/smart_ptr/test/shared_ptr_alloc_construct11_test.cpp index 436f828f57..3ddabc85e9 100644 --- a/libs/smart_ptr/test/shared_ptr_alloc_construct11_test.cpp +++ b/libs/smart_ptr/test/shared_ptr_alloc_construct11_test.cpp @@ -14,7 +14,7 @@ struct counters { unsigned construct; }; -template<class T> +template<class T = void> class creator { public: typedef T value_type; @@ -101,7 +101,7 @@ int main() { counters state = { }; boost::shared_ptr<int[]> pointer = - boost::allocate_shared<int[]>(creator<int>(&state), 5); + boost::allocate_shared<int[]>(creator<>(&state), 5); BOOST_TEST(state.allocate == 1); BOOST_TEST(state.construct == 5); pointer.reset(); @@ -111,7 +111,7 @@ int main() { counters state = { }; boost::shared_ptr<int[5]> pointer = - boost::allocate_shared<int[5]>(creator<int>(&state)); + boost::allocate_shared<int[5]>(creator<>(&state)); BOOST_TEST(state.allocate == 1); BOOST_TEST(state.construct == 5); pointer.reset(); diff --git a/libs/smart_ptr/test/shared_ptr_fn_test.cpp b/libs/smart_ptr/test/shared_ptr_fn_test.cpp new file mode 100644 index 0000000000..dfbdf1893f --- /dev/null +++ b/libs/smart_ptr/test/shared_ptr_fn_test.cpp @@ -0,0 +1,43 @@ +// +// shared_ptr_fn_test.cpp +// +// Copyright 2017 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 <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/core/lightweight_test.hpp> + +static void f() +{ +} + +struct null_deleter +{ + template<class Y> void operator()( Y* ) {} +}; + +int main() +{ + boost::shared_ptr<void()> pf( f, null_deleter() ); + + BOOST_TEST( pf.get() == f ); + BOOST_TEST_EQ( pf.use_count(), 1 ); + BOOST_TEST( boost::get_deleter<null_deleter>( pf ) != 0 ); + + boost::weak_ptr<void()> wp( pf ); + + BOOST_TEST( wp.lock().get() == f ); + BOOST_TEST_EQ( wp.use_count(), 1 ); + + pf.reset(); + + BOOST_TEST( wp.lock().get() == 0 ); + BOOST_TEST_EQ( wp.use_count(), 0 ); + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/sp_bml_unique_ptr_test.cpp b/libs/smart_ptr/test/sp_bml_unique_ptr_test.cpp index 0d4921dc3f..e414552998 100644 --- a/libs/smart_ptr/test/sp_bml_unique_ptr_test.cpp +++ b/libs/smart_ptr/test/sp_bml_unique_ptr_test.cpp @@ -12,6 +12,7 @@ #include <boost/enable_shared_from_this.hpp> #include <boost/detail/lightweight_test.hpp> #include <boost/move/unique_ptr.hpp> +#include <boost/type_traits/remove_reference.hpp> #include <memory> #include <utility> @@ -66,11 +67,42 @@ struct YD { void operator()( Y* p ) const { - p->deleted_ = true; - delete p; + if( p ) + { + p->deleted_ = true; + delete p; + } + else + { + BOOST_ERROR( "YD::operator()(0) called" ); + } } }; +template<class U, class T, class D> static void test_null_unique_ptr( boost::movelib::unique_ptr<T, D> p1, boost::movelib::unique_ptr<T, D> p2 ) +{ + BOOST_TEST( T::instances == 0 ); + + boost::shared_ptr<U> sp( boost::move( p1 ) ); + + BOOST_TEST( sp.get() == 0 ); + BOOST_TEST( sp.use_count() == 0 ); + + sp.reset( new T, typename boost::remove_reference<D>::type() ); + + BOOST_TEST( sp.get() != 0 ); + BOOST_TEST( sp.use_count() == 1 ); + + BOOST_TEST( T::instances == 1 ); + + sp = boost::move( p2 ); + + BOOST_TEST( sp.get() == 0 ); + BOOST_TEST( sp.use_count() == 0 ); + + BOOST_TEST( T::instances == 0 ); +} + int main() { { @@ -235,5 +267,28 @@ int main() BOOST_TEST( Y::instances == 0 ); } + { + test_null_unique_ptr<X>( boost::movelib::unique_ptr<X>(), boost::movelib::unique_ptr<X>() ); + test_null_unique_ptr<X const>( boost::movelib::unique_ptr<X>(), boost::movelib::unique_ptr<X>() ); + test_null_unique_ptr<void>( boost::movelib::unique_ptr<X>(), boost::movelib::unique_ptr<X>() ); + test_null_unique_ptr<void const>( boost::movelib::unique_ptr<X>(), boost::movelib::unique_ptr<X>() ); + } + + { + test_null_unique_ptr<Y>( boost::movelib::unique_ptr<Y, YD>( 0, YD() ), boost::movelib::unique_ptr<Y, YD>( 0, YD() ) ); + test_null_unique_ptr<Y const>( boost::movelib::unique_ptr<Y, YD>( 0, YD() ), boost::movelib::unique_ptr<Y, YD>( 0, YD() ) ); + test_null_unique_ptr<void>( boost::movelib::unique_ptr<Y, YD>( 0, YD() ), boost::movelib::unique_ptr<Y, YD>( 0, YD() ) ); + test_null_unique_ptr<void const>( boost::movelib::unique_ptr<Y, YD>( 0, YD() ), boost::movelib::unique_ptr<Y, YD>( 0, YD() ) ); + } + + { + YD yd; + + test_null_unique_ptr<Y>( boost::movelib::unique_ptr<Y, YD&>( 0, yd ), boost::movelib::unique_ptr<Y, YD&>( 0, yd ) ); + test_null_unique_ptr<Y const>( boost::movelib::unique_ptr<Y, YD&>( 0, yd ), boost::movelib::unique_ptr<Y, YD&>( 0, yd ) ); + test_null_unique_ptr<void>( boost::movelib::unique_ptr<Y, YD&>( 0, yd ), boost::movelib::unique_ptr<Y, YD&>( 0, yd ) ); + test_null_unique_ptr<void const>( boost::movelib::unique_ptr<Y, YD&>( 0, yd ), boost::movelib::unique_ptr<Y, YD&>( 0, yd ) ); + } + return boost::report_errors(); } diff --git a/libs/smart_ptr/test/sp_constexpr_test.cpp b/libs/smart_ptr/test/sp_constexpr_test.cpp new file mode 100644 index 0000000000..7238e264e0 --- /dev/null +++ b/libs/smart_ptr/test/sp_constexpr_test.cpp @@ -0,0 +1,86 @@ +// +// sp_constexpr_test.cpp +// +// Copyright 2017 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 <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#define HAVE_CONSTEXPR_INIT + +#if defined( BOOST_NO_CXX11_CONSTEXPR ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if defined(__clang__) && defined( BOOST_NO_CXX14_CONSTEXPR ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if !defined( HAVE_CONSTEXPR_INIT ) + +int main() +{ +} + +#else + +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/core/lightweight_test.hpp> + +struct X: public boost::enable_shared_from_this<X> +{ +}; + +struct Z +{ + Z(); +}; + +static Z z; + +static boost::shared_ptr<X> p1; +static boost::weak_ptr<X> p2; + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + static boost::shared_ptr<X> p3( nullptr ); +#endif + +Z::Z() +{ + p1.reset( new X ); + p2 = p1; +#if !defined( BOOST_NO_CXX11_NULLPTR ) + p3.reset( new X ); +#endif +} + +int main() +{ + BOOST_TEST( p1.get() != 0 ); + BOOST_TEST_EQ( p1.use_count(), 1 ); + + BOOST_TEST_EQ( p2.use_count(), 1 ); + BOOST_TEST_EQ( p2.lock(), p1 ); + +#if !defined( BOOST_NO_CXX11_NULLPTR ) + + BOOST_TEST( p3.get() != 0 ); + BOOST_TEST_EQ( p3.use_count(), 1 ); + +#endif + + return boost::report_errors(); +} + +#endif // #if defined( BOOST_NO_CXX11_CONSEXPR ) diff --git a/libs/smart_ptr/test/sp_constexpr_test2.cpp b/libs/smart_ptr/test/sp_constexpr_test2.cpp new file mode 100644 index 0000000000..e508fa1835 --- /dev/null +++ b/libs/smart_ptr/test/sp_constexpr_test2.cpp @@ -0,0 +1,68 @@ +// +// sp_constexpr_test2.cpp +// +// Copyright 2017 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 <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#define HAVE_CONSTEXPR_INIT + +#if defined( BOOST_NO_CXX11_CONSTEXPR ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if defined(__clang__) && defined( BOOST_NO_CXX14_CONSTEXPR ) +# undef HAVE_CONSTEXPR_INIT +#endif + +#if !defined( HAVE_CONSTEXPR_INIT ) + +int main() +{ +} + +#else + +#include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/core/lightweight_test.hpp> + +struct X: public boost::enable_shared_from_this<X> +{ + int v_; + + constexpr X() BOOST_NOEXCEPT: v_( 1 ) + { + } +}; + +struct Z +{ + Z(); +}; + +static Z z; +static X x; + +Z::Z() +{ + BOOST_TEST_EQ( x.v_, 1 ); +} + +int main() +{ + return boost::report_errors(); +} + +#endif // #if defined( BOOST_NO_CXX11_CONSEXPR ) diff --git a/libs/smart_ptr/test/sp_convertible_test2.cpp b/libs/smart_ptr/test/sp_convertible_test2.cpp new file mode 100644 index 0000000000..7635d82731 --- /dev/null +++ b/libs/smart_ptr/test/sp_convertible_test2.cpp @@ -0,0 +1,108 @@ +#include <boost/config.hpp> + +// sp_convertible_test2.cpp +// +// Copyright 2012, 2017 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 <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/type_traits/is_convertible.hpp> + +// + +class X; + +class B +{ +}; + +class D: public B +{ +}; + +using boost::is_convertible; + +#define TEST_CV_TRUE_( S1, T, S2, U ) \ + BOOST_TEST(( is_convertible< S1<T>, S2<U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const volatile U> >::value == true )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const volatile U> >::value == true )); + +#define TEST_CV_FALSE_( S1, T, S2, U ) \ + BOOST_TEST(( is_convertible< S1<T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<volatile T>, S2<const volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<volatile U> >::value == false )); \ + BOOST_TEST(( is_convertible< S1<const volatile T>, S2<const volatile U> >::value == false )); + +using boost::shared_ptr; +using boost::weak_ptr; + +#define TEST_CV_TRUE( T, U ) \ + TEST_CV_TRUE_( shared_ptr, T, shared_ptr, U ) \ + TEST_CV_TRUE_( shared_ptr, T, weak_ptr, U ) \ + TEST_CV_TRUE_( weak_ptr, T, weak_ptr, U ) + +#define TEST_CV_FALSE( T, U ) \ + TEST_CV_FALSE_( shared_ptr, T, shared_ptr, U ) \ + TEST_CV_FALSE_( shared_ptr, T, weak_ptr, U ) \ + TEST_CV_FALSE_( weak_ptr, T, weak_ptr, U ) + +int main() +{ +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + TEST_CV_TRUE( X, X ) + TEST_CV_TRUE( X, void ) + TEST_CV_FALSE( void, X ) + TEST_CV_TRUE( D, B ) + TEST_CV_FALSE( B, D ) + + TEST_CV_TRUE( X[], X[] ) + TEST_CV_FALSE( D[], B[] ) + + TEST_CV_TRUE( X[3], X[3] ) + TEST_CV_FALSE( X[3], X[4] ) + TEST_CV_FALSE( D[3], B[3] ) + + TEST_CV_TRUE( X[3], X[] ) + TEST_CV_FALSE( X[], X[3] ) + + TEST_CV_TRUE( X[], void ) + TEST_CV_FALSE( void, X[] ) + + TEST_CV_TRUE( X[3], void ) + TEST_CV_FALSE( void, X[3] ) + +#endif + + return boost::report_errors(); +} diff --git a/libs/smart_ptr/test/sp_unique_ptr_test.cpp b/libs/smart_ptr/test/sp_unique_ptr_test.cpp index a6d1e4c233..8e82959279 100644 --- a/libs/smart_ptr/test/sp_unique_ptr_test.cpp +++ b/libs/smart_ptr/test/sp_unique_ptr_test.cpp @@ -11,6 +11,7 @@ #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/detail/lightweight_test.hpp> +#include <boost/type_traits/remove_reference.hpp> #include <memory> #include <utility> @@ -67,11 +68,42 @@ struct YD { void operator()( Y* p ) const { - p->deleted_ = true; - delete p; + if( p ) + { + p->deleted_ = true; + delete p; + } + else + { + BOOST_ERROR( "YD::operator()(0) called" ); + } } }; +template<class U, class T, class D> static void test_null_unique_ptr( std::unique_ptr<T, D> p1, std::unique_ptr<T, D> p2 ) +{ + BOOST_TEST( T::instances == 0 ); + + boost::shared_ptr<U> sp( std::move( p1 ) ); + + BOOST_TEST( sp.get() == 0 ); + BOOST_TEST( sp.use_count() == 0 ); + + sp.reset( new T, typename boost::remove_reference<D>::type() ); + + BOOST_TEST( sp.get() != 0 ); + BOOST_TEST( sp.use_count() == 1 ); + + BOOST_TEST( T::instances == 1 ); + + sp = std::move( p2 ); + + BOOST_TEST( sp.get() == 0 ); + BOOST_TEST( sp.use_count() == 0 ); + + BOOST_TEST( T::instances == 0 ); +} + int main() { { @@ -226,6 +258,29 @@ int main() BOOST_TEST( Y::instances == 0 ); } + { + test_null_unique_ptr<X>( std::unique_ptr<X>(), std::unique_ptr<X>() ); + test_null_unique_ptr<X const>( std::unique_ptr<X>(), std::unique_ptr<X>() ); + test_null_unique_ptr<void>( std::unique_ptr<X>(), std::unique_ptr<X>() ); + test_null_unique_ptr<void const>( std::unique_ptr<X>(), std::unique_ptr<X>() ); + } + + { + test_null_unique_ptr<Y>( std::unique_ptr<Y, YD>( 0, YD() ), std::unique_ptr<Y, YD>( 0, YD() ) ); + test_null_unique_ptr<Y const>( std::unique_ptr<Y, YD>( 0, YD() ), std::unique_ptr<Y, YD>( 0, YD() ) ); + test_null_unique_ptr<void>( std::unique_ptr<Y, YD>( 0, YD() ), std::unique_ptr<Y, YD>( 0, YD() ) ); + test_null_unique_ptr<void const>( std::unique_ptr<Y, YD>( 0, YD() ), std::unique_ptr<Y, YD>( 0, YD() ) ); + } + + { + YD yd; + + test_null_unique_ptr<Y>( std::unique_ptr<Y, YD&>( 0, yd ), std::unique_ptr<Y, YD&>( 0, yd ) ); + test_null_unique_ptr<Y const>( std::unique_ptr<Y, YD&>( 0, yd ), std::unique_ptr<Y, YD&>( 0, yd ) ); + test_null_unique_ptr<void>( std::unique_ptr<Y, YD&>( 0, yd ), std::unique_ptr<Y, YD&>( 0, yd ) ); + test_null_unique_ptr<void const>( std::unique_ptr<Y, YD&>( 0, yd ), std::unique_ptr<Y, YD&>( 0, yd ) ); + } + return boost::report_errors(); } |