1 //===-- Freestanding version of bit_cast  -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SUPPORT_CPP_BIT_H
10 #define LLVM_LIBC_SUPPORT_CPP_BIT_H
11 
12 namespace __llvm_libc {
13 
14 #if defined __has_builtin
15 #if __has_builtin(__builtin_bit_cast)
16 #define LLVM_LIBC_HAS_BUILTIN_BIT_CAST
17 #endif
18 #endif
19 
20 #if defined __has_builtin
21 #if __has_builtin(__builtin_memcpy_inline)
22 #define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
23 #endif
24 #endif
25 
26 // This function guarantees the bitcast to be optimized away by the compiler for
27 // GCC >= 8 and Clang >= 6.
bit_cast(const From & from)28 template <class To, class From> constexpr To bit_cast(const From &from) {
29   static_assert(sizeof(To) == sizeof(From), "To and From must be of same size");
30 #if defined(LLVM_LIBC_HAS_BUILTIN_BIT_CAST)
31   return __builtin_bit_cast(To, from);
32 #else
33   To to;
34   char *dst = reinterpret_cast<char *>(&to);
35   const char *src = reinterpret_cast<const char *>(&from);
36 #if defined(LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE)
37   __builtin_memcpy_inline(dst, src, sizeof(To));
38 #else
39   for (unsigned i = 0; i < sizeof(To); ++i)
40     dst[i] = src[i];
41 #endif // defined(LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE)
42   return to;
43 #endif // defined(LLVM_LIBC_HAS_BUILTIN_BIT_CAST)
44 }
45 
46 } // namespace __llvm_libc
47 
48 #endif // LLVM_LIBC_SUPPORT_CPP_BIT_H
49