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.
This commit is contained in:
parent
adbeeb198a
commit
9e433b3461
4 changed files with 123 additions and 0 deletions
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
81
libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc
Normal file
81
libstdc++-v3/testsuite/26_numerics/bit/bit.cast/bit_cast.cc
Normal file
|
@ -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();
|
||||
}
|
27
libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc
Normal file
27
libstdc++-v3/testsuite/26_numerics/bit/bit.cast/version.cc
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue