|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r67020 - trunk/boost/optional
From: andrey.semashev_at_[hidden]
Date: 2010-12-05 09:43:19
Author: andysem
Date: 2010-12-05 09:43:18 EST (Sun, 05 Dec 2010)
New Revision: 67020
URL: http://svn.boost.org/trac/boost/changeset/67020
Log:
Refs #3395. Optional construction and assignment now works correctly for types with overridden operator&. Also silenced some GCC warnings about broken strict aliasing rules.
Text files modified:
trunk/boost/optional/optional.hpp | 63 +++++++++++++++++++++++++++------------
1 files changed, 44 insertions(+), 19 deletions(-)
Modified: trunk/boost/optional/optional.hpp
==============================================================================
--- trunk/boost/optional/optional.hpp (original)
+++ trunk/boost/optional/optional.hpp 2010-12-05 09:43:18 EST (Sun, 05 Dec 2010)
@@ -11,12 +11,12 @@
//
// Revisions:
// 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
-//
+//
#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
-#include<new>
-#include<algorithm>
+#include <new>
+#include <algorithm>
#include "boost/config.hpp"
#include "boost/assert.hpp"
@@ -31,6 +31,7 @@
#include "boost/mpl/not.hpp"
#include "boost/detail/reference_content.hpp"
#include "boost/none.hpp"
+#include "boost/utility/addressof.hpp"
#include "boost/utility/compare_pointees.hpp"
#include "boost/utility/in_place_factory.hpp"
@@ -110,7 +111,12 @@
class aligned_storage
{
// Borland ICEs if unnamed unions are used for this!
- union dummy_u
+ union
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+ // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T*
+ __attribute__((may_alias))
+#endif
+ dummy_u
{
char data[ sizeof(T) ];
BOOST_DEDUCED_TYPENAME type_with_alignment<
@@ -119,8 +125,13 @@
public:
- void const* address() const { return &dummy_.data[0]; }
- void * address() { return &dummy_.data[0]; }
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+ void const* address() const { return &dummy_; }
+ void * address() { return &dummy_; }
+#else
+ void const* address() const { return dummy_.data; }
+ void * address() { return dummy_.data; }
+#endif
} ;
template<class T>
@@ -154,7 +165,7 @@
typedef
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
BOOST_DEDUCED_TYPENAME
-#endif
+#endif
::boost::detail::make_reference_content<T>::type internal_type ;
typedef aligned_storage<internal_type> storage_type ;
@@ -205,7 +216,7 @@
{
construct(val);
}
-
+
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
// Can throw if T::T(T const&) does
optional_base ( bool cond, argument_type val )
@@ -426,8 +437,22 @@
private :
// internal_type can be either T or reference_content<T>
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+ // This workaround is supposed to silence GCC warnings about broken strict aliasing rules
+ internal_type const* get_object() const
+ {
+ union { void const* ap_pvoid; internal_type const* as_ptype; } caster = { m_storage.address() };
+ return caster.as_ptype;
+ }
+ internal_type * get_object()
+ {
+ union { void* ap_pvoid; internal_type* as_ptype; } caster = { m_storage.address() };
+ return caster.as_ptype;
+ }
+#else
internal_type const* get_object() const { return static_cast<internal_type const*>(m_storage.address()); }
internal_type * get_object() { return static_cast<internal_type *> (m_storage.address()); }
+#endif
// reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
@@ -518,7 +543,7 @@
// Depending on the above some T ctor is called.
// Can throw is the resolved T ctor throws.
template<class Expr>
- explicit optional ( Expr const& expr ) : base(expr,&expr) {}
+ explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
#endif
// Creates a deep copy of another optional<T>
@@ -532,9 +557,9 @@
// Assigns from an expression. See corresponding constructor.
// Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
template<class Expr>
- optional& operator= ( Expr expr )
+ optional& operator= ( Expr const& expr )
{
- this->assign_expr(expr,&expr);
+ this->assign_expr(expr,boost::addressof(expr));
return *this ;
}
#endif
@@ -595,7 +620,7 @@
// Returns a copy of the value if this is initialized, 'v' otherwise
reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; }
-
+
// Returns a pointer to the value if this is initialized, otherwise,
// the behaviour is UNDEFINED
// No-throw
@@ -612,22 +637,22 @@
// No-throw
operator unspecified_bool_type() const { return this->safe_bool() ; }
- // This is provided for those compilers which don't like the conversion to bool
- // on some contexts.
- bool operator!() const { return !this->is_initialized() ; }
+ // This is provided for those compilers which don't like the conversion to bool
+ // on some contexts.
+ bool operator!() const { return !this->is_initialized() ; }
} ;
// Returns optional<T>(v)
-template<class T>
-inline
+template<class T>
+inline
optional<T> make_optional ( T const& v )
{
return optional<T>(v);
}
// Returns optional<T>(cond,v)
-template<class T>
-inline
+template<class T>
+inline
optional<T> make_optional ( bool cond, T const& v )
{
return optional<T>(cond,v);
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