From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 70B6F3857003 for ; Thu, 3 Dec 2020 19:26:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 70B6F3857003 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-402-X6xRvm74OpKTIGb6f__EBA-1; Thu, 03 Dec 2020 14:25:57 -0500 X-MC-Unique: X6xRvm74OpKTIGb6f__EBA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D119D1005513; Thu, 3 Dec 2020 19:25:56 +0000 (UTC) Received: from localhost (unknown [10.33.37.15]) by smtp.corp.redhat.com (Postfix) with ESMTP id 796111A8A0; Thu, 3 Dec 2020 19:25:56 +0000 (UTC) Date: Thu, 3 Dec 2020 19:25:55 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Add std::bit_cast for C++20 [PR 93121] Message-ID: <20201203192555.GA3795239@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="Qxx1br4bt0+wmkIi" Content-Disposition: inline X-Spam-Status: No, score=-14.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Dec 2020 19:26:02 -0000 --Qxx1br4bt0+wmkIi Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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. Tested powerpc64le-linux. Committed to trunk. --Qxx1br4bt0+wmkIi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 9e433b3461ab64b38350817392a77efb67bb78b4 Author: Jonathan Wakely Date: Thu Dec 3 19:17:13 2020 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 --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 + constexpr _To + bit_cast(const _From& __from) noexcept + { + return __builtin_bit_cast(_To, __from); + } +#endif + /// @cond undoc template 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +#ifndef __cpp_lib_bit_cast +# error "Feature-test macro for bit_cast wait missing in " +#elif __cpp_lib_bit_cast != 201806L +# error "Feature-test macro for bit_cast wait has wrong value in " +#endif + +#include +#include +#include + +template +constexpr bool +check(const From& from) +{ + return std::bit_cast(std::bit_cast(from)) == from; +} + +void +test01() +{ + static_assert( std::bit_cast(123) == 123 ); + static_assert( std::bit_cast(123u) == 123 ); + static_assert( std::bit_cast(~0u) == ~0 ); + + if constexpr (sizeof(int) == sizeof(float)) + static_assert( check(12.34f) ); + if constexpr (sizeof(unsigned long long) == sizeof(double)) + static_assert( check(123.456) ); + if constexpr (sizeof(std::intptr_t) == sizeof(void(*)())) + VERIFY( check(&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(arr) == arr ); + VERIFY( std::bit_cast(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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +#ifndef __cpp_lib_bit_cast +# error "Feature-test macro for bit_cast wait missing in " +#elif __cpp_lib_bit_cast != 201806L +# error "Feature-test macro for bit_cast wait has wrong value in " +#endif --Qxx1br4bt0+wmkIi--