[libcxx-commits] [PATCH] D58004: Bit-casting object representations (p0476r2)

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sat Feb 9 10:11:21 PST 2019


zoecarver created this revision.
zoecarver added reviewers: mclow.lists, jfb.
Herald added subscribers: libcxx-commits, ldionne, christof.

Add `bit_cast` function outlined here <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0476r2.html>.


Repository:
  rCXX libc++

https://reviews.llvm.org/D58004

Files:
  include/bit
  test/libcxx/bit/bit_cast.pass.cpp


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 <bit>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T, class F>
+void test_bitcast(F init_value)
+{
+    auto cast_value = std::bit_cast<T>(init_value);
+    
+    ASSERT_SAME_TYPE(decltype(cast_value), T); // make sure type is the same
+    assert(std::bit_cast<F>(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<std::uint64_t>(d);
+    
+    constexpr long long int lli = 12345;
+    test_bitcast<double>(lli);
+    
+    constexpr long int li = 4321;
+    test_bitcast<float*>(&li);
+    
+    // test structs
+    constexpr A a = A {.a=123};
+    B b = std::bit_cast<B>(a);
+    assert(b.b == 123);
+    
+    return 0;
+}
Index: include/bit
===================================================================
--- include/bit
+++ include/bit
@@ -21,6 +21,7 @@
 
 #include <__config>
 #include <version>
+#include <memory>
 
 #if defined(__IBMCPP__)
 #include "support/ibm/support.h"
@@ -152,6 +153,22 @@
 
 #endif // _LIBCPP_COMPILER_MSVC
 
+// bit_cast
+
+template <typename _To, typename _Fm>
+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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58004.186098.patch
Type: text/x-patch
Size: 2195 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190209/620e1da4/attachment.bin>


More information about the libcxx-commits mailing list