diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1814bd8..528fe06 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -84,6 +84,7 @@ import testing ; [ 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 ] diff --git a/test/shared_ptr_alloc_construct11_test.cpp b/test/shared_ptr_alloc_construct11_test.cpp new file mode 100644 index 0000000..436f828 --- /dev/null +++ b/test/shared_ptr_alloc_construct11_test.cpp @@ -0,0 +1,128 @@ +/* +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 counters { + unsigned allocate; + unsigned construct; +}; + +template +class creator { +public: + typedef T value_type; + + creator(counters* state) + : state_(state) { } + + template + creator(const creator& other) + : state_(other.state()) { } + + T* allocate(std::size_t size) { + void* ptr = ::operator new(sizeof(T) * size); + ++state_->allocate; + return static_cast(ptr); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + --state_->allocate; + } + + template + void construct(T* ptr, Args&&... args) { + ::new(static_cast(ptr)) T(std::forward(args)...); + ++state_->construct; + } + + void destroy(T* ptr) { + ptr->~T(); + --state_->construct; + } + + counters* state() const { + return state_; + } + +private: + counters* state_; +}; + +template +inline bool +operator==(const creator& lhs, const creator& rhs) +{ + return lhs.state() == rhs.state(); +} + +template +inline bool +operator!=(const creator& lhs, const creator& rhs) +{ + return !(lhs == rhs); +} + +struct deleter { + template + void operator()(U ptr) const { + delete ptr; + } +}; + +int main() +{ + { + counters state = { }; + boost::shared_ptr pointer(new int(), deleter(), + creator(&state)); + BOOST_TEST(state.allocate == 1); + BOOST_TEST(state.construct == 0); + pointer.reset(); + BOOST_TEST(state.allocate == 0); + } + { + counters state = { }; + boost::shared_ptr pointer = + boost::allocate_shared(creator(&state)); + BOOST_TEST(state.allocate == 1); + BOOST_TEST(state.construct == 1); + pointer.reset(); + BOOST_TEST(state.allocate == 0); + BOOST_TEST(state.construct == 0); + } + { + counters state = { }; + boost::shared_ptr pointer = + boost::allocate_shared(creator(&state), 5); + BOOST_TEST(state.allocate == 1); + BOOST_TEST(state.construct == 5); + pointer.reset(); + BOOST_TEST(state.allocate == 0); + BOOST_TEST(state.construct == 0); + } + { + counters state = { }; + boost::shared_ptr pointer = + boost::allocate_shared(creator(&state)); + BOOST_TEST(state.allocate == 1); + BOOST_TEST(state.construct == 5); + pointer.reset(); + BOOST_TEST(state.allocate == 0); + BOOST_TEST(state.construct == 0); + } + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif