public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r11-5722] libstdc++: Add std::bit_cast for C++20 [PR 93121] Date: Thu, 3 Dec 2020 19:17:30 +0000 (GMT) [thread overview] Message-ID: <20201203191730.BD7BB3857003@sourceware.org> (raw) https://gcc.gnu.org/g:9e433b3461ab64b38350817392a77efb67bb78b4 commit r11-5722-g9e433b3461ab64b38350817392a77efb67bb78b4 Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Dec 3 19:17:13 2020 +0000 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. Diff: --- libstdc++-v3/include/std/bit | 12 ++++ libstdc++-v3/include/std/version | 3 + .../testsuite/26_numerics/bit/bit.cast/bit_cast.cc | 81 ++++++++++++++++++++++ .../testsuite/26_numerics/bit/bit.cast/version.cc | 27 ++++++++ 4 files changed, 123 insertions(+) diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index 16f7eba46d7..1d99c807c4a 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 25f628f399d..6e4bd99b361 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 00000000000..b451f152b47 --- /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 00000000000..688d44bbb89 --- /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
reply other threads:[~2020-12-03 19:17 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20201203191730.BD7BB3857003@sourceware.org \ --to=redi@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).