[libcxx-commits] [libcxx] [libc++][test] Rewrite tests for `std::byte` (PR #204116)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 16 04:07:15 PDT 2026
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/204116
>From a38bb3bf33090efe9a2e600d13c1212e35892fe1 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Tue, 16 Jun 2026 18:46:03 +0800
Subject: [PATCH] [libc++][test] Rewrite tests for `std::byte`
Previously, test files for `std::byte` were less than ideal. There were
many issues.
- `byte.pass.cpp` tested many properties which hold for enumeration
types, but failed to verity that `std::byte` is a scoped enumeration
type. Also, it was not a `.compile.pass.cpp`.
- `enum_direct_init.pass.cpp` seemed to be completely redundant.
- It was not tested that compound assignment operators return references
to their left operands.
- Return types of operators were rarely tested.
- Constraints of functions were not tested using SFINAE techniques.
- Test cases were not made run in both constant evaluation and at run
time in the conventional way.
This patch
- rewrites tests for `std::byte` to address these issues,
- expands test coverage for integer types listed in `type_algorithms.h`,
and
- updates lit comments to new-style `// REQUIRES: std-at-least-c++17`.
---
...ct_init.pass.cpp => byte.compile.pass.cpp} | 15 +--
.../support.types/byte.pass.cpp | 37 --------
.../support.types/byteops/and.assign.pass.cpp | 45 +++++----
.../support.types/byteops/and.pass.cpp | 35 ++++---
.../byteops/lshift.assign.compile.fail.cpp | 29 ------
.../byteops/lshift.assign.pass.cpp | 90 ++++++++++++++----
.../byteops/lshift.compile.fail.cpp | 24 -----
.../support.types/byteops/lshift.pass.cpp | 75 ++++++++++++---
.../support.types/byteops/not.pass.cpp | 29 ++++--
.../support.types/byteops/or.assign.pass.cpp | 46 ++++++----
.../support.types/byteops/or.pass.cpp | 35 ++++---
.../byteops/rshift.assign.compile.fail.cpp | 29 ------
.../byteops/rshift.assign.pass.cpp | 91 +++++++++++++++----
.../byteops/rshift.compile.fail.cpp | 24 -----
.../support.types/byteops/rshift.pass.cpp | 74 +++++++++++----
.../byteops/to_integer.compile.fail.cpp | 24 -----
.../support.types/byteops/to_integer.pass.cpp | 68 +++++++++++---
.../support.types/byteops/xor.assign.pass.cpp | 45 +++++----
.../support.types/byteops/xor.pass.cpp | 35 ++++---
19 files changed, 491 insertions(+), 359 deletions(-)
rename libcxx/test/std/language.support/support.types/{byteops/enum_direct_init.pass.cpp => byte.compile.pass.cpp} (56%)
delete mode 100644 libcxx/test/std/language.support/support.types/byte.pass.cpp
delete mode 100644 libcxx/test/std/language.support/support.types/byteops/lshift.assign.compile.fail.cpp
delete mode 100644 libcxx/test/std/language.support/support.types/byteops/lshift.compile.fail.cpp
delete mode 100644 libcxx/test/std/language.support/support.types/byteops/rshift.assign.compile.fail.cpp
delete mode 100644 libcxx/test/std/language.support/support.types/byteops/rshift.compile.fail.cpp
delete mode 100644 libcxx/test/std/language.support/support.types/byteops/to_integer.compile.fail.cpp
diff --git a/libcxx/test/std/language.support/support.types/byteops/enum_direct_init.pass.cpp b/libcxx/test/std/language.support/support.types/byte.compile.pass.cpp
similarity index 56%
rename from libcxx/test/std/language.support/support.types/byteops/enum_direct_init.pass.cpp
rename to libcxx/test/std/language.support/support.types/byte.compile.pass.cpp
index 8a84663206b6b..fdfb0e60c300d 100644
--- a/libcxx/test/std/language.support/support.types/byteops/enum_direct_init.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byte.compile.pass.cpp
@@ -7,13 +7,14 @@
//===----------------------------------------------------------------------===//
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
-int main(int, char**) {
- constexpr std::byte b{42};
- static_assert(std::to_integer<int>(b) == 42, "");
+// <cstddef>
- return 0;
-}
+// enum class byte : unsigned char {};
+
+static_assert(std::is_enum_v<std::byte>);
+static_assert(std::is_same_v<std::underlying_type_t<std::byte>, unsigned char>);
+static_assert(!std::is_convertible_v<std::byte, unsigned char>);
diff --git a/libcxx/test/std/language.support/support.types/byte.pass.cpp b/libcxx/test/std/language.support/support.types/byte.pass.cpp
deleted file mode 100644
index c707bde584af5..0000000000000
--- a/libcxx/test/std/language.support/support.types/byte.pass.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstddef>
-#include <type_traits>
-#include "test_macros.h"
-
-// XFAIL: c++03, c++11, c++14
-
-// std::byte is not an integer type, nor a character type.
-// It is a distinct type for accessing the bits that ultimately make up object storage.
-
-#if TEST_STD_VER > 17
-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
-static_assert(!std::is_arithmetic<std::byte>::value, "" );
-static_assert(!std::is_integral<std::byte>::value, "" );
-
-static_assert(!std::is_same<std::byte, char>::value, "" );
-static_assert(!std::is_same<std::byte, signed char>::value, "" );
-static_assert(!std::is_same<std::byte, unsigned char>::value, "" );
-
-// The standard doesn't outright say this, but it's pretty clear that it has to be true.
-static_assert(sizeof(std::byte) == 1, "" );
-
-int main(int, char**) {
- return 0;
-}
diff --git a/libcxx/test/std/language.support/support.types/byteops/and.assign.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/and.assign.pass.cpp
index 17008b30e4571..b5a57124a2d7d 100644
--- a/libcxx/test/std/language.support/support.types/byteops/and.assign.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/and.assign.pass.cpp
@@ -6,35 +6,42 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
-// constexpr byte& operator &=(byte l, byte r) noexcept;
+// constexpr byte& operator&=(byte& l, byte r) noexcept;
+constexpr std::byte test_op(std::byte b1, std::byte b2) {
+ static_assert(noexcept(b1 &= b2));
+ static_assert(std::is_same_v<decltype(b1 &= b2), std::byte&>);
-constexpr std::byte test(std::byte b1, std::byte b2) {
- std::byte bret = b1;
- return bret &= b2;
- }
+ std::byte& ret = b1 &= b2;
+ assert(&ret == &b1);
+ return ret;
+}
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b8{8};
+ std::byte b9{9};
-int main(int, char**) {
- std::byte b; // not constexpr, just used in noexcept check
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
- constexpr std::byte b9{static_cast<std::byte>(9)};
+ assert(std::to_integer<int>(test_op(b1, b8)) == 0);
+ assert(std::to_integer<int>(test_op(b1, b9)) == 1);
+ assert(std::to_integer<int>(test_op(b8, b9)) == 8);
- static_assert(noexcept(b &= b), "" );
+ assert(std::to_integer<int>(test_op(b8, b1)) == 0);
+ assert(std::to_integer<int>(test_op(b9, b1)) == 1);
+ assert(std::to_integer<int>(test_op(b9, b8)) == 8);
- static_assert(std::to_integer<int>(test(b1, b8)) == 0, "");
- static_assert(std::to_integer<int>(test(b1, b9)) == 1, "");
- static_assert(std::to_integer<int>(test(b8, b9)) == 8, "");
+ return true;
+}
- static_assert(std::to_integer<int>(test(b8, b1)) == 0, "");
- static_assert(std::to_integer<int>(test(b9, b1)) == 1, "");
- static_assert(std::to_integer<int>(test(b9, b8)) == 8, "");
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/and.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/and.pass.cpp
index 32c73c56913cd..3afc1d9ef6909 100644
--- a/libcxx/test/std/language.support/support.types/byteops/and.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/and.pass.cpp
@@ -6,27 +6,36 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// constexpr byte operator&(byte l, byte r) noexcept;
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
- constexpr std::byte b9{static_cast<std::byte>(9)};
+static_assert(noexcept(std::byte{} & std::byte{}));
+static_assert(std::is_same_v<decltype(std::byte{} & std::byte{}), std::byte>);
+
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b8{8};
+ std::byte b9{9};
- static_assert(noexcept(b1 & b8), "" );
+ assert(std::to_integer<int>(b1 & b8) == 0);
+ assert(std::to_integer<int>(b1 & b9) == 1);
+ assert(std::to_integer<int>(b8 & b9) == 8);
- static_assert(std::to_integer<int>(b1 & b8) == 0, "");
- static_assert(std::to_integer<int>(b1 & b9) == 1, "");
- static_assert(std::to_integer<int>(b8 & b9) == 8, "");
+ assert(std::to_integer<int>(b8 & b1) == 0);
+ assert(std::to_integer<int>(b9 & b1) == 1);
+ assert(std::to_integer<int>(b9 & b8) == 8);
- static_assert(std::to_integer<int>(b8 & b1) == 0, "");
- static_assert(std::to_integer<int>(b9 & b1) == 1, "");
- static_assert(std::to_integer<int>(b9 & b8) == 8, "");
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/lshift.assign.compile.fail.cpp b/libcxx/test/std/language.support/support.types/byteops/lshift.assign.compile.fail.cpp
deleted file mode 100644
index cdbb7886e5a5e..0000000000000
--- a/libcxx/test/std/language.support/support.types/byteops/lshift.assign.compile.fail.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstddef>
-#include <test_macros.h>
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// template <class IntegerType>
-// constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept;
-// This function shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
-
-
-constexpr std::byte test(std::byte b) {
- return b <<= 2.0;
- }
-
-
-int main(int, char**) {
- constexpr std::byte b1 = test(std::byte{1});
-
- return 0;
-}
diff --git a/libcxx/test/std/language.support/support.types/byteops/lshift.assign.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/lshift.assign.pass.cpp
index 7d7040f64d9cb..57c4a36ecfa1f 100644
--- a/libcxx/test/std/language.support/support.types/byteops/lshift.assign.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/lshift.assign.pass.cpp
@@ -6,32 +6,90 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
+#include <utility>
-// UNSUPPORTED: c++03, c++11, c++14
+#include "type_algorithms.h"
-// template <class IntegerType>
-// constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept;
-// This function shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
+// REQUIRES: std-at-least-c++17
+// template<class IntType>
+// constexpr byte& operator<<=(byte& b, IntType shift) noexcept;
+// Constraints: is_integral_v<IntType> is true.
-constexpr std::byte test(std::byte b) {
- return b <<= 2;
- }
+template <class, class = void>
+constexpr bool can_shl_assign_byte = false;
+template <class T>
+constexpr bool can_shl_assign_byte<T, std::void_t<decltype(std::declval<std::byte&>() <<= std::declval<T>())>> = true;
+template <class I>
+constexpr std::byte test_op(std::byte b) {
+ static_assert(noexcept(b <<= I{2}));
+ static_assert(std::is_same_v<decltype(b <<= I{2}), std::byte&>);
-int main(int, char**) {
- std::byte b; // not constexpr, just used in noexcept check
- constexpr std::byte b2{static_cast<std::byte>(2)};
- constexpr std::byte b3{static_cast<std::byte>(3)};
+ std::byte& ret = b <<= I{2};
+ assert(&ret == &b);
+ return ret;
+}
+
+struct test_functor {
+ template <class I>
+ constexpr void operator()() const {
+ static_assert(can_shl_assign_byte<I>);
+
+ std::byte b2{2};
+ std::byte b3{3};
+
+ assert(std::to_integer<int>(test_op<I>(b2)) == 8);
+ assert(std::to_integer<int>(test_op<I>(b3)) == 12);
+ }
+};
+
+struct test_failing_functor {
+ template <class T>
+ constexpr void operator()() const {
+ static_assert(!can_shl_assign_byte<T>);
+ }
+};
- static_assert(noexcept(b <<= 2), "" );
+constexpr void test_bool(std::byte b) {
+ static_assert(noexcept(b <<= true));
+ static_assert(std::is_same_v<decltype(b <<= true), std::byte&>);
- static_assert(std::to_integer<int>(test(b2)) == 8, "" );
- static_assert(std::to_integer<int>(test(b3)) == 12, "" );
+ {
+ std::byte b1 = b;
+ std::byte& ret = b1 <<= true;
+ assert(&ret == &b1);
+ assert(std::to_integer<int>(b1) == static_cast<unsigned char>(std::to_integer<int>(b) << 1));
+ }
+ {
+ std::byte b1 = b;
+ std::byte& ret = b1 <<= false;
+ assert(&ret == &b1);
+ assert(std::to_integer<int>(b1) == std::to_integer<int>(b));
+ }
+}
+
+constexpr bool test() {
+ types::for_each(types::integer_types{}, test_functor{});
+ types::for_each(types::floating_point_types{}, test_failing_functor{});
+ types::for_each(types::type_list<void*, std::nullptr_t, void, int()>{}, test_failing_functor{});
+
+ test_bool(std::byte{0});
+ test_bool(std::byte{1});
+ test_bool(std::byte{127});
+ test_bool(std::byte{128});
+ test_bool(std::byte{129});
+ test_bool(std::byte{255});
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/lshift.compile.fail.cpp b/libcxx/test/std/language.support/support.types/byteops/lshift.compile.fail.cpp
deleted file mode 100644
index 4bacc12296709..0000000000000
--- a/libcxx/test/std/language.support/support.types/byteops/lshift.compile.fail.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstddef>
-#include <test_macros.h>
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// template <class IntegerType>
-// constexpr byte operator <<(byte b, IntegerType shift) noexcept;
-// These functions shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
-
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b2 = b1 << 2.0f;
-
- return 0;
-}
diff --git a/libcxx/test/std/language.support/support.types/byteops/lshift.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/lshift.pass.cpp
index 7ded2d4dfda29..18182f5baecea 100644
--- a/libcxx/test/std/language.support/support.types/byteops/lshift.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/lshift.pass.cpp
@@ -6,26 +6,73 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+#include "type_algorithms.h"
-// template <class IntegerType>
-// constexpr byte operator <<(byte b, IntegerType shift) noexcept;
-// These functions shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
+// REQUIRES: std-at-least-c++17
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b3{static_cast<std::byte>(3)};
+// template<class IntType>
+// constexpr byte operator<<(byte b, IntType shift) noexcept;
+// Constraints: is_integral_v<IntType> is true.
+
+template <class, class = void>
+constexpr bool can_shl_byte = false;
+template <class T>
+constexpr bool can_shl_byte<T, std::void_t<decltype(std::byte{} << T{})>> = true;
+
+struct test_functor {
+ template <class I>
+ constexpr void operator()() const {
+ static_assert(can_shl_byte<I>);
+ static_assert(noexcept(std::byte{} << I{}));
+ static_assert(std::is_same_v<decltype(std::byte{} << I{}), std::byte>);
+
+ std::byte b1{1};
+ std::byte b3{3};
- static_assert(noexcept(b3 << 2), "" );
+ assert(std::to_integer<int>(b1 << I{1}) == 2);
+ assert(std::to_integer<int>(b1 << I{2}) == 4);
+ assert(std::to_integer<int>(b3 << I{4}) == 48);
+ assert(std::to_integer<int>(b3 << I{6}) == 192);
+ }
+};
- static_assert(std::to_integer<int>(b1 << 1) == 2, "");
- static_assert(std::to_integer<int>(b1 << 2) == 4, "");
- static_assert(std::to_integer<int>(b3 << 4) == 48, "");
- static_assert(std::to_integer<int>(b3 << 6) == 192, "");
+struct test_failing_functor {
+ template <class T>
+ constexpr void operator()() const {
+ static_assert(!can_shl_byte<T>);
+ }
+};
+
+constexpr void test_bool(std::byte b) {
+ static_assert(noexcept(b << true));
+ static_assert(std::is_same_v<decltype(b << true), std::byte>);
+
+ assert(std::to_integer<int>(b << true) == static_cast<unsigned char>(std::to_integer<int>(b) << 1));
+ assert(std::to_integer<int>(b << false) == std::to_integer<int>(b));
+}
+
+constexpr bool test() {
+ types::for_each(types::integer_types{}, test_functor{});
+ types::for_each(types::floating_point_types{}, test_failing_functor{});
+ types::for_each(types::type_list<void*, std::nullptr_t, void, int()>{}, test_failing_functor{});
+
+ test_bool(std::byte{0});
+ test_bool(std::byte{1});
+ test_bool(std::byte{127});
+ test_bool(std::byte{128});
+ test_bool(std::byte{129});
+ test_bool(std::byte{255});
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/not.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/not.pass.cpp
index 5c832b4d362ac..4e7b69ae5834f 100644
--- a/libcxx/test/std/language.support/support.types/byteops/not.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/not.pass.cpp
@@ -6,23 +6,32 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// constexpr byte operator~(byte b) noexcept;
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b2{static_cast<std::byte>(2)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
+static_assert(noexcept(~std::byte{}));
+static_assert(std::is_same_v<decltype(~std::byte{}), std::byte>);
+
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b2{2};
+ std::byte b8{8};
- static_assert(noexcept(~b1), "" );
+ assert(std::to_integer<int>(~b1) == 254);
+ assert(std::to_integer<int>(~b2) == 253);
+ assert(std::to_integer<int>(~b8) == 247);
- static_assert(std::to_integer<int>(~b1) == 254, "");
- static_assert(std::to_integer<int>(~b2) == 253, "");
- static_assert(std::to_integer<int>(~b8) == 247, "");
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/or.assign.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/or.assign.pass.cpp
index af34ab523903a..081f21589ea4e 100644
--- a/libcxx/test/std/language.support/support.types/byteops/or.assign.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/or.assign.pass.cpp
@@ -6,36 +6,42 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
-// constexpr byte& operator |=(byte l, byte r) noexcept;
+// constexpr byte& operator|=(byte& l, byte r) noexcept;
+constexpr std::byte test_op(std::byte b1, std::byte b2) {
+ static_assert(noexcept(b1 |= b2));
+ static_assert(std::is_same_v<decltype(b1 |= b2), std::byte&>);
-constexpr std::byte test(std::byte b1, std::byte b2) {
- std::byte bret = b1;
- return bret |= b2;
- }
-
+ std::byte& ret = b1 |= b2;
+ assert(&ret == &b1);
+ return ret;
+}
-int main(int, char**) {
- std::byte b; // not constexpr, just used in noexcept check
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b2{static_cast<std::byte>(2)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b2{2};
+ std::byte b8{8};
- static_assert(noexcept(b |= b), "" );
+ assert(std::to_integer<int>(test_op(b1, b2)) == 3);
+ assert(std::to_integer<int>(test_op(b1, b8)) == 9);
+ assert(std::to_integer<int>(test_op(b2, b8)) == 10);
- static_assert(std::to_integer<int>(test(b1, b2)) == 3, "");
- static_assert(std::to_integer<int>(test(b1, b8)) == 9, "");
- static_assert(std::to_integer<int>(test(b2, b8)) == 10, "");
+ assert(std::to_integer<int>(test_op(b2, b1)) == 3);
+ assert(std::to_integer<int>(test_op(b8, b1)) == 9);
+ assert(std::to_integer<int>(test_op(b8, b2)) == 10);
- static_assert(std::to_integer<int>(test(b2, b1)) == 3, "");
- static_assert(std::to_integer<int>(test(b8, b1)) == 9, "");
- static_assert(std::to_integer<int>(test(b8, b2)) == 10, "");
+ return true;
+}
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/or.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/or.pass.cpp
index 108da1d660be0..44a74e5cc9721 100644
--- a/libcxx/test/std/language.support/support.types/byteops/or.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/or.pass.cpp
@@ -6,27 +6,36 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// constexpr byte operator|(byte l, byte r) noexcept;
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b2{static_cast<std::byte>(2)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
+static_assert(noexcept(std::byte{} | std::byte{}));
+static_assert(std::is_same_v<decltype(std::byte{} | std::byte{}), std::byte>);
+
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b2{2};
+ std::byte b8{8};
- static_assert(noexcept(b1 | b2), "" );
+ assert(std::to_integer<int>(b1 | b2) == 3);
+ assert(std::to_integer<int>(b1 | b8) == 9);
+ assert(std::to_integer<int>(b2 | b8) == 10);
- static_assert(std::to_integer<int>(b1 | b2) == 3, "");
- static_assert(std::to_integer<int>(b1 | b8) == 9, "");
- static_assert(std::to_integer<int>(b2 | b8) == 10, "");
+ assert(std::to_integer<int>(b2 | b1) == 3);
+ assert(std::to_integer<int>(b8 | b1) == 9);
+ assert(std::to_integer<int>(b8 | b2) == 10);
- static_assert(std::to_integer<int>(b2 | b1) == 3, "");
- static_assert(std::to_integer<int>(b8 | b1) == 9, "");
- static_assert(std::to_integer<int>(b8 | b2) == 10, "");
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/rshift.assign.compile.fail.cpp b/libcxx/test/std/language.support/support.types/byteops/rshift.assign.compile.fail.cpp
deleted file mode 100644
index 95c8b8ea35561..0000000000000
--- a/libcxx/test/std/language.support/support.types/byteops/rshift.assign.compile.fail.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstddef>
-#include <test_macros.h>
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// template <class IntegerType>
-// constexpr byte operator>>(byte& b, IntegerType shift) noexcept;
-// This function shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
-
-
-constexpr std::byte test(std::byte b) {
- return b >>= 2.0;
- }
-
-
-int main(int, char**) {
- constexpr std::byte b1 = test(std::byte{1});
-
- return 0;
-}
diff --git a/libcxx/test/std/language.support/support.types/byteops/rshift.assign.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/rshift.assign.pass.cpp
index 3410e7a9737ab..055b4c877344f 100644
--- a/libcxx/test/std/language.support/support.types/byteops/rshift.assign.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/rshift.assign.pass.cpp
@@ -6,31 +6,90 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
+#include <utility>
-// UNSUPPORTED: c++03, c++11, c++14
+#include "type_algorithms.h"
-// template <class IntegerType>
-// constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept;
-// This function shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
+// REQUIRES: std-at-least-c++17
+// template<class IntType>
+// constexpr byte& operator>>=(byte& b, IntType shift) noexcept;
+// Constraints: is_integral_v<IntType> is true.
-constexpr std::byte test(std::byte b) {
- return b >>= 2;
- }
+template <class, class = void>
+constexpr bool can_shr_assign_byte = false;
+template <class T>
+constexpr bool can_shr_assign_byte<T, std::void_t<decltype(std::declval<std::byte&>() >>= std::declval<T>())>> = true;
+template <class I>
+constexpr std::byte test_op(std::byte b) {
+ static_assert(noexcept(b >>= I{2}));
+ static_assert(std::is_same_v<decltype(b >>= I{2}), std::byte&>);
-int main(int, char**) {
- std::byte b; // not constexpr, just used in noexcept check
- constexpr std::byte b16{static_cast<std::byte>(16)};
- constexpr std::byte b192{static_cast<std::byte>(192)};
+ std::byte& ret = b >>= I{2};
+ assert(&ret == &b);
+ return ret;
+}
+
+struct test_functor {
+ template <class I>
+ constexpr void operator()() const {
+ static_assert(can_shr_assign_byte<I>);
+
+ std::byte b16{16};
+ std::byte b192{192};
- static_assert(noexcept(b >>= 2), "" );
+ assert(std::to_integer<int>(test_op<I>(b16)) == 4);
+ assert(std::to_integer<int>(test_op<I>(b192)) == 48);
+ }
+};
- static_assert(std::to_integer<int>(test(b16)) == 4, "" );
- static_assert(std::to_integer<int>(test(b192)) == 48, "" );
+struct test_failing_functor {
+ template <class T>
+ constexpr void operator()() const {
+ static_assert(!can_shr_assign_byte<T>);
+ }
+};
+
+constexpr void test_bool(std::byte b) {
+ static_assert(noexcept(b >>= true));
+ static_assert(std::is_same_v<decltype(b >>= true), std::byte&>);
+
+ {
+ std::byte b1 = b;
+ std::byte& ret = b1 >>= true;
+ assert(&ret == &b1);
+ assert(std::to_integer<int>(b1) == std::to_integer<int>(b) >> 1);
+ }
+ {
+ std::byte b1 = b;
+ std::byte& ret = b1 >>= false;
+ assert(&ret == &b1);
+ assert(std::to_integer<int>(b1) == std::to_integer<int>(b));
+ }
+}
+
+constexpr bool test() {
+ types::for_each(types::integer_types{}, test_functor{});
+ types::for_each(types::floating_point_types{}, test_failing_functor{});
+ types::for_each(types::type_list<void*, std::nullptr_t, void, int()>{}, test_failing_functor{});
+
+ test_bool(std::byte{0});
+ test_bool(std::byte{1});
+ test_bool(std::byte{127});
+ test_bool(std::byte{128});
+ test_bool(std::byte{129});
+ test_bool(std::byte{255});
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/rshift.compile.fail.cpp b/libcxx/test/std/language.support/support.types/byteops/rshift.compile.fail.cpp
deleted file mode 100644
index 06fda34cad51b..0000000000000
--- a/libcxx/test/std/language.support/support.types/byteops/rshift.compile.fail.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstddef>
-#include <test_macros.h>
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// template <class IntegerType>
-// constexpr byte operator >>(byte b, IntegerType shift) noexcept;
-// These functions shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
-
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b2 = b1 >> 2.0f;
-
- return 0;
-}
diff --git a/libcxx/test/std/language.support/support.types/byteops/rshift.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/rshift.pass.cpp
index ffd929b3dee85..2412142abc0cf 100644
--- a/libcxx/test/std/language.support/support.types/byteops/rshift.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/rshift.pass.cpp
@@ -6,33 +6,73 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+#include "type_algorithms.h"
-// template <class IntegerType>
-// constexpr byte operator <<(byte b, IntegerType shift) noexcept;
-// These functions shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
+// REQUIRES: std-at-least-c++17
+// template<class IntType>
+// constexpr byte operator>>(byte b, IntType shift) noexcept;
+// Constraints: is_integral_v<IntType> is true.
-constexpr std::byte test(std::byte b) {
- return b <<= 2;
- }
+template <class, class = void>
+constexpr bool can_shr_byte = false;
+template <class T>
+constexpr bool can_shr_byte<T, std::void_t<decltype(std::byte{} >> T{})>> = true;
+struct test_functor {
+ template <class I>
+ constexpr void operator()() const {
+ static_assert(can_shr_byte<I>);
+ static_assert(noexcept(std::byte{} >> I{}));
+ static_assert(std::is_same_v<decltype(std::byte{} >> I{}), std::byte>);
-int main(int, char**) {
- constexpr std::byte b100{static_cast<std::byte>(100)};
- constexpr std::byte b115{static_cast<std::byte>(115)};
+ std::byte b100{100};
+ std::byte b115{115};
+
+ assert(std::to_integer<int>(b100 >> 1) == 50);
+ assert(std::to_integer<int>(b100 >> 2) == 25);
+ assert(std::to_integer<int>(b115 >> 3) == 14);
+ assert(std::to_integer<int>(b115 >> 6) == 1);
+ }
+};
+
+struct test_failing_functor {
+ template <class T>
+ constexpr void operator()() const {
+ static_assert(!can_shr_byte<T>);
+ }
+};
- static_assert(noexcept(b100 << 2), "" );
+constexpr void test_bool(std::byte b) {
+ static_assert(noexcept(b >> true));
+ static_assert(std::is_same_v<decltype(b >> true), std::byte>);
+
+ assert(std::to_integer<int>(b >> true) == std::to_integer<int>(b) >> 1);
+ assert(std::to_integer<int>(b >> false) == std::to_integer<int>(b));
+}
- static_assert(std::to_integer<int>(b100 >> 1) == 50, "");
- static_assert(std::to_integer<int>(b100 >> 2) == 25, "");
- static_assert(std::to_integer<int>(b115 >> 3) == 14, "");
- static_assert(std::to_integer<int>(b115 >> 6) == 1, "");
+constexpr bool test() {
+ types::for_each(types::integer_types{}, test_functor{});
+ types::for_each(types::floating_point_types{}, test_failing_functor{});
+ types::for_each(types::type_list<void*, std::nullptr_t, void, int()>{}, test_failing_functor{});
+ test_bool(std::byte{0});
+ test_bool(std::byte{1});
+ test_bool(std::byte{127});
+ test_bool(std::byte{128});
+ test_bool(std::byte{129});
+ test_bool(std::byte{255});
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/to_integer.compile.fail.cpp b/libcxx/test/std/language.support/support.types/byteops/to_integer.compile.fail.cpp
deleted file mode 100644
index 3981741603f62..0000000000000
--- a/libcxx/test/std/language.support/support.types/byteops/to_integer.compile.fail.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstddef>
-#include <test_macros.h>
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// template <class IntegerType>
-// constexpr IntegerType to_integer(byte b) noexcept;
-// This function shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
-
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- auto f = std::to_integer<float>(b1);
-
- return 0;
-}
diff --git a/libcxx/test/std/language.support/support.types/byteops/to_integer.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/to_integer.pass.cpp
index fe4b3ca51ea0c..5b73b9bc10a03 100644
--- a/libcxx/test/std/language.support/support.types/byteops/to_integer.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/to_integer.pass.cpp
@@ -6,28 +6,66 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
#include <type_traits>
-#include <test_macros.h>
-// UNSUPPORTED: c++03, c++11, c++14
+#include "type_algorithms.h"
-// template <class IntegerType>
-// constexpr IntegerType to_integer(byte b) noexcept;
-// This function shall not participate in overload resolution unless
-// is_integral_v<IntegerType> is true.
+// REQUIRES: std-at-least-c++17
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b3{static_cast<std::byte>(3)};
+// template<class IntType>
+// constexpr IntType to_integer(byte b) noexcept;
+// Constraints: is_integral_v<IntType> is true.
+
+template <class, class = void>
+constexpr bool can_to_integer = false;
+template <class T>
+constexpr bool can_to_integer<T, std::void_t<decltype(std::to_integer<T>(std::byte{}))>> = true;
+
+struct test_functor {
+ template <class I>
+ constexpr void operator()() const {
+ static_assert(can_to_integer<I>);
+ static_assert(noexcept(std::to_integer<I>(std::byte{})));
+ static_assert(std::is_same_v<decltype(std::to_integer<I>(std::byte{})), I>);
+
+ std::byte b1{1};
+ std::byte b3{3};
+
+ assert(std::to_integer<I>(b1) == I{1});
+ assert(std::to_integer<I>(b3) == I{3});
+ }
+};
+
+struct test_failing_functor {
+ template <class T>
+ constexpr void operator()() const {
+ static_assert(!can_to_integer<T>);
+ }
+};
- static_assert(noexcept(std::to_integer<int>(b1)), "" );
- static_assert(std::is_same<int, decltype(std::to_integer<int>(b1))>::value, "" );
- static_assert(std::is_same<long, decltype(std::to_integer<long>(b1))>::value, "" );
- static_assert(std::is_same<unsigned short, decltype(std::to_integer<unsigned short>(b1))>::value, "" );
+constexpr bool test() {
+ types::for_each(types::integer_types{}, test_functor{});
+ types::for_each(types::floating_point_types{}, test_failing_functor{});
+ types::for_each(types::type_list<void*, std::nullptr_t, void, int()>{}, test_failing_functor{});
- static_assert(std::to_integer<int>(b1) == 1, "");
- static_assert(std::to_integer<int>(b3) == 3, "");
+ static_assert(noexcept(std::to_integer<bool>(std::byte{})));
+ static_assert(std::is_same_v<decltype(std::to_integer<bool>(std::byte{})), bool>);
+
+ assert(!std::to_integer<bool>(std::byte{0}));
+ assert(std::to_integer<bool>(std::byte{1}));
+ assert(std::to_integer<bool>(std::byte{127}));
+ assert(std::to_integer<bool>(std::byte{128}));
+ assert(std::to_integer<bool>(std::byte{129}));
+ assert(std::to_integer<bool>(std::byte{255}));
+
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/xor.assign.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/xor.assign.pass.cpp
index 253033627fe53..01474883cd8cd 100644
--- a/libcxx/test/std/language.support/support.types/byteops/xor.assign.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/xor.assign.pass.cpp
@@ -6,35 +6,42 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
-// constexpr byte& operator ^=(byte l, byte r) noexcept;
+// constexpr byte& operator^=(byte& l, byte r) noexcept;
+constexpr std::byte test_op(std::byte b1, std::byte b2) {
+ static_assert(noexcept(b1 ^= b2));
+ static_assert(std::is_same_v<decltype(b1 ^= b2), std::byte&>);
-constexpr std::byte test(std::byte b1, std::byte b2) {
- std::byte bret = b1;
- return bret ^= b2;
- }
+ std::byte& ret = b1 ^= b2;
+ assert(&ret == &b1);
+ return ret;
+}
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b8{8};
+ std::byte b9{9};
-int main(int, char**) {
- std::byte b; // not constexpr, just used in noexcept check
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
- constexpr std::byte b9{static_cast<std::byte>(9)};
+ assert(std::to_integer<int>(test_op(b1, b8)) == 9);
+ assert(std::to_integer<int>(test_op(b1, b9)) == 8);
+ assert(std::to_integer<int>(test_op(b8, b9)) == 1);
- static_assert(noexcept(b ^= b), "" );
+ assert(std::to_integer<int>(test_op(b8, b1)) == 9);
+ assert(std::to_integer<int>(test_op(b9, b1)) == 8);
+ assert(std::to_integer<int>(test_op(b9, b8)) == 1);
- static_assert(std::to_integer<int>(test(b1, b8)) == 9, "");
- static_assert(std::to_integer<int>(test(b1, b9)) == 8, "");
- static_assert(std::to_integer<int>(test(b8, b9)) == 1, "");
+ return true;
+}
- static_assert(std::to_integer<int>(test(b8, b1)) == 9, "");
- static_assert(std::to_integer<int>(test(b9, b1)) == 8, "");
- static_assert(std::to_integer<int>(test(b9, b8)) == 1, "");
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
diff --git a/libcxx/test/std/language.support/support.types/byteops/xor.pass.cpp b/libcxx/test/std/language.support/support.types/byteops/xor.pass.cpp
index 9fa7b3ea3f441..aba8e39af33b0 100644
--- a/libcxx/test/std/language.support/support.types/byteops/xor.pass.cpp
+++ b/libcxx/test/std/language.support/support.types/byteops/xor.pass.cpp
@@ -6,27 +6,36 @@
//
//===----------------------------------------------------------------------===//
+#include <cassert>
#include <cstddef>
-#include <test_macros.h>
+#include <type_traits>
-// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: std-at-least-c++17
// constexpr byte operator^(byte l, byte r) noexcept;
-int main(int, char**) {
- constexpr std::byte b1{static_cast<std::byte>(1)};
- constexpr std::byte b8{static_cast<std::byte>(8)};
- constexpr std::byte b9{static_cast<std::byte>(9)};
+static_assert(noexcept(std::byte{} ^ std::byte{}));
+static_assert(std::is_same_v<decltype(std::byte{} ^ std::byte{}), std::byte>);
+
+constexpr bool test() {
+ std::byte b1{1};
+ std::byte b8{8};
+ std::byte b9{9};
- static_assert(noexcept(b1 ^ b8), "" );
+ assert(std::to_integer<int>(b1 ^ b8) == 9);
+ assert(std::to_integer<int>(b1 ^ b9) == 8);
+ assert(std::to_integer<int>(b8 ^ b9) == 1);
- static_assert(std::to_integer<int>(b1 ^ b8) == 9, "");
- static_assert(std::to_integer<int>(b1 ^ b9) == 8, "");
- static_assert(std::to_integer<int>(b8 ^ b9) == 1, "");
+ assert(std::to_integer<int>(b8 ^ b1) == 9);
+ assert(std::to_integer<int>(b9 ^ b1) == 8);
+ assert(std::to_integer<int>(b9 ^ b8) == 1);
- static_assert(std::to_integer<int>(b8 ^ b1) == 9, "");
- static_assert(std::to_integer<int>(b9 ^ b1) == 8, "");
- static_assert(std::to_integer<int>(b9 ^ b8) == 1, "");
+ return true;
+}
+
+int main(int, char**) {
+ test();
+ static_assert(test());
return 0;
}
More information about the libcxx-commits
mailing list