Skip to content

[libc++] P3247R2: Deprecate is_trivial(_v) #130573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libcxx/docs/ReleaseNotes/21.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Implemented Papers
- P2562R1: ``constexpr`` Stable Sorting (`Github <https://github.com/llvm/llvm-project/issues/105360>`__)
- P0472R3: Put std::monostate in <utility> (`Github <https://github.com/llvm/llvm-project/issues/127874>`__)
- P1222R4: A Standard ``flat_set`` (`Github <https://github.com/llvm/llvm-project/issues/105193>`__)
- P3247R2: Deprecate the notion of trivial types (`Github <https://github.com/llvm/llvm-project/issues/118387>`__)

Improvements and New Features
-----------------------------
Expand All @@ -65,6 +66,8 @@ Deprecations and Removals

- ``std::is_pod`` and ``std::is_pod_v`` are deprecated in C++20 and later.

- ``std::is_trivial`` and ``std::is_trivial_v`` are deprecated in C++26 and later.

Upcoming Deprecations and Removals
----------------------------------

Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cPapers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"`P1928R15 <https://wg21.link/P1928R15>`__","``std::simd`` — merge data-parallel types from the Parallelism TS 2","2024-11 (Wrocław)","","",""
"`P3325R5 <https://wg21.link/P3325R5>`__","A Utility for Creating Execution Environments","2024-11 (Wrocław)","","",""
"`P3068R6 <https://wg21.link/P3068R6>`__","Allowing exception throwing in constant-evaluation","2024-11 (Wrocław)","","",""
"`P3247R2 <https://wg21.link/P3247R2>`__","Deprecate the notion of trivial types","2024-11 (Wrocław)","","",""
"`P3247R2 <https://wg21.link/P3247R2>`__","Deprecate the notion of trivial types","2024-11 (Wrocław)","|Complete|","21",""
"","","","","",""
"`P3074R7 <https://wg21.link/P3074R7>`__","trivial unions (was ``std::uninitialized``)","2025-02 (Hagenberg)","","",""
"`P1494R5 <https://wg21.link/P1494R5>`__","Partial program correctness","2025-02 (Hagenberg)","","",""
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -750,8 +750,10 @@ typedef __char32_t char32_t;

# if _LIBCPP_STD_VER >= 26
# define _LIBCPP_DEPRECATED_IN_CXX26 _LIBCPP_DEPRECATED
# define _LIBCPP_DEPRECATED_IN_CXX26_(m) _LIBCPP_DEPRECATED_(m)
# else
# define _LIBCPP_DEPRECATED_IN_CXX26
# define _LIBCPP_DEPRECATED_IN_CXX26_(m)
# endif

# if _LIBCPP_HAS_CHAR8_T
Expand Down
6 changes: 4 additions & 2 deletions libcxx/include/__iterator/aliasing_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
#include <__memory/pointer_traits.h>
#include <__type_traits/is_trivial.h>
#include <__type_traits/is_trivially_constructible.h>
#include <__type_traits/is_trivially_copyable.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand Down Expand Up @@ -45,7 +46,8 @@ struct __aliasing_iterator_wrapper {
using reference = value_type&;
using pointer = value_type*;

static_assert(is_trivial<value_type>::value);
static_assert(is_trivially_default_constructible<value_type>::value);
static_assert(is_trivially_copyable<value_type>::value);
static_assert(sizeof(__base_value_type) == sizeof(value_type));

_LIBCPP_HIDE_FROM_ABI __iterator() = default;
Expand Down
6 changes: 4 additions & 2 deletions libcxx/include/__type_traits/is_char_like_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#include <__config>
#include <__type_traits/conjunction.h>
#include <__type_traits/is_standard_layout.h>
#include <__type_traits/is_trivial.h>
#include <__type_traits/is_trivially_constructible.h>
#include <__type_traits/is_trivially_copyable.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand All @@ -21,7 +22,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _CharT>
using _IsCharLikeType _LIBCPP_NODEBUG = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >;
using _IsCharLikeType _LIBCPP_NODEBUG =
_And<is_standard_layout<_CharT>, is_trivially_default_constructible<_CharT>, is_trivially_copyable<_CharT> >;

