15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_CASTS_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_CASTS_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> // for use with down_cast<> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> // for memcpy 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/macros.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use implicit_cast as a safe version of static_cast or const_cast 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for upcasting in the type hierarchy (i.e. casting a pointer to Foo 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a pointer to SuperclassOfFoo or casting a pointer to Foo to 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a const pointer to Foo). 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When you use implicit_cast, the compiler checks that the cast is safe. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Such explicit implicit_casts are necessary in surprisingly many 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// situations where C++ demands an exact type match instead of an 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argument type convertable to a target type. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The From type can be inferred, so the preferred syntax for using 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implicit_cast is the same as for static_cast etc.: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implicit_cast<ToType>(expr) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implicit_cast would have been part of the C++ standard library, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but the proposal was submitted too late. It will probably make 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// its way into the language in the future. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename To, typename From> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline To implicit_cast(From const &f) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return f; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When you upcast (that is, cast a pointer from type Foo to type 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// always succeed. When you downcast (that is, cast a pointer from 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// how do you know the pointer is really of type SubclassOfFoo? It 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when you downcast, you should use this macro. In debug mode, we 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use dynamic_cast<> to double-check the downcast is legal (we die 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if it's not). In normal mode, we do the efficient static_cast<> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead. Thus, it's important to test in debug mode to make sure 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the cast is legal! 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the only place in the code we should use dynamic_cast<>. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In particular, you SHOULDN'T be using dynamic_cast<> in order to 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do RTTI (eg code like this: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You should design the code some other way not to need this. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename To, typename From> // use like this: down_cast<T*>(foo); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline To down_cast(From* f) { // so we only accept pointers 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensures that To is a sub-type of From *. This test is here only 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for compile-time type checking, and has no overhead in an 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // optimized build at run-time, as it will be optimized away 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completely. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (false) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<From*, To>(0); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only! 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<To>(f); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Overload of down_cast for references. Use like this: down_cast<T&>(foo). 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The code is slightly convoluted because we're still using the pointer 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// form of dynamic cast. (The reference form throws an exception if it 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fails.) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There's no need for a special const overload either for the pointer 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or the reference form. If you call down_cast with a const T&, the 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compiler will just bind From to const T. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename To, typename From> 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline To down_cast(From& f) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(base::is_reference<To>::value, target_type_not_a_reference); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename base::remove_reference<To>::type* ToAsPointer; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (false) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compile-time check that To inherits from From. See above for details. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<From*, ToAsPointer>(0); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(dynamic_cast<ToAsPointer>(&f) != NULL); // RTTI: debug mode only 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<To>(f); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bit_cast<Dest,Source> is a template function that implements the 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// very low-level functions like the protobuf library and fast math 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// support. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// float f = 3.14159265358979; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int i = bit_cast<int32>(f); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // i = 0x40490fdb 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The classical address-casting method is: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // WRONG 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// float f = 3.14159265358979; // WRONG 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int i = * reinterpret_cast<int*>(&f); // WRONG 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The address-casting method actually produces undefined behavior 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// according to ISO C++ specification section 3.10 -15 -. Roughly, this 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// section says: if an object in memory has one type, and a program 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// accesses it with a different type, then the result is undefined 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// behavior for most values of "different type". 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is true for any cast syntax, either *(int*)&f or 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// *reinterpret_cast<int*>(&f). And it is particularly true for 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// conversions betweeen integral lvalues and floating-point lvalues. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The purpose of 3.10 -15- is to allow optimizing compilers to assume 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that expressions with different types refer to different memory. gcc 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4.0.1 has an optimizer that takes advantage of this. So a 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-conforming program quietly produces wildly incorrect output. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The problem is not the use of reinterpret_cast. The problem is type 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// punning: holding an object in memory of one type and reading its bits 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back using a different type. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The C++ standard is more subtle and complex than this, but that 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is the basic idea. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Anyways ... 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bit_cast<> calls memcpy() which is blessed by the standard, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// especially by the example in section 3.9 . Also, of course, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bit_cast<> wraps up the nasty logic in one place. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fortunately memcpy() is very fast. In optimized mode, with a 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// code with the minimal amount of data movement. On a 32-bit system, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compiles to two loads and two stores. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: if Dest or Source is a non-POD type, the result of the memcpy 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is likely to surprise you. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class Dest, class Source> 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline Dest bit_cast(const Source& source) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compile time assertion: sizeof(Dest) == sizeof(Source) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A compile error here means your Dest and Source have different sizes. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dest dest; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&dest, &source, sizeof(dest)); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dest; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_CASTS_H_ 157