Index: include/bit =================================================================== --- include/bit +++ include/bit @@ -21,6 +21,7 @@ #include <__config> #include +#include #if defined(__IBMCPP__) #include "support/ibm/support.h" @@ -152,6 +153,22 @@ #endif // _LIBCPP_COMPILER_MSVC +// bit_cast + +template +constexpr typename enable_if< + (sizeof(_To) == sizeof(_Fm)) && + std::is_trivially_copyable<_To>::value && + std::is_trivially_copyable<_Fm>::value, + _To +>::type +bit_cast(const _Fm &__src) noexcept +{ + _To __dst; + std::memcpy(&__dst, &__src, sizeof(_To)); + return __dst; +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_BIT Index: test/libcxx/bit/bit_cast.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/bit/bit_cast.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include +#include + +#include "test_macros.h" + +template +void test_bitcast(F init_value) +{ + auto cast_value = std::bit_cast(init_value); + + ASSERT_SAME_TYPE(decltype(cast_value), T); // make sure type is the same + assert(std::bit_cast(cast_value) == init_value); // make sure data isnt lost when casting back + +} + +struct A { int a; }; +struct B { int b; }; + +int main(int, char**) +{ + constexpr double d = 1234.0; // make sure it works with constexprs + test_bitcast(d); + + constexpr long long int lli = 12345; + test_bitcast(lli); + + constexpr long int li = 4321; + test_bitcast(&li); + + // test structs + constexpr A a = A {.a=123}; + B b = std::bit_cast(a); + assert(b.b == 123); + + return 0; +}