|
Boost-Commit : |
From: asutton_at_[hidden]
Date: 2008-07-18 12:43:02
Author: asutton
Date: 2008-07-18 12:43:02 EDT (Fri, 18 Jul 2008)
New Revision: 47573
URL: http://svn.boost.org/trac/boost/changeset/47573
Log:
Fixed a type punning warning by hiding the cast behind a union (union_cast<>).
Text files modified:
sandbox/SOC/2008/graphs/trunk/boost/blob.hpp | 34 ++++++++++++++++++++++++++++++----
1 files changed, 30 insertions(+), 4 deletions(-)
Modified: sandbox/SOC/2008/graphs/trunk/boost/blob.hpp
==============================================================================
--- sandbox/SOC/2008/graphs/trunk/boost/blob.hpp (original)
+++ sandbox/SOC/2008/graphs/trunk/boost/blob.hpp 2008-07-18 12:43:02 EDT (Fri, 18 Jul 2008)
@@ -6,14 +6,32 @@
#include <boost/functional/hash.hpp>
+namespace detail
+{
+ // Not for the faint of heart. This helps get around type punning issues
+ // by using a union to hide the explicit recast of an array of bytes to
+ // a real object.
+ template <typename T>
+ union union_caster
+ {
+ inline union_caster(void* src) : src(src) { }
+ T cast;
+ void* src;
+ };
+
+ // Use the union caster to affect type punning.
+ template <typename T>
+ inline T union_cast(void* x)
+ { union_caster<T> u(x); return u.cast; }
+}
+
/**
* The blob type is used to allocate a small buffer of memory that can be
* reinterpreted as a type of the same size. This is used solely as a means
* of deferring the immediate need for the type of an object if you can guess
* its size.
*
- * One can imagine this stands for "Binary Little OBject". Little because you
- * probably don't want to copy these around all over the place.
+ * One can imagine this stands for "Binary Little OBject".
*
* If you're going to write something hacky, you may as well try to make it a
* little bit pretty.
@@ -45,10 +63,18 @@
/** Get the value of the blob object, returning it as an object of type T. */
template <typename T>
- inline T& get() const
+ inline T& get()
+ {
+ static_assert(sizeof(T) == N, "Getting value of wrong size");
+ return *detail::union_cast<T*>(mem);
+ }
+
+ /** Get the value of the blob object, returning it as an object of type T. */
+ template <typename T>
+ inline T const& get() const
{
static_assert(sizeof(T) == N, "Getting value of wrong size");
- return *reinterpret_cast<T*>(mem);
+ return *detail::union_cast<T const*>(mem);
}
/** @name Equality Comparable
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk