From 8d585ba878a06092776de614056d930e6ba99de8 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Tue, 19 Mar 2024 22:00:58 +0900 Subject: [PATCH 01/13] Resolve committee comments --- proxy.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/proxy.h b/proxy.h index 3186883..4306804 100644 --- a/proxy.h +++ b/proxy.h @@ -636,32 +636,84 @@ class sbo_ptr { mutable T value_; }; -template +template class deep_ptr { + struct storage { + template + explicit storage(const Alloc& alloc, Args&&... args) + : value(std::forward(args)...), alloc(alloc) {} + + T value; + [[no_unique_address]] Alloc alloc; + }; + using ReboundAlloc = typename std::allocator_traits + ::template rebind_alloc; + public: template - deep_ptr(Args&&... args) requires(std::is_constructible_v) - : ptr_(new T(std::forward(args)...)) {} + deep_ptr(const Alloc& alloc, Args&&... args) + requires(std::is_constructible_v) + : ptr_(allocate(alloc, std::forward(args)...)) {} deep_ptr(const deep_ptr& rhs) requires(std::is_copy_constructible_v) - : ptr_(rhs.ptr_ == nullptr ? nullptr : new T(*rhs.ptr_)) {} - deep_ptr(deep_ptr&& rhs) noexcept : ptr_(rhs.ptr_) { rhs.ptr_ = nullptr; } - ~deep_ptr() noexcept { delete ptr_; } + : ptr_(rhs.ptr_ == nullptr ? nullptr : + allocate(rhs.ptr_->alloc, std::as_const(rhs.ptr_->value))) {} + deep_ptr(deep_ptr&& rhs) noexcept : ptr_(std::exchange(rhs.ptr_, nullptr)) {} + ~deep_ptr() noexcept { + if (ptr_ != nullptr) { + ReboundAlloc al(ptr_->alloc); + ptr_->~storage(); + al.deallocate(ptr_, 1); + } + } - T* operator->() const noexcept { return ptr_; } + T* operator->() const noexcept { return &ptr_->value; } private: - T* ptr_; + template + static storage* allocate(const Alloc& alloc, Args&&... args) { + ReboundAlloc al(alloc); + auto deleter = [&](storage* ptr) { al.deallocate(ptr, 1); }; + std::unique_ptr result{al.allocate(1), deleter}; + new(result.get()) storage(alloc, std::forward(args)...); + return result.release(); + } + + storage* ptr_; }; +template +proxy allocate_proxy_impl(const Alloc& alloc, Args&&... args) { + if constexpr (proxiable, F>) { + return proxy{std::in_place_type>, + std::forward(args)...}; + } else { + return proxy{std::in_place_type>, + alloc, std::forward(args)...}; + } +} template proxy make_proxy_impl(Args&&... args) { - return proxy{std::in_place_type< - std::conditional_t, F>, sbo_ptr, deep_ptr>>, - std::forward(args)...}; + return allocate_proxy_impl( + std::allocator{}, std::forward(args)...); } } // namespace details +template +proxy allocate_proxy(const Alloc& alloc, Args&&... args) { + return details::allocate_proxy_impl(alloc, std::forward(args)...); +} +template +proxy allocate_proxy(const Alloc& alloc, std::initializer_list il, + Args&&... args) { + return details::allocate_proxy_impl( + alloc, il, std::forward(args)...); +} +template +proxy allocate_proxy(const Alloc& alloc, T&& value) { + return details::allocate_proxy_impl>( + alloc, std::forward(value)); +} template proxy make_proxy(Args&&... args) { return details::make_proxy_impl(std::forward(args)...); } From 121b36b57553a8561c8230ee7475ba0b8a427e92 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Wed, 20 Mar 2024 10:16:07 +0900 Subject: [PATCH 02/13] Update implementation --- proxy.h | 61 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/proxy.h b/proxy.h index 4306804..86c0f94 100644 --- a/proxy.h +++ b/proxy.h @@ -52,6 +52,23 @@ template consteval bool is_consteval(Expr) { return requires { typename std::bool_constant<(Expr{}(), false)>; }; } +template +concept tuple_like = + requires { { std::tuple_size::value } -> + std::same_as; } && + is_consteval([] { return std::tuple_size::value; }) && + [](std::index_sequence) { + return (requires { typename std::tuple_element_t; } && ...); + }(std::make_index_sequence>{}); + +template