// // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) // // 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) // #ifndef BEAST_TEST_TEST_ALLOCATOR_HPP #define BEAST_TEST_TEST_ALLOCATOR_HPP #include #include #include namespace beast { namespace test { struct test_allocator_info { std::size_t id; std::size_t ncopy = 0; std::size_t nmove = 0; std::size_t nmassign = 0; std::size_t ncpassign = 0; std::size_t nselect = 0; test_allocator_info() : id([] { static std::atomic sid(0); return ++sid; }()) { } }; template class test_allocator; template struct test_allocator_base { }; template struct test_allocator_base { static test_allocator select_on_container_copy_construction(test_allocator< T, Equal, Assign, Move, Swap, true> const& a) { return test_allocator{}; } }; template class test_allocator : public test_allocator_base< T, Equal, Assign, Move, Swap, Select> { std::shared_ptr info_; template friend class test_allocator; public: using value_type = T; using propagate_on_container_copy_assignment = std::integral_constant; using propagate_on_container_move_assignment = std::integral_constant; using propagate_on_container_swap = std::integral_constant; template struct rebind { using other = test_allocator; }; test_allocator() : info_(std::make_shared()) { } test_allocator(test_allocator const& u) noexcept : info_(u.info_) { ++info_->ncopy; } template test_allocator(test_allocator const& u) noexcept : info_(u.info_) { ++info_->ncopy; } test_allocator(test_allocator&& t) : info_(t.info_) { ++info_->nmove; } test_allocator& operator=(test_allocator const& u) noexcept { info_ = u.info_; ++info_->ncpassign; return *this; } test_allocator& operator=(test_allocator&& u) noexcept { info_ = u.info_; ++info_->nmassign; return *this; } value_type* allocate(std::size_t n) { return static_cast( ::operator new (n*sizeof(value_type))); } void deallocate(value_type* p, std::size_t) noexcept { ::operator delete(p); } bool operator==(test_allocator const& other) const { return id() == other.id() || Equal; } bool operator!=(test_allocator const& other) const { return ! this->operator==(other); } std::size_t id() const { return info_->id; } test_allocator_info const* operator->() const { return info_.get(); } }; } // test } // beast #endif