1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/capy
7  
// Official repository: https://github.com/cppalliance/capy
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_CAPY_DETAIL_FRAME_MEMORY_RESOURCE_HPP
10  
#ifndef BOOST_CAPY_DETAIL_FRAME_MEMORY_RESOURCE_HPP
11  
#define BOOST_CAPY_DETAIL_FRAME_MEMORY_RESOURCE_HPP
11  
#define BOOST_CAPY_DETAIL_FRAME_MEMORY_RESOURCE_HPP
12  

12  

13  
#include <boost/capy/detail/config.hpp>
13  
#include <boost/capy/detail/config.hpp>
14  

14  

15  
#include <cstddef>
15  
#include <cstddef>
16  
#include <memory>
16  
#include <memory>
17  
#include <memory_resource>
17  
#include <memory_resource>
18  
#include <type_traits>
18  
#include <type_traits>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace capy {
21  
namespace capy {
22  
namespace detail {
22  
namespace detail {
23  

23  

24  
/** Wrapper that adapts a standard Allocator to memory_resource.
24  
/** Wrapper that adapts a standard Allocator to memory_resource.
25  

25  

26  
    This wrapper is used to store value-type allocators in the
26  
    This wrapper is used to store value-type allocators in the
27  
    execution context or trampoline frame. It rebinds the allocator
27  
    execution context or trampoline frame. It rebinds the allocator
28  
    to std::byte for raw memory allocation.
28  
    to std::byte for raw memory allocation.
29  

29  

30  
    @tparam Alloc The standard allocator type.
30  
    @tparam Alloc The standard allocator type.
31  
*/
31  
*/
32  
template<class Alloc>
32  
template<class Alloc>
33  
class frame_memory_resource : public std::pmr::memory_resource
33  
class frame_memory_resource : public std::pmr::memory_resource
34  
{
34  
{
35  
    using traits = std::allocator_traits<Alloc>;
35  
    using traits = std::allocator_traits<Alloc>;
36  
    using byte_alloc = typename traits::template rebind_alloc<std::byte>;
36  
    using byte_alloc = typename traits::template rebind_alloc<std::byte>;
37  
    using byte_traits = std::allocator_traits<byte_alloc>;
37  
    using byte_traits = std::allocator_traits<byte_alloc>;
38  

38  

39  
    static_assert(
39  
    static_assert(
40  
        requires { typename traits::value_type; },
40  
        requires { typename traits::value_type; },
41  
        "Alloc must satisfy allocator requirements");
41  
        "Alloc must satisfy allocator requirements");
42  

42  

43  
    static_assert(
43  
    static_assert(
44  
        std::is_copy_constructible_v<Alloc>,
44  
        std::is_copy_constructible_v<Alloc>,
45  
        "Alloc must be copy constructible");
45  
        "Alloc must be copy constructible");
46  

46  

47  
    byte_alloc alloc_;
47  
    byte_alloc alloc_;
48  

48  

49  
public:
49  
public:
50  
    /** Construct from an allocator.
50  
    /** Construct from an allocator.
51  

51  

52  
        The allocator is rebind-copied to std::byte.
52  
        The allocator is rebind-copied to std::byte.
53  

53  

54  
        @param a The allocator to adapt.
54  
        @param a The allocator to adapt.
55  
    */
55  
    */
56  
    explicit
56  
    explicit
57  
    frame_memory_resource(Alloc const& a)
57  
    frame_memory_resource(Alloc const& a)
58  
        : alloc_(a)
58  
        : alloc_(a)
59  
    {
59  
    {
60  
    }
60  
    }
61  

61  

62  
    /** Get the memory resource pointer.
62  
    /** Get the memory resource pointer.
63  

63  

64  
        @return Pointer to this memory resource.
64  
        @return Pointer to this memory resource.
65  
    */
65  
    */
66  
    std::pmr::memory_resource* get() noexcept { return this; }
66  
    std::pmr::memory_resource* get() noexcept { return this; }
67  

67  

68  
protected:
68  
protected:
69  
    void*
69  
    void*
70  
    do_allocate(std::size_t bytes, std::size_t) override
70  
    do_allocate(std::size_t bytes, std::size_t) override
71  
    {
71  
    {
72  
        return byte_traits::allocate(alloc_, bytes);
72  
        return byte_traits::allocate(alloc_, bytes);
73  
    }
73  
    }
74  

74  

75  
    void
75  
    void
76  
    do_deallocate(void* p, std::size_t bytes, std::size_t) override
76  
    do_deallocate(void* p, std::size_t bytes, std::size_t) override
77  
    {
77  
    {
78  
        byte_traits::deallocate(alloc_, static_cast<std::byte*>(p), bytes);
78  
        byte_traits::deallocate(alloc_, static_cast<std::byte*>(p), bytes);
79  
    }
79  
    }
80  

80  

81  
    bool
81  
    bool
82  
    do_is_equal(const memory_resource& other) const noexcept override
82  
    do_is_equal(const memory_resource& other) const noexcept override
83  
    {
83  
    {
84  
        return this == &other;
84  
        return this == &other;
85  
    }
85  
    }
86  
};
86  
};
87  

87  

88  
} // namespace detail
88  
} // namespace detail
89  
} // namespace capy
89  
} // namespace capy
90  
} // namespace boost
90  
} // namespace boost
91  

91  

92  
#endif
92  
#endif