diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2020-12-03 19:17:13 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2020-12-03 19:17:13 +0000 |
commit | 9e433b3461ab64b38350817392a77efb67bb78b4 (patch) | |
tree | e7120a6f2ad5b0176b2325ceb078ef977673379c /libstdc++-v3 | |
parent | adbeeb198a2a00812a5cd2ff0a38d6243a590dd0 (diff) | |
download | gcc-9e433b3461ab64b38350817392a77efb67bb78b4.zip gcc-9e433b3461ab64b38350817392a77efb67bb78b4.tar.gz gcc-9e433b3461ab64b38350817392a77efb67bb78b4.tar.bz2 |
libstdc++: Add std::bit_cast for C++20 [PR 93121]
Thanks to Jakub's addition of the built-in, we can add this to the
library now. The compiler tests for the built-in are quite extensive,
including verifying the constraints, so this only adds minimal tests to
the library testsuite.
This doesn't add a new _GLIBCXX_HAVE_BUILTIN_BIT_CAST because using
__has_builtin(__builtin_bit_cast) works for GCC and versions of Clang
that provide the built-in.
libstdc++-v3/ChangeLog:
PR libstdc++/93121
* include/std/bit (__cpp_lib_bit_cast, bit_cast): Define.
* include/std/version (__cpp_lib_bit_cast): Define.
* testsuite/26_numerics/bit/bit.cast/bit_cast.cc: New test.
* testsuite/26_numerics/bit/bit.cast/version.cc: New test.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/include/std/bit | 12 | ||||
-rw-r--r-- | libstdc++-v3/include/std/version | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc | 81 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc | 27 |
4 files changed, 123 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index 16f7eba..1d99c80 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -49,6 +49,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ +#if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast) +#define __cpp_lib_bit_cast 201806L + + /// Create a value of type `To` from the bits of `from`. + template<typename _To, typename _From> + constexpr _To + bit_cast(const _From& __from) noexcept + { + return __builtin_bit_cast(_To, __from); + } +#endif + /// @cond undoc template<typename _Tp> diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index 25f628f..6e4bd99 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -201,6 +201,9 @@ # define __cpp_lib_atomic_wait 201907L #endif #define __cpp_lib_bind_front 201907L +#if __has_builtin(__builtin_bit_cast) +# define __cpp_lib_bit_cast 201806L +#endif // FIXME: #define __cpp_lib_execution 201902L #define __cpp_lib_integer_comparison_functions 202002L #define __cpp_lib_constexpr_algorithms 201806L diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc new file mode 100644 index 0000000..b451f15 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc @@ -0,0 +1,81 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <bit> + +#ifndef __cpp_lib_bit_cast +# error "Feature-test macro for bit_cast wait missing in <bit>" +#elif __cpp_lib_bit_cast != 201806L +# error "Feature-test macro for bit_cast wait has wrong value in <bit>" +#endif + +#include <cstdint> +#include <cstring> +#include <testsuite_hooks.h> + +template<typename To, typename From> +constexpr bool +check(const From& from) +{ + return std::bit_cast<From>(std::bit_cast<To>(from)) == from; +} + +void +test01() +{ + static_assert( std::bit_cast<int>(123) == 123 ); + static_assert( std::bit_cast<int>(123u) == 123 ); + static_assert( std::bit_cast<int>(~0u) == ~0 ); + + if constexpr (sizeof(int) == sizeof(float)) + static_assert( check<int>(12.34f) ); + if constexpr (sizeof(unsigned long long) == sizeof(double)) + static_assert( check<unsigned long long>(123.456) ); + if constexpr (sizeof(std::intptr_t) == sizeof(void(*)())) + VERIFY( check<std::intptr_t>(&test01) ); +} + +void +test02() +{ + struct S + { + int i; + + bool operator==(const char* s) const + { return std::memcmp(&i, s, sizeof(i)) == 0; } + }; + + char arr[sizeof(int)]; + char arr2[sizeof(int)]; + for (int i = 0; i < sizeof(int); ++i) + { + arr[i] = i + 1; + arr2[i] = (i + 1) * -(i % 2); + } + VERIFY( std::bit_cast<S>(arr) == arr ); + VERIFY( std::bit_cast<S>(arr2) == arr2 ); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc new file mode 100644 index 0000000..688d44b --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc @@ -0,0 +1,27 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <version> + +#ifndef __cpp_lib_bit_cast +# error "Feature-test macro for bit_cast wait missing in <version>" +#elif __cpp_lib_bit_cast != 201806L +# error "Feature-test macro for bit_cast wait has wrong value in <version>" +#endif |