| 1 | #ifndef BOOST_CORE_MEMORY_RESOURCE_HPP_INCLUDED |
| 2 | #define BOOST_CORE_MEMORY_RESOURCE_HPP_INCLUDED |
| 3 | |
| 4 | // MS compatible compilers support #pragma once |
| 5 | |
| 6 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| 7 | # pragma once |
| 8 | #endif |
| 9 | |
| 10 | // Copyright 2023 Peter Dimov |
| 11 | // Distributed under the Boost Software License, Version 1.0. |
| 12 | // https://www.boost.org/LICENSE_1_0.txt |
| 13 | |
| 14 | #include <boost/core/max_align.hpp> |
| 15 | #include <boost/config.hpp> |
| 16 | #include <boost/config/workaround.hpp> |
| 17 | #include <cstddef> |
| 18 | |
| 19 | // Define our own placement new to avoid the inclusion of <new> |
| 20 | // (~9K extra lines) at Ion Gaztanhaga's request. |
| 21 | // |
| 22 | // We can use our own because [intro.object] p13 says: |
| 23 | // |
| 24 | // Any implicit or explicit invocation of a function named `operator new` |
| 25 | // or `operator new[]` implicitly creates objects in the returned region of |
| 26 | // storage and returns a pointer to a suitable created object. |
| 27 | |
| 28 | namespace boost |
| 29 | { |
| 30 | namespace core |
| 31 | { |
| 32 | namespace detail |
| 33 | { |
| 34 | |
| 35 | struct placement_new_tag {}; |
| 36 | |
| 37 | } // namespace detail |
| 38 | } // namespace core |
| 39 | } // namespace boost |
| 40 | |
| 41 | inline void* operator new( std::size_t, void* p, boost::core::detail::placement_new_tag ) |
| 42 | { |
| 43 | return p; |
| 44 | } |
| 45 | |
| 46 | inline void operator delete( void*, void*, boost::core::detail::placement_new_tag ) |
| 47 | { |
| 48 | } |
| 49 | |
| 50 | namespace boost |
| 51 | { |
| 52 | namespace core |
| 53 | { |
| 54 | |
| 55 | class memory_resource |
| 56 | { |
| 57 | public: |
| 58 | |
| 59 | #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || BOOST_WORKAROUND(BOOST_GCC, < 40700) |
| 60 | |
| 61 | virtual ~memory_resource() {} |
| 62 | |
| 63 | #else |
| 64 | |
| 65 | virtual ~memory_resource() = default; |
| 66 | |
| 67 | #endif |
| 68 | |
| 69 | BOOST_ATTRIBUTE_NODISCARD void* allocate( std::size_t bytes, std::size_t alignment = max_align ) |
| 70 | { |
| 71 | // https://github.com/boostorg/container/issues/199 |
| 72 | // https://cplusplus.github.io/LWG/issue3471 |
| 73 | |
| 74 | return ::operator new( bytes, p: do_allocate( bytes, alignment ), core::detail::placement_new_tag() ); |
| 75 | } |
| 76 | |
| 77 | void deallocate( void* p, std::size_t bytes, std::size_t alignment = max_align ) |
| 78 | { |
| 79 | do_deallocate( p, bytes, alignment ); |
| 80 | } |
| 81 | |
| 82 | bool is_equal( memory_resource const & other ) const BOOST_NOEXCEPT |
| 83 | { |
| 84 | return do_is_equal( other ); |
| 85 | } |
| 86 | |
| 87 | private: |
| 88 | |
| 89 | virtual void* do_allocate( std::size_t bytes, std::size_t alignment ) = 0; |
| 90 | virtual void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) = 0; |
| 91 | |
| 92 | virtual bool do_is_equal( memory_resource const & other ) const BOOST_NOEXCEPT = 0; |
| 93 | }; |
| 94 | |
| 95 | inline bool operator==( memory_resource const& a, memory_resource const& b ) BOOST_NOEXCEPT |
| 96 | { |
| 97 | return &a == &b || a.is_equal( other: b ); |
| 98 | } |
| 99 | |
| 100 | inline bool operator!=( memory_resource const& a, memory_resource const& b ) BOOST_NOEXCEPT |
| 101 | { |
| 102 | return !( a == b ); |
| 103 | } |
| 104 | |
| 105 | } // namespace core |
| 106 | } // namespace boost |
| 107 | |
| 108 | #endif // #ifndef BOOST_CORE_MEMORY_RESOURCE_HPP_INCLUDED |
| 109 | |