aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/include/bits/alloc_traits.h104
-rw-r--r--libstdc++-v3/include/bits/allocator.h38
-rw-r--r--libstdc++-v3/include/ext/extptr_allocator.h5
3 files changed, 120 insertions, 27 deletions
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index 3441258..05b584f 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -559,6 +559,110 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __rhs; }
};
+ /// Explicit specialization for std::allocator<void>.
+ template<>
+ struct allocator_traits<allocator<void>>
+ {
+ /// The allocator type
+ using allocator_type = allocator<void>;
+
+ /// The allocated type
+ using value_type = void;
+
+ /// The allocator's pointer type.
+ using pointer = void*;
+
+ /// The allocator's const pointer type.
+ using const_pointer = const void*;
+
+ /// The allocator's void pointer type.
+ using void_pointer = void*;
+
+ /// The allocator's const void pointer type.
+ using const_void_pointer = const void*;
+
+ /// The allocator's difference type
+ using difference_type = std::ptrdiff_t;
+
+ /// The allocator's size type
+ using size_type = std::size_t;
+
+ /// How the allocator is propagated on copy assignment
+ using propagate_on_container_copy_assignment = false_type;
+
+ /// How the allocator is propagated on move assignment
+ using propagate_on_container_move_assignment = true_type;
+
+ /// How the allocator is propagated on swap
+ using propagate_on_container_swap = false_type;
+
+ /// Whether all instances of the allocator type compare equal.
+ using is_always_equal = true_type;
+
+ template<typename _Up>
+ using rebind_alloc = allocator<_Up>;
+
+ template<typename _Up>
+ using rebind_traits = allocator_traits<allocator<_Up>>;
+
+ /// allocate is ill-formed for allocator<void>
+ static void*
+ allocate(allocator_type&, size_type, const void* = nullptr) = delete;
+
+ /// deallocate is ill-formed for allocator<void>
+ static void
+ deallocate(allocator_type&, void*, size_type) = delete;
+
+ /**
+ * @brief Construct an object of type `_Up`
+ * @param __a An allocator.
+ * @param __p Pointer to memory of suitable size and alignment for
+ * an object of type `_Up`.
+ * @param __args Constructor arguments.
+ *
+ * Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
+ * in C++11, C++14 and C++17. Changed in C++20 to call
+ * `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
+ */
+ template<typename _Up, typename... _Args>
+ static _GLIBCXX20_CONSTEXPR void
+ construct(allocator_type&, _Up* __p, _Args&&... __args)
+ noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
+ {
+#if __cplusplus <= 201703L
+ ::new((void *)__p) _Up(std::forward<_Args>(__args)...);
+#else
+ std::construct_at(__p, std::forward<_Args>(__args)...);
+#endif
+ }
+
+ /**
+ * @brief Destroy an object of type `_Up`
+ * @param __a An allocator.
+ * @param __p Pointer to the object to destroy
+ *
+ * Invokes the destructor for `*__p`.
+ */
+ template<typename _Up>
+ static _GLIBCXX20_CONSTEXPR void
+ destroy(allocator_type&, _Up* __p)
+ noexcept(is_nothrow_destructible<_Up>::value)
+ { std::_Destroy(__p); }
+
+ /// max_size is ill-formed for allocator<void>
+ static size_type
+ max_size(const allocator_type&) = delete;
+
+ /**
+ * @brief Obtain an allocator to use when copying a container.
+ * @param __rhs An allocator.
+ * @return `__rhs`
+ */
+ static _GLIBCXX20_CONSTEXPR allocator_type
+ select_on_container_copy_construction(const allocator_type& __rhs)
+ { return __rhs; }
+ };
+
#if __cplusplus < 201703L
template<typename _Alloc>
inline void
diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h
index 396872f..a6883c6 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -61,12 +61,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
// Since C++20 the primary template should be used for allocator<void>,
- // but then it would have a non-trivial default ctor and dtor, which
- // would be an ABI change. So C++20 still uses the allocator<void> explicit
- // specialization, with the historical ABI properties, but with the same
- // members that are present in the primary template.
+ // but then it would have a non-trivial default ctor and dtor for C++20,
+ // but trivial for C++98-17, which would be an ABI incompatibiliy between
+ // different standard dialects. So C++20 still uses the allocator<void>
+ // explicit specialization, with the historical ABI properties, but with
+ // the same members that are present in the primary template.
-#if ! _GLIBCXX_INLINE_VERSION
/// allocator<void> specialization.
template<>
class allocator<void>
@@ -77,7 +77,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
- // These were removed for C++20.
+ // These were removed for C++20, allocator_traits does the right thing.
typedef void* pointer;
typedef const void* const_pointer;
@@ -96,7 +96,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= true_type;
#if __cplusplus >= 202002L
+ // As noted above, these members are present for C++20 to provide the
+ // same API as the primary template, but still trivial as in pre-C++20.
allocator() = default;
+ ~allocator() = default;
template<typename _Up>
constexpr
@@ -105,28 +108,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// No allocate member because it's ill-formed by LWG 3307.
// No deallocate member because it would be undefined to call it
// with any pointer which wasn't obtained from allocate.
-
-#else // ! C++20
- private:
- // This uses construct and destroy in C++11/14/17 modes.
- friend allocator_traits<allocator<void>>;
-
- template<typename _Up, typename... _Args>
- void
- construct(_Up* __p, _Args&&... __args)
- noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
- { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
-
- template<typename _Up>
- void
- destroy(_Up* __p)
- noexcept(std::is_nothrow_destructible<_Up>::value)
- { __p->~_Up(); }
-#endif // C++17
+#endif // C++20
#endif // C++11
-
};
-#endif // ! _GLIBCXX_INLINE_VERSION
/**
* @brief The @a standard allocator, as per C++03 [20.4.1].
@@ -212,7 +196,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return;
}
#endif
- __allocator_base<_Tp>::deallocate(__p, __n);
+ __allocator_base<_Tp>::deallocate(__p, __n);
}
#endif // C++20
diff --git a/libstdc++-v3/include/ext/extptr_allocator.h b/libstdc++-v3/include/ext/extptr_allocator.h
index 7d8aaac..2dfc73e 100644
--- a/libstdc++-v3/include/ext/extptr_allocator.h
+++ b/libstdc++-v3/include/ext/extptr_allocator.h
@@ -176,6 +176,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
const_pointer;
+ _ExtPtr_allocator() { }
+
+ template<typename _Up>
+ _ExtPtr_allocator(const _ExtPtr_allocator<_Up>&) { }
+
template<typename _Up>
struct rebind
{ typedef _ExtPtr_allocator<_Up> other; };