_LIBCPP_END_NAMESPACE_STD

Expand Down
7 changes: 5 additions & 2 deletions libcxx/include/__type_traits/is_trivial.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {
};
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX26_(
"Consider using is_trivially_copyable<T>::value && is_trivially_default_constructible<T>::value instead.")
_LIBCPP_NO_SPECIALIZATIONS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {};

#if _LIBCPP_STD_VER >= 17
template <class _Tp>
_LIBCPP_DEPRECATED_IN_CXX26_(
"Consider using is_trivially_copyable_v<T> && is_trivially_default_constructible_v<T> instead.")
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivial_v = __is_trivial(_Tp);
#endif

Expand Down
7 changes: 5 additions & 2 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,8 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
# include <__type_traits/is_nothrow_constructible.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_standard_layout.h>
# include <__type_traits/is_trivial.h>
# include <__type_traits/is_trivially_constructible.h>
# include <__type_traits/is_trivially_copyable.h>
# include <__type_traits/is_trivially_relocatable.h>
# include <__type_traits/remove_cvref.h>
# include <__type_traits/void_t.h>
Expand Down Expand Up @@ -788,7 +789,9 @@ public:

static_assert(!is_array<value_type>::value, "Character type of basic_string must not be an array");
static_assert(is_standard_layout<value_type>::value, "Character type of basic_string must be standard-layout");
static_assert(is_trivial<value_type>::value, "Character type of basic_string must be trivial");
static_assert(is_trivially_default_constructible<value_type>::value,
"Character type of basic_string must be trivially default constructible");
static_assert(is_trivially_copyable<value_type>::value, "Character type of basic_string must be trivially copyable");
static_assert(is_same<_CharT, typename traits_type::char_type>::value,
"traits_type::char_type must be the same type as CharT");
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
Expand Down
8 changes: 6 additions & 2 deletions libcxx/include/string_view
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ namespace std {
# include <__type_traits/is_convertible.h>
# include <__type_traits/is_same.h>
# include <__type_traits/is_standard_layout.h>
# include <__type_traits/is_trivial.h>
# include <__type_traits/is_trivially_constructible.h>
# include <__type_traits/is_trivially_copyable.h>
# include <__type_traits/remove_cvref.h>
# include <__type_traits/remove_reference.h>
# include <__type_traits/type_identity.h>
Expand Down Expand Up @@ -302,7 +303,10 @@ public:

static_assert(!is_array<value_type>::value, "Character type of basic_string_view must not be an array");
static_assert(is_standard_layout<value_type>::value, "Character type of basic_string_view must be standard-layout");
static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial");
static_assert(is_trivially_default_constructible<value_type>::value,
"Character type of basic_string_view must be trivially default constructible");
static_assert(is_trivially_copyable<value_type>::value,
"Character type of basic_string_view must be trivially copyable");
static_assert(is_same<_CharT, typename traits_type::char_type>::value,
"traits_type::char_type must be the same type as CharT");

Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ namespace std
template <class T> struct is_unbounded_array; // since C++20

// Member introspection:
template <class T> struct is_trivial;
template <class T> struct is_trivial; // deprecated in C++26
template <class T> struct is_pod; // deprecated in C++20
template <class T> struct is_trivially_copyable;
template <class T> struct is_standard_layout;
Expand Down Expand Up @@ -323,7 +323,7 @@ namespace std
template <class T> inline constexpr bool is_volatile_v
= is_volatile<T>::value; // since C++17
template <class T> inline constexpr bool is_trivial_v
= is_trivial<T>::value; // since C++17
= is_trivial<T>::value; // since C++17; deprecated in C++26
template <class T> inline constexpr bool is_trivially_copyable_v
= is_trivially_copyable<T>::value; // since C++17
template <class T> inline constexpr bool is_standard_layout_v
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ typedef std::allocator<void> A1;
struct A2 : std::allocator<void> { };

static_assert(std::is_trivially_default_constructible<A1>::value, "");
static_assert(std::is_trivial<A1>::value, "");
static_assert(std::is_trivially_copyable<A1>::value, "");

static_assert(std::is_trivially_default_constructible<A2>::value, "");
static_assert(std::is_trivial<A2>::value, "");
static_assert(std::is_trivially_copyable<A2>::value, "");
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ void test() {

// Make sure both types have the same triviality (that has ABI impact since
// it determined how objects are passed). Both should be non-trivial.
static_assert(std::is_trivial<New>::value == std::is_trivial<Old>::value, "");
static_assert(std::is_trivially_copyable<New>::value == std::is_trivially_copyable<Old>::value, "");
static_assert(
std::is_trivially_default_constructible<New>::value == std::is_trivially_default_constructible<Old>::value, "");
}

// Object types to store in the control block
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
#include <__utility/private_constructor_tag.h>
#include <type_traits>

static_assert(std::is_trivial<std::__private_constructor_tag>::value, "");
static_assert(std::is_trivially_copyable<std::__private_constructor_tag>::value, "");
static_assert(std::is_trivially_default_constructible<std::__private_constructor_tag>::value, "");
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ static_assert((std::is_same<decltype(nullptr), nullptr_t>::value), "");
static_assert(sizeof(nullptr_t) == sizeof(void*), "");
#if TEST_STD_VER >= 11
# if TEST_STD_VER >= 20
// P0767
static_assert(std::is_trivial<max_align_t>::value, "");
// P0767R1 and P3247R2
static_assert(std::is_trivially_copyable<max_align_t>::value, "");
static_assert(std::is_trivially_default_constructible<max_align_t>::value, "");
static_assert(std::is_standard_layout<max_align_t>::value, "");
# else
static_assert(std::is_pod<max_align_t>::value, "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
// It is a distinct type for accessing the bits that ultimately make up object storage.

#if TEST_STD_VER > 17
static_assert( std::is_trivial<std::byte>::value, "" ); // P0767
static_assert(std::is_trivially_copyable<std::byte>::value, "");
static_assert(std::is_trivially_default_constructible<std::byte>::value, "");
static_assert(std::is_standard_layout<std::byte>::value, "");
#else
static_assert( std::is_pod<std::byte>::value, "" );
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

#include "test_macros.h"

static_assert(std::is_trivial<std::max_align_t>::value, "");
static_assert(std::is_trivially_copyable<std::max_align_t>::value, "");
static_assert(std::is_trivially_default_constructible<std::max_align_t>::value, "");
static_assert(std::is_standard_layout<std::max_align_t>::value, "");
#if TEST_STD_VER <= 17
static_assert(std::is_pod<std::max_align_t>::value, "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ template <class CPO, class... Args>
constexpr bool test(CPO& o, Args&&...) {
static_assert(std::is_const_v<CPO>);
static_assert(std::is_class_v<CPO>);
static_assert(std::is_trivial_v<CPO>);
static_assert(std::is_trivially_copyable_v<CPO>);
static_assert(std::is_trivially_default_constructible_v<CPO>);

auto p = o;
using T = decltype(p);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ template <class CPO, class... Args>
constexpr bool test(CPO& o, Args&&...) {
static_assert(std::is_const_v<CPO>);
static_assert(std::is_class_v<CPO>);
static_assert(std::is_trivial_v<CPO>);
static_assert(std::is_trivially_copyable_v<CPO>);
static_assert(std::is_trivially_default_constructible_v<CPO>);

auto p = o;
using T = decltype(p);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#include <type_traits>

static_assert(std::is_empty_v<std::ranges::view_base>);
static_assert(std::is_trivial_v<std::ranges::view_base>);
static_assert(std::is_trivially_copyable_v<std::ranges::view_base>);
static_assert(std::is_trivially_default_constructible_v<std::ranges::view_base>);

// Make sure we can inherit from it, as it's intended (that wouldn't be the
// case if e.g. it was marked as final).
Expand Down
30 changes: 24 additions & 6 deletions libcxx/test/std/strings/basic.string/char.bad.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,25 @@
//
//===----------------------------------------------------------------------===//

// XFAIL: FROZEN-CXX03-HEADERS-FIXME

// <string>
// ... manipulating sequences of any non-array trivial standard-layout types.

#include <string>
#include <type_traits>
#include "test_traits.h"

struct NotTrivial {
NotTrivial() : value(3) {}
struct NotTriviallyCopyable {
int value;
NotTriviallyCopyable& operator=(const NotTriviallyCopyable& other) {
value = other.value;
return *this;
}
};

struct NotTriviallyDefaultConstructible {
NotTriviallyDefaultConstructible() : value(3) {}
int value;
};

Expand All @@ -37,10 +48,17 @@ void f() {
}

{
// not trivial
static_assert(!std::is_trivial<NotTrivial>::value, "");
std::basic_string<NotTrivial, test_traits<NotTrivial> > s;
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string must be trivial}}
// not trivially copyable
static_assert(!std::is_trivially_copyable<NotTriviallyCopyable>::value, "");
std::basic_string<NotTriviallyCopyable, test_traits<NotTriviallyCopyable> > s;
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string must be trivially copyable}}
}

{
// not trivially default constructible
static_assert(!std::is_trivially_default_constructible<NotTriviallyDefaultConstructible>::value, "");
std::basic_string<NotTriviallyDefaultConstructible, test_traits<NotTriviallyDefaultConstructible> > s;
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string must be trivially default constructible}}
}

