Skip to content

Commit 243da90

Browse files
Quuxplusoneldionne
authored andcommitted
[libc++] Add the C++17 <memory_resource> header (mono-patch)
This patch is the rebase and squash of three earlier patches. It supersedes all three of them. - D47111: experimental monotonic_buffer_resource. - D47358: experimental pool resources. - D47360: Copy std::experimental::pmr to std::pmr. The significant difference between this patch and the-sum-of-those-three is that this patch does not add `std::experimental::pmr::monotonic_buffer_resource` and so on. This patch simply adds the C++17 standard facilities, and leaves the `std::experimental` namespace entirely alone. Differential Revision: https://reviews.llvm.org/D89057
1 parent defe7c0 commit 243da90

File tree

131 files changed

+7447
-341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+7447
-341
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Status
126126
------------------------------------------------- -----------------
127127
``__cpp_lib_math_special_functions`` *unimplemented*
128128
------------------------------------------------- -----------------
129-
``__cpp_lib_memory_resource`` *unimplemented*
129+
``__cpp_lib_memory_resource`` ``201603L``
130130
------------------------------------------------- -----------------
131131
``__cpp_lib_node_extract`` ``201606L``
132132
------------------------------------------------- -----------------

libcxx/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Improvements and New Features
4848
- Declarations of ``std::c8rtomb()`` and ``std::mbrtoc8()`` from P0482R6 are
4949
now provided when implementations in the global namespace are provided by
5050
the C library.
51+
- Implemented ``<memory_resource>`` header from C++17
5152

5253
Deprecations and Removals
5354
-------------------------

