= typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
/// @endcond
+#if __cplusplus > 202002L
+# define _GLIBCXX_NO_ALLOC_TRAITS_SPECIALIZATIONS _GLIBCXX_NO_SPECIALIZATIONS
+#else
+# define _GLIBCXX_NO_ALLOC_TRAITS_SPECIALIZATIONS
+#endif
+
/**
* @brief Uniform interface to all allocator types.
* @headerfile memory
* @since C++11
*/
template<typename _Alloc>
- struct allocator_traits : __allocator_traits_base
+ struct _GLIBCXX_NO_ALLOC_TRAITS_SPECIALIZATIONS allocator_traits
+ : __allocator_traits_base
{
/// The allocator type
typedef _Alloc allocator_type;
};
#pragma GCC diagnostic pop
+#undef _GLIBCXX_NO_ALLOC_TRAITS_SPECIALIZATIONS
+
#if _GLIBCXX_HOSTED
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-specialization"
+
/**
* @brief Partial specialization for `std::allocator`
* @headerfile memory
select_on_container_copy_construction(const allocator_type& __rhs)
{ return __rhs; }
};
+#pragma GCC diagnostic pop
#endif // _GLIBCXX_HOSTED
/// @cond undocumented
template<typename _Alloc> struct allocator_traits;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winvalid-specialization"
+
/// Partial specialization for `std::pmr::polymorphic_allocator`
/**
* @ingroup pmr
max_size(const allocator_type&) noexcept
{ return size_t(-1) / sizeof(value_type); }
};
+#pragma GCC diagnostic pop
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
--- /dev/null
+// { dg-do compile { target c++11 } }
+
+#include <memory>
+
+template<typename T> struct Alloc : std::allocator<T>
+{
+ template<typename U>
+ struct rebind { using other = Alloc<U>; };
+};
+
+template<typename T>
+struct std::allocator_traits<Alloc<T>> // { dg-error "cannot be specialized" "" { target c++23 } }
+{};
+
+template<>
+struct std::allocator_traits<Alloc<void>> // { dg-error "cannot be specialized" "" { target c++23 } }
+{};
+
+// { dg-bogus "cannot be specialized" "" { target c++20_down } 0 }