[/
  Copyright 2023 Peter Dimov
  Distributed under the Boost Software License, Version 1.0.
  https://boost.org/LICENSE_1_0.txt
]

[section:memory_resource memory_resource]

[simplesect Authors]

* Peter Dimov

[endsimplesect]

[section Header <boost/core/memory_resource.hpp>]

The header `<boost/core/memory_resource.hpp>` defines the class
`boost::core::memory_resource`, a portable equivalent of
`std::pmr::memory_resource` from C++17.

This is not a complete implementation of the standard `<memory_resource>`
header; for such, one should use Boost.Container. The abstract base class
is only provided by Core so that Boost libraries that provide and take
advantage of PMR facilities such as concrete implementations of memory
resources, or implementations of `polymorphic_allocator`, can interoperate.

[section Synopsis]

``
namespace boost
{
namespace core
{

class memory_resource
{
public:

    virtual ~memory_resource() = default;

    [[nodiscard]] void* allocate( std::size_t bytes, std::size_t alignment = max_align );
    void deallocate( void* p, std::size_t bytes, std::size_t alignment = max_align );

    bool is_equal( memory_resource const & other ) const noexcept;

private:

    virtual void* do_allocate( std::size_t bytes, std::size_t alignment ) = 0;
    virtual void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) = 0;

    virtual bool do_is_equal( memory_resource const& other ) const noexcept = 0;
};

inline bool operator==( memory_resource const& a, memory_resource const& b ) noexcept;
inline bool operator!=( memory_resource const& a, memory_resource const& b ) noexcept;

} // namespace core
} // namespace boost
``

[endsect]

[section `allocate`]

`[[nodiscard]] void* allocate( std::size_t bytes, std::size_t alignment = max_align );`

* *Returns:* `do_allocate( bytes, alignment )`.
* *Remarks:* Implicitly creates objects in the returned region of storage.

[endsect]

[section `deallocate`]

`void deallocate( void* p, std::size_t bytes, std::size_t alignment = max_align );`

* *Effects:* `do_deallocate( bytes, alignment )`.

[endsect]

[section `is_equal`]

`bool is_equal( memory_resource const& other ) const noexcept;`

* *Returns:* `do_is_equal( other )`.

[endsect]

[section `do_allocate`]

`void* do_allocate( std::size_t bytes, std::size_t alignment ) = 0;`

* *Remarks:* A derived class should implement this member function to return
  a pointer to allocated storage of size at least `bytes` and alignment at
  least `alignment`.
* *Throws:* An appropriate exception (by convention `std::bad_alloc` or
  derived) when storage with the specified size and alignment could not be
  obtained.

[endsect]

[section `do_deallocate`]

`void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) = 0;`

* *Remarks:* A derived class should implement this member function to deallocate
  a region of storage previously allocated by `do_allocate`.
* *Throws:* Nothing.

[endsect]

[section `do_is_equal`]

`bool do_is_equal( memory_resource const& other ) const noexcept = 0;`

* *Remarks:* A derived class shall implement this function to return `true` if
  memory allocated from `*this` can be deallocated from `other` and vice-versa,
  otherwise `false`.

[endsect]

[section `operator==`]

`bool operator==( memory_resource const& a, memory_resource const& b ) noexcept;`

* *Returns:* `&a == &b || a.is_equal( b )`.

[endsect]

[section `operator!=`]

`bool operator!=( memory_resource const& a, memory_resource const& b ) noexcept;`

* *Returns:* `!( a == b )`.

[endsect]

[endsect]

[endsect]
