00001 // 00002 // Copyright 2017 The Abseil Authors. 00003 // 00004 // Licensed under the Apache License, Version 2.0 (the "License"); 00005 // you may not use this file except in compliance with the License. 00006 // You may obtain a copy of the License at 00007 // 00008 // https://www.apache.org/licenses/LICENSE-2.0 00009 // 00010 // Unless required by applicable law or agreed to in writing, software 00011 // distributed under the License is distributed on an "AS IS" BASIS, 00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 // See the License for the specific language governing permissions and 00014 // limitations under the License. 00015 // 00016 // ----------------------------------------------------------------------------- 00017 // File: casts.h 00018 // ----------------------------------------------------------------------------- 00019 // 00020 // This header file defines casting templates to fit use cases not covered by 00021 // the standard casts provided in the C++ standard. As with all cast operations, 00022 // use these with caution and only if alternatives do not exist. 00023 00024 #ifndef ABSL_BASE_CASTS_H_ 00025 #define ABSL_BASE_CASTS_H_ 00026 00027 #include <cstring> 00028 #include <memory> 00029 #include <type_traits> 00030 #include <utility> 00031 00032 #include "absl/base/internal/identity.h" 00033 #include "absl/base/macros.h" 00034 #include "absl/meta/type_traits.h" 00035 00036 namespace absl { 00037 00038 namespace internal_casts { 00039 00040 template <class Dest, class Source> 00041 struct is_bitcastable 00042 : std::integral_constant< 00043 bool, 00044 sizeof(Dest) == sizeof(Source) && 00045 type_traits_internal::is_trivially_copyable<Source>::value && 00046 type_traits_internal::is_trivially_copyable<Dest>::value && 00047 std::is_default_constructible<Dest>::value> {}; 00048 00049 } // namespace internal_casts 00050 00051 // implicit_cast() 00052 // 00053 // Performs an implicit conversion between types following the language 00054 // rules for implicit conversion; if an implicit conversion is otherwise 00055 // allowed by the language in the given context, this function performs such an 00056 // implicit conversion. 00057 // 00058 // Example: 00059 // 00060 // // If the context allows implicit conversion: 00061 // From from; 00062 // To to = from; 00063 // 00064 // // Such code can be replaced by: 00065 // implicit_cast<To>(from); 00066 // 00067 // An `implicit_cast()` may also be used to annotate numeric type conversions 00068 // that, although safe, may produce compiler warnings (such as `long` to `int`). 00069 // Additionally, an `implicit_cast()` is also useful within return statements to 00070 // indicate a specific implicit conversion is being undertaken. 00071 // 00072 // Example: 00073 // 00074 // return implicit_cast<double>(size_in_bytes) / capacity_; 00075 // 00076 // Annotating code with `implicit_cast()` allows you to explicitly select 00077 // particular overloads and template instantiations, while providing a safer 00078 // cast than `reinterpret_cast()` or `static_cast()`. 00079 // 00080 // Additionally, an `implicit_cast()` can be used to allow upcasting within a 00081 // type hierarchy where incorrect use of `static_cast()` could accidentally 00082 // allow downcasting. 00083 // 00084 // Finally, an `implicit_cast()` can be used to perform implicit conversions 00085 // from unrelated types that otherwise couldn't be implicitly cast directly; 00086 // C++ will normally only implicitly cast "one step" in such conversions. 00087 // 00088 // That is, if C is a type which can be implicitly converted to B, with B being 00089 // a type that can be implicitly converted to A, an `implicit_cast()` can be 00090 // used to convert C to B (which the compiler can then implicitly convert to A 00091 // using language rules). 00092 // 00093 // Example: 00094 // 00095 // // Assume an object C is convertible to B, which is implicitly convertible 00096 // // to A 00097 // A a = implicit_cast<B>(C); 00098 // 00099 // Such implicit cast chaining may be useful within template logic. 00100 template <typename To> 00101 constexpr To implicit_cast(typename absl::internal::identity_t<To> to) { 00102 return to; 00103 } 00104 00105 // bit_cast() 00106 // 00107 // Performs a bitwise cast on a type without changing the underlying bit 00108 // representation of that type's value. The two types must be of the same size 00109 // and both types must be trivially copyable. As with most casts, use with 00110 // caution. A `bit_cast()` might be needed when you need to temporarily treat a 00111 // type as some other type, such as in the following cases: 00112 // 00113 // * Serialization (casting temporarily to `char *` for those purposes is 00114 // always allowed by the C++ standard) 00115 // * Managing the individual bits of a type within mathematical operations 00116 // that are not normally accessible through that type 00117 // * Casting non-pointer types to pointer types (casting the other way is 00118 // allowed by `reinterpret_cast()` but round-trips cannot occur the other 00119 // way). 00120 // 00121 // Example: 00122 // 00123 // float f = 3.14159265358979; 00124 // int i = bit_cast<int32_t>(f); 00125 // // i = 0x40490fdb 00126 // 00127 // Casting non-pointer types to pointer types and then dereferencing them 00128 // traditionally produces undefined behavior. 00129 // 00130 // Example: 00131 // 00132 // // WRONG 00133 // float f = 3.14159265358979; // WRONG 00134 // int i = * reinterpret_cast<int*>(&f); // WRONG 00135 // 00136 // The address-casting method produces undefined behavior according to the ISO 00137 // C++ specification section [basic.lval]. Roughly, this section says: if an 00138 // object in memory has one type, and a program accesses it with a different 00139 // type, the result is undefined behavior for most values of "different type". 00140 // 00141 // Such casting results in type punning: holding an object in memory of one type 00142 // and reading its bits back using a different type. A `bit_cast()` avoids this 00143 // issue by implementing its casts using `memcpy()`, which avoids introducing 00144 // this undefined behavior. 00145 // 00146 // NOTE: The requirements here are more strict than the bit_cast of standard 00147 // proposal p0476 due to the need for workarounds and lack of intrinsics. 00148 // Specifically, this implementation also requires `Dest` to be 00149 // default-constructible. 00150 template < 00151 typename Dest, typename Source, 00152 typename std::enable_if<internal_casts::is_bitcastable<Dest, Source>::value, 00153 int>::type = 0> 00154 inline Dest bit_cast(const Source& source) { 00155 Dest dest; 00156 memcpy(static_cast<void*>(std::addressof(dest)), 00157 static_cast<const void*>(std::addressof(source)), sizeof(dest)); 00158 return dest; 00159 } 00160 00161 // NOTE: This overload is only picked if the requirements of bit_cast are not 00162 // met. It is therefore UB, but is provided temporarily as previous versions of 00163 // this function template were unchecked. Do not use this in new code. 00164 template < 00165 typename Dest, typename Source, 00166 typename std::enable_if< 00167 !internal_casts::is_bitcastable<Dest, Source>::value, int>::type = 0> 00168 ABSL_DEPRECATED( 00169 "absl::bit_cast type requirements were violated. Update the types being " 00170 "used such that they are the same size and are both TriviallyCopyable.") 00171 inline Dest bit_cast(const Source& source) { 00172 static_assert(sizeof(Dest) == sizeof(Source), 00173 "Source and destination types should have equal sizes."); 00174 00175 Dest dest; 00176 memcpy(&dest, &source, sizeof(dest)); 00177 return dest; 00178 } 00179 00180 } // namespace absl 00181 00182 #endif // ABSL_BASE_CASTS_H_