Index: third_party/cld/base/casts.h |
=================================================================== |
--- third_party/cld/base/casts.h (revision 0) |
+++ third_party/cld/base/casts.h (revision 0) |
@@ -0,0 +1,156 @@ |
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_CASTS_H_ |
+#define BASE_CASTS_H_ |
+ |
+#include <assert.h> // for use with down_cast<> |
+#include <string.h> // for memcpy |
+ |
+#include "third_party/cld/base/macros.h" |
+ |
+ |
+// Use implicit_cast as a safe version of static_cast or const_cast |
+// for upcasting in the type hierarchy (i.e. casting a pointer to Foo |
+// to a pointer to SuperclassOfFoo or casting a pointer to Foo to |
+// a const pointer to Foo). |
+// When you use implicit_cast, the compiler checks that the cast is safe. |
+// Such explicit implicit_casts are necessary in surprisingly many |
+// situations where C++ demands an exact type match instead of an |
+// argument type convertable to a target type. |
+// |
+// The From type can be inferred, so the preferred syntax for using |
+// implicit_cast is the same as for static_cast etc.: |
+// |
+// implicit_cast<ToType>(expr) |
+// |
+// implicit_cast would have been part of the C++ standard library, |
+// but the proposal was submitted too late. It will probably make |
+// its way into the language in the future. |
+template<typename To, typename From> |
+inline To implicit_cast(From const &f) { |
+ return f; |
+} |
+ |
+ |
+// When you upcast (that is, cast a pointer from type Foo to type |
+// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts |
+// always succeed. When you downcast (that is, cast a pointer from |
+// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because |
+// how do you know the pointer is really of type SubclassOfFoo? It |
+// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, |
+// when you downcast, you should use this macro. In debug mode, we |
+// use dynamic_cast<> to double-check the downcast is legal (we die |
+// if it's not). In normal mode, we do the efficient static_cast<> |
+// instead. Thus, it's important to test in debug mode to make sure |
+// the cast is legal! |
+// This is the only place in the code we should use dynamic_cast<>. |
+// In particular, you SHOULDN'T be using dynamic_cast<> in order to |
+// do RTTI (eg code like this: |
+// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo); |
+// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo); |
+// You should design the code some other way not to need this. |
+ |
+template<typename To, typename From> // use like this: down_cast<T*>(foo); |
+inline To down_cast(From* f) { // so we only accept pointers |
+ // Ensures that To is a sub-type of From *. This test is here only |
+ // for compile-time type checking, and has no overhead in an |
+ // optimized build at run-time, as it will be optimized away |
+ // completely. |
+ if (false) { |
+ implicit_cast<From*, To>(0); |
+ } |
+ |
+ assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only! |
+ return static_cast<To>(f); |
+} |
+ |
+// Overload of down_cast for references. Use like this: down_cast<T&>(foo). |
+// The code is slightly convoluted because we're still using the pointer |
+// form of dynamic cast. (The reference form throws an exception if it |
+// fails.) |
+// |
+// There's no need for a special const overload either for the pointer |
+// or the reference form. If you call down_cast with a const T&, the |
+// compiler will just bind From to const T. |
+template<typename To, typename From> |
+inline To down_cast(From& f) { |
+ COMPILE_ASSERT(base::is_reference<To>::value, target_type_not_a_reference); |
+ typedef typename base::remove_reference<To>::type* ToAsPointer; |
+ if (false) { |
+ // Compile-time check that To inherits from From. See above for details. |
+ implicit_cast<From*, ToAsPointer>(0); |
+ } |
+ |
+ assert(dynamic_cast<ToAsPointer>(&f) != NULL); // RTTI: debug mode only |
+ return static_cast<To>(f); |
+} |
+ |
+// bit_cast<Dest,Source> is a template function that implements the |
+// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in |
+// very low-level functions like the protobuf library and fast math |
+// support. |
+// |
+// float f = 3.14159265358979; |
+// int i = bit_cast<int32>(f); |
+// // i = 0x40490fdb |
+// |
+// The classical address-casting method is: |
+// |
+// // WRONG |
+// float f = 3.14159265358979; // WRONG |
+// int i = * reinterpret_cast<int*>(&f); // WRONG |
+// |
+// The address-casting method actually produces undefined behavior |
+// according to ISO C++ specification section 3.10 -15 -. Roughly, this |
+// section says: if an object in memory has one type, and a program |
+// accesses it with a different type, then the result is undefined |
+// behavior for most values of "different type". |
+// |
+// This is true for any cast syntax, either *(int*)&f or |
+// *reinterpret_cast<int*>(&f). And it is particularly true for |
+// conversions betweeen integral lvalues and floating-point lvalues. |
+// |
+// The purpose of 3.10 -15- is to allow optimizing compilers to assume |
+// that expressions with different types refer to different memory. gcc |
+// 4.0.1 has an optimizer that takes advantage of this. So a |
+// non-conforming program quietly produces wildly incorrect output. |
+// |
+// The problem is not the use of reinterpret_cast. The problem is type |
+// punning: holding an object in memory of one type and reading its bits |
+// back using a different type. |
+// |
+// The C++ standard is more subtle and complex than this, but that |
+// is the basic idea. |
+// |
+// Anyways ... |
+// |
+// bit_cast<> calls memcpy() which is blessed by the standard, |
+// especially by the example in section 3.9 . Also, of course, |
+// bit_cast<> wraps up the nasty logic in one place. |
+// |
+// Fortunately memcpy() is very fast. In optimized mode, with a |
+// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline |
+// code with the minimal amount of data movement. On a 32-bit system, |
+// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) |
+// compiles to two loads and two stores. |
+// |
+// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. |
+// |
+// WARNING: if Dest or Source is a non-POD type, the result of the memcpy |
+// is likely to surprise you. |
+// |
+ |
+template <class Dest, class Source> |
+inline Dest bit_cast(const Source& source) { |
+ // Compile time assertion: sizeof(Dest) == sizeof(Source) |
+ // A compile error here means your Dest and Source have different sizes. |
+ typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; |
+ |
+ Dest dest; |
+ memcpy(&dest, &source, sizeof(dest)); |
+ return dest; |
+} |
+ |
+#endif // BASE_CASTS_H_ |
Property changes on: third_party\cld\base\casts.h |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |