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)28template <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