From 633e34c1e89b882868a4b74ff14b4110662c4218 Mon Sep 17 00:00:00 2001 From: jyxiong Date: Mon, 22 Sep 2025 20:13:54 +0800 Subject: [PATCH] feat: construct_at & destroy_at --- source/tinystl/memory.h | 5 ++- source/tinystl/memory/allocator_traits.h | 57 ++++++++++++++---------- source/tinystl/memory/construct.h | 13 ++++++ source/tinystl/memory/destroy.h | 20 +++++++++ source/tinystl/type_traits.h | 5 ++- 5 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 source/tinystl/memory/construct.h create mode 100644 source/tinystl/memory/destroy.h diff --git a/source/tinystl/memory.h b/source/tinystl/memory.h index 7d02056..778d4ee 100644 --- a/source/tinystl/memory.h +++ b/source/tinystl/memory.h @@ -1,6 +1,9 @@ #pragma once +#include #include #include -#include +#include +#include #include + diff --git a/source/tinystl/memory/allocator_traits.h b/source/tinystl/memory/allocator_traits.h index 1dcf342..b4daa8e 100644 --- a/source/tinystl/memory/allocator_traits.h +++ b/source/tinystl/memory/allocator_traits.h @@ -1,13 +1,17 @@ #pragma once -#include #include +#include + +#include "tinystl/memory/construct.h" +#include "tinystl/memory/destroy.h" #include "tinystl/memory/pointer_traits.h" -#include "tinystl/type_traits/void_t.h" -#include "tinystl/type_traits/is_empty.h" #include "tinystl/type_traits/enable_if.h" +#include "tinystl/type_traits/is_empty.h" #include "tinystl/type_traits/make_unsigned.h" +#include "tinystl/type_traits/void_t.h" + // https://en.cppreference.com/w/cpp/memory/allocator_traits.html @@ -44,8 +48,7 @@ struct get_void_pointer { typename tinystl::pointer_traits::template rebind; }; template -struct get_void_pointer< - Alloc, tinystl::void_t> { +struct get_void_pointer> { using type = typename Alloc::void_pointer; }; @@ -66,24 +69,26 @@ struct get_const_void_pointer< // get_difference_type template struct get_difference_type { - using _Ptrty = typename get_pointer::type; - using type = typename tinystl::pointer_traits<_Ptrty>::difference_type; + using _Ptrty = typename get_pointer::type; + using type = typename tinystl::pointer_traits<_Ptrty>::difference_type; }; template -struct get_difference_type> { - using type = typename Alloc::difference_type; +struct get_difference_type< + Alloc, tinystl::void_t> { + using type = typename Alloc::difference_type; }; // get_size_type template struct get_size_type { - using type = tinystl::make_unsigned_t::type>; + using type = + tinystl::make_unsigned_t::type>; }; template struct get_size_type> { - using type = typename Alloc::size_type; + using type = typename Alloc::size_type; }; // propagate_on_container_copy_assignment @@ -144,7 +149,7 @@ template < template class Alloc, class First, class... Rest, class Newfirst> struct get_rebind_get_impl, Newfirst> { -// given Alloc, replace First with Newfirst + // given Alloc, replace First with Newfirst using type = Alloc; }; @@ -165,9 +170,9 @@ template const bool has_construct_impl = false; template -const bool - has_construct_impl().construct(std::declval()...)), Alloc, Args...> = - true; +const bool has_construct_impl< + decltype((void)std::declval().construct(std::declval()...)), + Alloc, Args...> = true; template const bool has_construct = has_construct_impl; @@ -177,15 +182,19 @@ template const bool has_destroy = false; template -const bool - has_destroy().destroy(std::declval()))> = true; +const bool has_destroy< + Alloc, Pointer, + decltype((void)std::declval().destroy(std::declval()))> = + true; // has_max_size template const bool has_max_size = false; template -const bool has_max_size().max_size())> = true; +const bool + has_max_size().max_size())> = + true; // has_select_on_container_copy_construction template @@ -193,8 +202,8 @@ const bool has_select_on_container_copy_construction = false; template const bool has_select_on_container_copy_construction< - Alloc, - decltype((void)std::declval().select_on_container_copy_construction())> = true; + Alloc, decltype((void)std::declval() + .select_on_container_copy_construction())> = true; } // namespace detail @@ -253,7 +262,7 @@ struct allocator_traits { class T, class... Args, enable_if_t, int> = 0> static void construct(Alloc &, T *p, Args &&...args) { - std::construct_at(p, std::forward(args)...); + construct_at(p, std::forward(args)...); } template , int> = 0> @@ -263,11 +272,13 @@ struct allocator_traits { template , int> = 0> static void destroy(Alloc &, T *p) { - std::destroy_at(p); + destroy_at(p); } template , int> = 0> - static size_type max_size(const Alloc &a) noexcept { return a.max_size(); } + static size_type max_size(const Alloc &a) noexcept { + return a.max_size(); + } template , int> = 0> static size_type max_size(const Alloc &) noexcept { diff --git a/source/tinystl/memory/construct.h b/source/tinystl/memory/construct.h new file mode 100644 index 0000000..103b59c --- /dev/null +++ b/source/tinystl/memory/construct.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace tinystl { +template < + class T, class... Args, + class = decltype(::new (std::declval()) T(std::declval()...))> +constexpr T *construct_at(T *location, Args &&...args) { + return ::new (static_cast(location)) T(std::forward(args)...); +} + +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/memory/destroy.h b/source/tinystl/memory/destroy.h new file mode 100644 index 0000000..5ec5916 --- /dev/null +++ b/source/tinystl/memory/destroy.h @@ -0,0 +1,20 @@ +#pragma once + +#include "tinystl/memory/addressof.h" +#include "tinystl/type_traits/enable_if.h" +#include "tinystl/type_traits/is_array.h" + +namespace tinystl { +template , int> = 0> +void destroy_at(T *p) { + p->~T(); +} + +template , int> = 0> +void destroy_at(T *p) { + for (auto &elem : *p) { + (destroy_at)(addressof(elem)); + } +} + +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/type_traits.h b/source/tinystl/type_traits.h index 8720b38..c16ee84 100644 --- a/source/tinystl/type_traits.h +++ b/source/tinystl/type_traits.h @@ -3,12 +3,13 @@ // https://en.cppreference.com/w/cpp/header/type_traits.html // composite_type_categories - #include #include #include +#include #include + // const_volatility_specifiers #include @@ -23,8 +24,10 @@ #include #include #include +#include #include #include +#include #include #include