// Copyright 2018 Hans Dembinski // // 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 BOOST_HISTOGRAM_TEST_UTILITY_ALLOCATOR_HPP #define BOOST_HISTOGRAM_TEST_UTILITY_ALLOCATOR_HPP #include #include #include #include #include namespace boost { namespace histogram { struct tracing_allocator_db : std::unordered_map> { template std::pair& at() { return this->operator[](&BOOST_CORE_TYPEID(T)); } std::pair sum; }; template struct tracing_allocator { using value_type = T; tracing_allocator_db* db = nullptr; tracing_allocator() noexcept {} tracing_allocator(tracing_allocator_db& x) noexcept : db(&x) {} template tracing_allocator(const tracing_allocator& a) noexcept : db(a.db) {} template tracing_allocator& operator=(const tracing_allocator& a) noexcept { db = a.db; return *this; } ~tracing_allocator() noexcept {} T* allocate(std::size_t n) { if (db) { db->at().first += n; db->sum.first += n; } return static_cast(::operator new(n * sizeof(T))); } void deallocate(T* p, std::size_t n) { if (db) { db->at().second += n; db->sum.second += n; } ::operator delete((void*)p); } }; template constexpr bool operator==(const tracing_allocator&, const tracing_allocator&) noexcept { return true; } template constexpr bool operator!=(const tracing_allocator& t, const tracing_allocator& u) noexcept { return !operator==(t, u); } } // namespace histogram } // namespace boost #endif