libcxx/include/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ set(files
414414
__memory/uses_allocator.h
415415
__memory/uses_allocator_construction.h
416416
__memory/voidify.h
417+
__memory_resource/memory_resource.h
418+
__memory_resource/monotonic_buffer_resource.h
419+
__memory_resource/polymorphic_allocator.h
420+
__memory_resource/pool_options.h
421+
__memory_resource/synchronized_pool_resource.h
422+
__memory_resource/unsynchronized_pool_resource.h
417423
__mutex_base
418424
__node_handle
419425
__numeric/accumulate.h
@@ -776,6 +782,7 @@ set(files
776782
map
777783
math.h
778784
memory
785+
memory_resource
779786
mutex
780787
new
781788
numbers
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
10+
#define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
11+
12+
#include <__config>
13+
#include <cstddef>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
#if _LIBCPP_STD_VER > 14
20+
21+
_LIBCPP_BEGIN_NAMESPACE_STD
22+
23+
namespace pmr {
24+
25+
// [mem.res.class]
26+
27+
_LIBCPP_DIAGNOSTIC_PUSH
28+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") // TODO: move destructor into the dylib
29+
class _LIBCPP_TYPE_VIS memory_resource {
30+
static const size_t __max_align = alignof(max_align_t);
31+
32+
public:
33+
virtual ~memory_resource() = default;
34+
35+
_LIBCPP_HIDE_FROM_ABI void* allocate(size_t __bytes, size_t __align = __max_align) {
36+
return do_allocate(__bytes, __align);
37+
}
38+
39+
_LIBCPP_HIDE_FROM_ABI void deallocate(void* __p, size_t __bytes, size_t __align = __max_align) {
40+
do_deallocate(__p, __bytes, __align);
41+
}
42+
43+
_LIBCPP_HIDE_FROM_ABI bool is_equal(const memory_resource& __other) const noexcept { return do_is_equal(__other); }
44+
45+
private:
46+
virtual void* do_allocate(size_t, size_t) = 0;
47+
virtual void do_deallocate(void*, size_t, size_t) = 0;
48+
virtual bool do_is_equal(memory_resource const&) const noexcept = 0;
49+
};
50+
_LIBCPP_DIAGNOSTIC_POP
51+
52+
// [mem.res.eq]
53+
54+
inline _LIBCPP_HIDE_FROM_ABI bool operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
55+
return &__lhs == &__rhs || __lhs.is_equal(__rhs);
56+
}
57+
58+
inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept {
59+
return !(__lhs == __rhs);
60+
}
61+
62+
// [mem.res.global]
63+
64+
_LIBCPP_FUNC_VIS memory_resource* get_default_resource() noexcept;
65+
66+
_LIBCPP_FUNC_VIS memory_resource* set_default_resource(memory_resource*) noexcept;
67+
68+
_LIBCPP_FUNC_VIS memory_resource* new_delete_resource() noexcept;
69+
70+
_LIBCPP_FUNC_VIS memory_resource* null_memory_resource() noexcept;
71+
72+
} // namespace pmr
73+
74+
_LIBCPP_END_NAMESPACE_STD
75+
76+
#endif // _LIBCPP_STD_VER > 14
77+
78+
#endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
10+
#define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H
11+
12+
#include <__config>
13+
#include <__memory/addressof.h>
14+
#include <__memory_resource/memory_resource.h>
15+
#include <cstddef>
16+
17+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18+
# pragma GCC system_header
19+
#endif
20+
21+
#if _LIBCPP_STD_VER > 14
22+
23+
_LIBCPP_BEGIN_NAMESPACE_STD
24+
25+
namespace pmr {
26+
27+
// [mem.res.monotonic.buffer]
28+
29+
class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource {
30+
static const size_t __default_buffer_capacity = 1024;
31+
static const size_t __default_buffer_alignment = 16;
32+
33+
struct __chunk_footer {
34+
__chunk_footer* __next_;
35+
char* __start_;
36+
char* __cur_;
37+
size_t __align_;
38+
size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); }
39+
void* __try_allocate_from_chunk(size_t, size_t);
40+
};
41+
42+
struct __initial_descriptor {
43+
char* __start_;
44+
char* __cur_;
45+
union {
46+
char* __end_;
47+
size_t __size_;
48+
};
49+
void* __try_allocate_from_chunk(size_t, size_t);
50+
};
51+
52+
public:
53+
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource()
54+
: monotonic_buffer_resource(nullptr, __default_buffer_capacity, get_default_resource()) {}
55+
56+
_LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(size_t __initial_size)
57+
: monotonic_buffer_resource(nullptr, __initial_size, get_default_resource()) {}
58+
59+
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size)
60+
: monotonic_buffer_resource(__buffer, __buffer_size, get_default_resource()) {}
61+
62+
_LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(memory_resource* __upstream)
63+
: monotonic_buffer_resource(nullptr, __default_buffer_capacity, __upstream) {}
64+
65+
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(size_t __initial_size, memory_resource* __upstream)
66+
: monotonic_buffer_resource(nullptr, __initial_size, __upstream) {}
67+
68+
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size, memory_resource* __upstream)
69+
: __res_(__upstream) {
70+
__initial_.__start_ = static_cast<char*>(__buffer);
71+
if (__buffer != nullptr) {
72+
__initial_.__cur_ = static_cast<char*>(__buffer);
73+
__initial_.__end_ = static_cast<char*>(__buffer) + __buffer_size;
74+
} else {
75+
__initial_.__cur_ = nullptr;
76+
__initial_.__size_ = __buffer_size;
77+
}
78+
__chunks_ = nullptr;
79+
}
80+
81+
monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
82+
83+
_LIBCPP_HIDE_FROM_ABI ~monotonic_buffer_resource() override { release(); }
84+
85+
monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete;
86+
87+
_LIBCPP_HIDE_FROM_ABI void release() {
88+
__initial_.__cur_ = __initial_.__start_;
89+
while (__chunks_ != nullptr) {
90+
__chunk_footer* __next = __chunks_->__next_;
91+
__res_->deallocate(__chunks_->__start_, __chunks_->__allocation_size(), __chunks_->__align_);
92+
__chunks_ = __next;
93+
}
94+
}
95+
96+
_LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; }
97+
98+
protected:
99+
void* do_allocate(size_t __bytes, size_t __alignment) override; // key function
100+
101+
_LIBCPP_HIDE_FROM_ABI void do_deallocate(void*, size_t, size_t) override {}
102+
103+
_LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override {
104+
return this == std::addressof(__other);
105+
}
106+
107+
private:
108+
__initial_descriptor __initial_;
109+
__chunk_footer* __chunks_;
110+
memory_resource* __res_;
111+
};
112+
113+
} // namespace pmr
114+
115+
_LIBCPP_END_NAMESPACE_STD
116+
117+
#endif // _LIBCPP_STD_VER > 14
118+
119+
#endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H

0 commit comments

Comments
 (0)