{
Expand Down
28 changes: 22 additions & 6 deletions libcxx/test/std/strings/string.view/char.bad.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@
// ... manipulating sequences of any non-array trivial standard-layout types.

#include <string>
#include <type_traits>
#include "../basic.string/test_traits.h"

struct NotTrivial {
NotTrivial() : value(3) {}
struct NotTriviallyCopyable {
int value;
NotTriviallyCopyable& operator=(const NotTriviallyCopyable& other) {
value = other.value;
return *this;
}
};

struct NotTriviallyDefaultConstructible {
NotTriviallyDefaultConstructible() : value(3) {}
int value;
};

Expand All @@ -41,10 +50,17 @@ int main(int, char**) {
}

{
// not trivial
static_assert(!std::is_trivial<NotTrivial>::value, "");
std::basic_string_view<NotTrivial, test_traits<NotTrivial> > sv;
// expected-error-re@string_view:* {{static assertion failed{{.*}}Character type of basic_string_view must be trivial}}
// not trivially copyable
static_assert(!std::is_trivially_copyable<NotTriviallyCopyable>::value, "");
std::basic_string_view<NotTriviallyCopyable, test_traits<NotTriviallyCopyable> > s;
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string_view must be trivially copyable}}
}

{
// not trivially default constructible
static_assert(!std::is_trivially_default_constructible<NotTriviallyDefaultConstructible>::value, "");
std::basic_string_view<NotTriviallyDefaultConstructible, test_traits<NotTriviallyDefaultConstructible> > sv;
// expected-error-re@string_view:* {{static assertion failed{{.*}}Character type of basic_string_view must be trivially default constructible}}
}

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@

// This test test whether non-specialized versions exhibit the expected
// behavior. (Note these specializations are not really useful.)
static_assert(std::is_trivial_v<std::chrono::zoned_traits<int>>);
static_assert(std::is_trivial_v<std::chrono::zoned_traits<float>>);
static_assert(std::is_trivial_v<std::chrono::zoned_traits<void*>>);
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<int>>);
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<float>>);
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<void*>>);
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<int>>);
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<float>>);
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<void*>>);

struct foo {};
static_assert(std::is_empty_v<std::chrono::zoned_traits<foo>>);
static_assert(std::is_trivial_v<std::chrono::zoned_traits<foo>>);
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<foo>>);
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<foo>>);
Loading