From be736e508821560138d980766a986ca12cc79cf3 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Thu, 29 Jun 2017 12:46:39 -0400 Subject: [PATCH] Implement allocate_local_shared for arrays Also fix the local_shared_ptr constructor to use element_type --- .../smart_ptr/allocate_local_shared_array.hpp | 240 ++++++++++++++++ .../boost/smart_ptr/allocate_shared_array.hpp | 4 + include/boost/smart_ptr/local_shared_ptr.hpp | 2 +- .../smart_ptr/make_local_shared_array.hpp | 98 +++---- test/Jamfile | 14 + ...cate_local_shared_array_construct_test.cpp | 162 +++++++++++ .../allocate_local_shared_array_esft_test.cpp | 94 +++++++ ...llocate_local_shared_array_noinit_test.cpp | 245 ++++++++++++++++ test/allocate_local_shared_array_test.cpp | 266 ++++++++++++++++++ ...llocate_local_shared_array_throws_test.cpp | 121 ++++++++ ...allocate_local_shared_array_value_test.cpp | 83 ++++++ test/allocate_local_shared_arrays_test.cpp | 90 ++++++ test/make_local_shared_array_esft_test.cpp | 57 ++++ test/make_local_shared_array_noinit_test.cpp | 207 ++++++++++++++ test/make_local_shared_array_test.cpp | 229 +++++++++++++++ test/make_local_shared_array_throws_test.cpp | 84 ++++++ test/make_local_shared_array_value_test.cpp | 46 +++ test/make_local_shared_arrays_test.cpp | 53 ++++ 18 files changed, 2047 insertions(+), 48 deletions(-) create mode 100644 include/boost/smart_ptr/allocate_local_shared_array.hpp create mode 100644 test/allocate_local_shared_array_construct_test.cpp create mode 100644 test/allocate_local_shared_array_esft_test.cpp create mode 100644 test/allocate_local_shared_array_noinit_test.cpp create mode 100644 test/allocate_local_shared_array_test.cpp create mode 100644 test/allocate_local_shared_array_throws_test.cpp create mode 100644 test/allocate_local_shared_array_value_test.cpp create mode 100644 test/allocate_local_shared_arrays_test.cpp create mode 100644 test/make_local_shared_array_esft_test.cpp create mode 100644 test/make_local_shared_array_noinit_test.cpp create mode 100644 test/make_local_shared_array_test.cpp create mode 100644 test/make_local_shared_array_throws_test.cpp create mode 100644 test/make_local_shared_array_value_test.cpp create mode 100644 test/make_local_shared_arrays_test.cpp diff --git a/include/boost/smart_ptr/allocate_local_shared_array.hpp b/include/boost/smart_ptr/allocate_local_shared_array.hpp new file mode 100644 index 0000000..9760eea --- /dev/null +++ b/include/boost/smart_ptr/allocate_local_shared_array.hpp @@ -0,0 +1,240 @@ +/* +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) +*/ +#ifndef BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP +#define BOOST_SMART_PTR_ALLOCATE_LOCAL_SHARED_ARRAY_HPP + +#include +#include + +namespace boost { +namespace detail { + +template +struct lsp_if_array { }; + +template +struct lsp_if_array { + typedef boost::local_shared_ptr type; +}; + +template +struct lsp_if_size_array { }; + +template +struct lsp_if_size_array { + typedef boost::local_shared_ptr type; +}; + +class lsp_array_base + : public local_counted_base { +public: + void set(sp_counted_base* base) BOOST_SP_NOEXCEPT { + shared_count(base).swap(count_); + } + + virtual void local_cb_destroy() BOOST_SP_NOEXCEPT { + shared_count().swap(count_); + } + + virtual shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT { + return count_; + } + +private: + shared_count count_; +}; + +template +class lsp_array_state + : public lsp_array_base { +public: + typedef A type; + + lsp_array_state(const A& allocator, std::size_t size) BOOST_SP_NOEXCEPT + : allocator_(allocator), + size_(size) { } + + A& allocator() BOOST_SP_NOEXCEPT { + return allocator_; + } + + std::size_t size() const BOOST_SP_NOEXCEPT { + return size_; + } + +private: + A allocator_; + std::size_t size_; +}; + +template +class lsp_size_array_state + : public lsp_array_base { +public: + typedef A type; + + lsp_size_array_state(const A& allocator, std::size_t) BOOST_SP_NOEXCEPT + : allocator_(allocator) { } + + A& allocator() BOOST_SP_NOEXCEPT { + return allocator_; + } + + BOOST_CONSTEXPR std::size_t size() const BOOST_SP_NOEXCEPT { + return N; + } + +private: + A allocator_; +}; + +} /* detail */ + +template +inline typename detail::lsp_if_array::type +allocate_local_shared(const A& allocator, std::size_t count) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::lsp_array_state state; + typedef detail::sp_array_base base; + std::size_t size = count * detail::sp_array_count::value; + detail::sp_array_result result(allocator, size); + base* node = result.get(); + ::new(static_cast(node)) base(allocator, size); + detail::lsp_array_base& local = node->state(); + local.set(node); + void* start = detail::sp_array_start(node); + result.release(); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), + static_cast(start), &local); +} + +template +inline typename detail::lsp_if_size_array::type +allocate_local_shared(const A& allocator) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; + enum { + size = detail::sp_array_count::value + }; + typedef detail::lsp_size_array_state state; + typedef detail::sp_array_base base; + detail::sp_array_result result(allocator, size); + base* node = result.get(); + ::new(static_cast(node)) base(allocator, size); + detail::lsp_array_base& local = node->state(); + local.set(node); + void* start = detail::sp_array_start(node); + result.release(); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), + static_cast(start), &local); +} + +template +inline typename detail::lsp_if_array::type +allocate_local_shared(const A& allocator, std::size_t count, + const typename detail::sp_array_element::type& value) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::lsp_array_state state; + typedef detail::sp_array_base base; + std::size_t size = count * detail::sp_array_count::value; + detail::sp_array_result result(allocator, size); + base* node = result.get(); + ::new(static_cast(node)) base(allocator, size, + reinterpret_cast(&value), + detail::sp_array_count::value); + detail::lsp_array_base& local = node->state(); + local.set(node); + void* start = detail::sp_array_start(node); + result.release(); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), + static_cast(start), &local); +} + +template +inline typename detail::lsp_if_size_array::type +allocate_local_shared(const A& allocator, + const typename detail::sp_array_element::type& value) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; + enum { + size = detail::sp_array_count::value + }; + typedef detail::lsp_size_array_state state; + typedef detail::sp_array_base base; + detail::sp_array_result result(allocator, size); + base* node = result.get(); + ::new(static_cast(node)) base(allocator, size, + reinterpret_cast(&value), + detail::sp_array_count::value); + detail::lsp_array_base& local = node->state(); + local.set(node); + void* start = detail::sp_array_start(node); + result.release(); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), + static_cast(start), &local); +} + +template +inline typename detail::lsp_if_array::type +allocate_local_shared_noinit(const A& allocator, std::size_t count) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; + typedef detail::lsp_array_state state; + typedef detail::sp_array_base base; + std::size_t size = count * detail::sp_array_count::value; + detail::sp_array_result result(allocator, size); + base* node = result.get(); + ::new(static_cast(node)) base(detail::sp_default(), + allocator, size); + detail::lsp_array_base& local = node->state(); + local.set(node); + void* start = detail::sp_array_start(node); + result.release(); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), + static_cast(start), &local); +} + +template +inline typename detail::lsp_if_size_array::type +allocate_local_shared_noinit(const A& allocator) +{ + typedef typename detail::sp_array_element::type type; + typedef typename detail::sp_array_scalar::type scalar; + typedef typename detail::sp_bind_allocator::type other; + enum { + size = detail::sp_array_count::value + }; + typedef detail::lsp_size_array_state state; + typedef detail::sp_array_base base; + detail::sp_array_result result(allocator, size); + base* node = result.get(); + ::new(static_cast(node)) base(detail::sp_default(), + allocator, size); + detail::lsp_array_base& local = node->state(); + local.set(node); + void* start = detail::sp_array_start(node); + result.release(); + return local_shared_ptr(detail::lsp_internal_constructor_tag(), + static_cast(start), &local); +} + +} /* boost */ + +#endif diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 0bd9b04..1b3cfcf 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -502,6 +502,10 @@ public: state_.size()); } + T& state() BOOST_SP_NOEXCEPT { + return state_; + } + virtual void dispose() { sp_array_destroy(state_.allocator(), sp_array_start(this), state_.size()); diff --git a/include/boost/smart_ptr/local_shared_ptr.hpp b/include/boost/smart_ptr/local_shared_ptr.hpp index 2e3b8bf..0d1fa01 100644 --- a/include/boost/smart_ptr/local_shared_ptr.hpp +++ b/include/boost/smart_ptr/local_shared_ptr.hpp @@ -149,7 +149,7 @@ public: #endif // internal constructor, used by make_shared - BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, T * px_, boost::detail::local_counted_base * pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ ) + BOOST_CONSTEXPR local_shared_ptr( boost::detail::lsp_internal_constructor_tag, element_type * px_, boost::detail::local_counted_base * pn_ ) BOOST_SP_NOEXCEPT : px( px_ ), pn( pn_ ) { } diff --git a/include/boost/smart_ptr/make_local_shared_array.hpp b/include/boost/smart_ptr/make_local_shared_array.hpp index 136c767..663f834 100644 --- a/include/boost/smart_ptr/make_local_shared_array.hpp +++ b/include/boost/smart_ptr/make_local_shared_array.hpp @@ -1,63 +1,67 @@ -#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP_INCLUDED -#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP_INCLUDED +/* +Copyright 2017 Peter Dimov +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) -// make_local_shared_array.hpp -// -// 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 -// -// See http://www.boost.org/libs/smart_ptr/ for documentation. +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP +#define BOOST_SMART_PTR_MAKE_LOCAL_SHARED_ARRAY_HPP -#include -#include -#include -#include +#include -namespace boost +namespace boost { + +template +inline typename detail::lsp_if_size_array::type +make_local_shared() { - -namespace detail -{ - -template struct lsp_if_array -{ -}; - -template struct lsp_if_array -{ - typedef boost::local_shared_ptr type; -}; - -template struct lsp_if_array -{ - typedef boost::local_shared_ptr type; -}; - -} // namespace detail - -template typename boost::detail::lsp_if_array::type make_local_shared( Args&&... args ) -{ - return boost::make_shared( std::forward(args)... ); + return boost::allocate_local_shared(std::allocator::type>()); } -template typename boost::detail::lsp_if_array::type make_local_shared_noinit( Args&&... args ) +template +inline typename detail::lsp_if_size_array::type +make_local_shared(const typename detail::sp_array_element::type& value) { - return boost::make_shared_noinit( std::forward(args)... ); + return boost::allocate_local_shared(std::allocator::type>(), value); } -template typename boost::detail::lsp_if_array::type allocate_local_shared( A const & a, Args&&... args ) +template +inline typename detail::lsp_if_array::type +make_local_shared(std::size_t size) { - return boost::allocate_shared( a, std::forward(args)... ); + return boost::allocate_local_shared(std::allocator::type>(), size); } -template typename boost::detail::lsp_if_array::type allocate_local_shared_noinit( A const & a, Args&&... args ) +template +inline typename detail::lsp_if_array::type +make_local_shared(std::size_t size, + const typename detail::sp_array_element::type& value) { - return boost::allocate_shared_noinit( a, std::forward(args)... ); + return boost::allocate_local_shared(std::allocator::type>(), size, value); } -} // namespace boost +template +inline typename detail::lsp_if_size_array::type +make_local_shared_noinit() +{ + return allocate_local_shared_noinit(std::allocator::type>()); +} -#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED +template +inline typename detail::lsp_if_array::type +make_local_shared_noinit(std::size_t size) +{ + return allocate_local_shared_noinit(std::allocator::type>(), size); +} + +} /* boost */ + +#endif diff --git a/test/Jamfile b/test/Jamfile index a80e655..bab6fa8 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -242,6 +242,20 @@ 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 : : : gcc-4.6.3_0x:-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 : : : gcc-4.6.3_0x:-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/test/allocate_local_shared_array_construct_test.cpp b/test/allocate_local_shared_array_construct_test.cpp new file mode 100644 index 0000000..c5bc3ef --- /dev/null +++ b/test/allocate_local_shared_array_construct_test.cpp @@ -0,0 +1,162 @@ +/* +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 +#include + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +struct allow { }; + +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } + + template + void construct(U* ptr) { + ::new(static_cast(ptr)) U(allow()); + } + + template + void destroy(U* ptr) { + ptr->~U(); + } + +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + 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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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/test/allocate_local_shared_array_esft_test.cpp b/test/allocate_local_shared_array_esft_test.cpp new file mode 100644 index 0000000..8f5195e --- /dev/null +++ b/test/allocate_local_shared_array_esft_test.cpp @@ -0,0 +1,94 @@ +/* +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 +#include +#include + +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + return false; +} + +class type + : public boost::enable_shared_from_this { +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 result = + boost::allocate_local_shared(creator(), 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 result = + boost::allocate_local_shared_noinit(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(); +} diff --git a/test/allocate_local_shared_array_noinit_test.cpp b/test/allocate_local_shared_array_noinit_test.cpp new file mode 100644 index 0000000..13e01f3 --- /dev/null +++ b/test/allocate_local_shared_array_noinit_test.cpp @@ -0,0 +1,245 @@ +/* +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 +#include +#include +#include +#include + +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + 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 result = + boost::allocate_local_shared_noinit(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::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(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::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared_noinit(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/allocate_local_shared_array_test.cpp b/test/allocate_local_shared_array_test.cpp new file mode 100644 index 0000000..cc0e697 --- /dev/null +++ b/test/allocate_local_shared_array_test.cpp @@ -0,0 +1,266 @@ +/* +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 +#include +#include +#include +#include + +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + 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 result = + boost::allocate_local_shared(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::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(creator()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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::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 result = + boost::allocate_local_shared(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::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 result = + boost::allocate_local_shared(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::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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::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 result = + boost::allocate_local_shared(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::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 result = + boost::allocate_local_shared(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::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(creator()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(creator<>()); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/allocate_local_shared_array_throws_test.cpp b/test/allocate_local_shared_array_throws_test.cpp new file mode 100644 index 0000000..6c344f9 --- /dev/null +++ b/test/allocate_local_shared_array_throws_test.cpp @@ -0,0 +1,121 @@ +/* +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 +#include + +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + 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(creator(), 6); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared(creator(), 3); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared(creator<>()); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared(creator<>()); + BOOST_ERROR("allocate_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit(creator<>(), 6); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit(creator<>(), 3); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit(creator<>()); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::allocate_local_shared_noinit(creator<>()); + BOOST_ERROR("allocate_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/allocate_local_shared_array_value_test.cpp b/test/allocate_local_shared_array_value_test.cpp new file mode 100644 index 0000000..8fe669e --- /dev/null +++ b/test/allocate_local_shared_array_value_test.cpp @@ -0,0 +1,83 @@ +/* +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 +#include + +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + return false; +} + +int main() +{ + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(creator(), 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 result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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(); +} diff --git a/test/allocate_local_shared_arrays_test.cpp b/test/allocate_local_shared_arrays_test.cpp new file mode 100644 index 0000000..2b6ce0c --- /dev/null +++ b/test/allocate_local_shared_arrays_test.cpp @@ -0,0 +1,90 @@ +/* +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 +#include + +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +template +struct creator { + typedef T value_type; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } +}; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + return false; +} + +int main() +{ + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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); + } + { + boost::local_shared_ptr result = + boost::allocate_local_shared(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 result = + boost::allocate_local_shared(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/test/make_local_shared_array_esft_test.cpp b/test/make_local_shared_array_esft_test.cpp new file mode 100644 index 0000000..f09b9f2 --- /dev/null +++ b/test/make_local_shared_array_esft_test.cpp @@ -0,0 +1,57 @@ +/* +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 +#include +#include + +class type + : public boost::enable_shared_from_this { +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 result = + boost::make_local_shared(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 result = + boost::make_local_shared_noinit(); + try { + result[0].shared_from_this(); + BOOST_ERROR("shared_from_this did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 3); + } + } + return boost::report_errors(); +} diff --git a/test/make_local_shared_array_noinit_test.cpp b/test/make_local_shared_array_noinit_test.cpp new file mode 100644 index 0000000..a6b9dd5 --- /dev/null +++ b/test/make_local_shared_array_noinit_test.cpp @@ -0,0 +1,207 @@ +/* +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 +#include +#include +#include +#include + +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 result = + boost::make_local_shared_noinit(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared_noinit(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + boost::weak_ptr other = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/make_local_shared_array_test.cpp b/test/make_local_shared_array_test.cpp new file mode 100644 index 0000000..fbd9e89 --- /dev/null +++ b/test/make_local_shared_array_test.cpp @@ -0,0 +1,229 @@ +/* +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 +#include +#include +#include +#include + +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 result = + boost::make_local_shared(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::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 result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::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 result = + boost::make_local_shared(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(result[0] == 0); + BOOST_TEST(result[1] == 0); + BOOST_TEST(result[2] == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::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 result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::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 result = + boost::make_local_shared(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + boost::weak_ptr w1 = result; + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(3); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 3); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(2); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + { + boost::local_shared_ptr result = + boost::make_local_shared(); + BOOST_TEST(result.get() != 0); + BOOST_TEST(result.local_use_count() == 1); + BOOST_TEST(boost::alignment::is_aligned(result.get(), + boost::alignment_of::value)); + BOOST_TEST(type::instances == 4); + result.reset(); + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/make_local_shared_array_throws_test.cpp b/test/make_local_shared_array_throws_test.cpp new file mode 100644 index 0000000..2d4781b --- /dev/null +++ b/test/make_local_shared_array_throws_test.cpp @@ -0,0 +1,84 @@ +/* +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 +#include + +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(6); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared(3); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared(); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared(); + BOOST_ERROR("make_local_shared did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit(6); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit(3); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit(); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + try { + boost::make_local_shared_noinit(); + BOOST_ERROR("make_local_shared_noinit did not throw"); + } catch (...) { + BOOST_TEST(type::instances == 0); + } + return boost::report_errors(); +} diff --git a/test/make_local_shared_array_value_test.cpp b/test/make_local_shared_array_value_test.cpp new file mode 100644 index 0000000..9f4b0e0 --- /dev/null +++ b/test/make_local_shared_array_value_test.cpp @@ -0,0 +1,46 @@ +/* +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 +#include + +int main() +{ + { + boost::local_shared_ptr result = + boost::make_local_shared(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 result = + boost::make_local_shared(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 result = + boost::make_local_shared(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 result = + boost::make_local_shared(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(); +} diff --git a/test/make_local_shared_arrays_test.cpp b/test/make_local_shared_arrays_test.cpp new file mode 100644 index 0000000..239a016 --- /dev/null +++ b/test/make_local_shared_arrays_test.cpp @@ -0,0 +1,53 @@ +/* +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 +#include + +#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +int main() +{ + { + boost::local_shared_ptr result = + boost::make_local_shared(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 result = + boost::make_local_shared({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 result = + boost::make_local_shared(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 result = + boost::make_local_shared({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