Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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
- Loading branch information
Showing
131 changed files
with
7,447 additions
and
341 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H | ||
#define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H | ||
|
||
#include <__config> | ||
#include <cstddef> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
#if _LIBCPP_STD_VER > 14 | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
namespace pmr { | ||
|
||
// [mem.res.class] | ||
|
||
_LIBCPP_DIAGNOSTIC_PUSH | ||
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") // TODO: move destructor into the dylib | ||
class _LIBCPP_TYPE_VIS memory_resource { | ||
static const size_t __max_align = alignof(max_align_t); | ||
|
||
public: | ||
virtual ~memory_resource() = default; | ||
|
||
_LIBCPP_HIDE_FROM_ABI void* allocate(size_t __bytes, size_t __align = __max_align) { | ||
return do_allocate(__bytes, __align); | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI void deallocate(void* __p, size_t __bytes, size_t __align = __max_align) { | ||
do_deallocate(__p, __bytes, __align); | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI bool is_equal(const memory_resource& __other) const noexcept { return do_is_equal(__other); } | ||
|
||
private: | ||
virtual void* do_allocate(size_t, size_t) = 0; | ||
virtual void do_deallocate(void*, size_t, size_t) = 0; | ||
virtual bool do_is_equal(memory_resource const&) const noexcept = 0; | ||
}; | ||
_LIBCPP_DIAGNOSTIC_POP | ||
|
||
// [mem.res.eq] | ||
|
||
inline _LIBCPP_HIDE_FROM_ABI bool operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept { | ||
return &__lhs == &__rhs || __lhs.is_equal(__rhs); | ||
} | ||
|
||
inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept { | ||
return !(__lhs == __rhs); | ||
} | ||
|
||
// [mem.res.global] | ||
|
||
_LIBCPP_FUNC_VIS memory_resource* get_default_resource() noexcept; | ||
|
||
_LIBCPP_FUNC_VIS memory_resource* set_default_resource(memory_resource*) noexcept; | ||
|
||
_LIBCPP_FUNC_VIS memory_resource* new_delete_resource() noexcept; | ||
|
||
_LIBCPP_FUNC_VIS memory_resource* null_memory_resource() noexcept; | ||
|
||
} // namespace pmr | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // _LIBCPP_STD_VER > 14 | ||
|
||
#endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H |
119 changes: 119 additions & 0 deletions
119
libcxx/include/__memory_resource/monotonic_buffer_resource.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H | ||
#define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H | ||
|
||
#include <__config> | ||
#include <__memory/addressof.h> | ||
#include <__memory_resource/memory_resource.h> | ||
#include <cstddef> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
#if _LIBCPP_STD_VER > 14 | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
namespace pmr { | ||
|
||
// [mem.res.monotonic.buffer] | ||
|
||
class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource { | ||
static const size_t __default_buffer_capacity = 1024; | ||
static const size_t __default_buffer_alignment = 16; | ||
|
||
struct __chunk_footer { | ||
__chunk_footer* __next_; | ||
char* __start_; | ||
char* __cur_; | ||
size_t __align_; | ||
size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); } | ||
void* __try_allocate_from_chunk(size_t, size_t); | ||
}; | ||
|
||
struct __initial_descriptor { | ||
char* __start_; | ||
char* __cur_; | ||
union { | ||
char* __end_; | ||
size_t __size_; | ||
}; | ||
void* __try_allocate_from_chunk(size_t, size_t); | ||
}; | ||
|
||
public: | ||
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource() | ||
: monotonic_buffer_resource(nullptr, __default_buffer_capacity, get_default_resource()) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(size_t __initial_size) | ||
: monotonic_buffer_resource(nullptr, __initial_size, get_default_resource()) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size) | ||
: monotonic_buffer_resource(__buffer, __buffer_size, get_default_resource()) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI explicit monotonic_buffer_resource(memory_resource* __upstream) | ||
: monotonic_buffer_resource(nullptr, __default_buffer_capacity, __upstream) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(size_t __initial_size, memory_resource* __upstream) | ||
: monotonic_buffer_resource(nullptr, __initial_size, __upstream) {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI monotonic_buffer_resource(void* __buffer, size_t __buffer_size, memory_resource* __upstream) | ||
: __res_(__upstream) { | ||
__initial_.__start_ = static_cast<char*>(__buffer); | ||
if (__buffer != nullptr) { | ||
__initial_.__cur_ = static_cast<char*>(__buffer); | ||
__initial_.__end_ = static_cast<char*>(__buffer) + __buffer_size; | ||
} else { | ||
__initial_.__cur_ = nullptr; | ||
__initial_.__size_ = __buffer_size; | ||
} | ||
__chunks_ = nullptr; | ||
} | ||
|
||
monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; | ||
|
||
_LIBCPP_HIDE_FROM_ABI ~monotonic_buffer_resource() override { release(); } | ||
|
||
monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; | ||
|
||
_LIBCPP_HIDE_FROM_ABI void release() { | ||
__initial_.__cur_ = __initial_.__start_; | ||
while (__chunks_ != nullptr) { | ||
__chunk_footer* __next = __chunks_->__next_; | ||
__res_->deallocate(__chunks_->__start_, __chunks_->__allocation_size(), __chunks_->__align_); | ||
__chunks_ = __next; | ||
} | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI memory_resource* upstream_resource() const { return __res_; } | ||
|
||
protected: | ||
void* do_allocate(size_t __bytes, size_t __alignment) override; // key function | ||
|
||
_LIBCPP_HIDE_FROM_ABI void do_deallocate(void*, size_t, size_t) override {} | ||
|
||
_LIBCPP_HIDE_FROM_ABI bool do_is_equal(const memory_resource& __other) const _NOEXCEPT override { | ||
return this == std::addressof(__other); | ||
} | ||
|
||
private: | ||
__initial_descriptor __initial_; | ||
__chunk_footer* __chunks_; | ||
memory_resource* __res_; | ||
}; | ||
|
||
} // namespace pmr | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // _LIBCPP_STD_VER > 14 | ||
|
||
#endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H |
Oops, something went wrong.