diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-03-14 18:35:17 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-03-14 18:35:17 (GMT) | 
| commit | a135c6ff4dcded5661a2321512960b14cf8c15c8 (patch) | |
| tree | b0017ecfe702304f592b9d4e8b943784cff26fb2 /3rdParty/Boost/src/boost/optional/optional.hpp | |
| parent | 02d6188ab335e6c62b8341b84579d9549d215118 (diff) | |
| download | swift-contrib-a135c6ff4dcded5661a2321512960b14cf8c15c8.zip swift-contrib-a135c6ff4dcded5661a2321512960b14cf8c15c8.tar.bz2  | |
Updated Boost to 1.46.1.
This should hopefuily fix a hang on shutdown on Mac OS X.
Resolves: #782
Release-Notes: Fixed a potential hang on shutdown on Mac OS X.
Diffstat (limited to '3rdParty/Boost/src/boost/optional/optional.hpp')
| -rw-r--r-- | 3rdParty/Boost/src/boost/optional/optional.hpp | 225 | 
1 files changed, 146 insertions, 79 deletions
diff --git a/3rdParty/Boost/src/boost/optional/optional.hpp b/3rdParty/Boost/src/boost/optional/optional.hpp index 88041d1..ec9006e 100644 --- a/3rdParty/Boost/src/boost/optional/optional.hpp +++ b/3rdParty/Boost/src/boost/optional/optional.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.  //  // Use, modification, and distribution is subject to the Boost Software  // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,27 +9,34 @@  // You are welcome to contact the author at:  //  fernando_cacciola@hotmail.com  // +// 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 "boost/config.hpp" -#include "boost/assert.hpp" -#include "boost/type.hpp" -#include "boost/type_traits/alignment_of.hpp" -#include "boost/type_traits/type_with_alignment.hpp" -#include "boost/type_traits/remove_reference.hpp" -#include "boost/type_traits/is_reference.hpp" -#include "boost/mpl/if.hpp" -#include "boost/mpl/bool.hpp" -#include "boost/mpl/not.hpp" -#include "boost/detail/reference_content.hpp" -#include "boost/none.hpp" -#include "boost/utility/compare_pointees.hpp" - -#include "boost/optional/optional_fwd.hpp" +#include <new> +#include <algorithm> + +#include <boost/config.hpp> +#include <boost/assert.hpp> +#include <boost/type.hpp> +#include <boost/type_traits/alignment_of.hpp> +#include <boost/type_traits/has_nothrow_constructor.hpp> +#include <boost/type_traits/type_with_alignment.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/is_reference.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/not.hpp> +#include <boost/detail/reference_content.hpp> +#include <boost/none.hpp> +#include <boost/utility/swap.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/utility/compare_pointees.hpp> +#include <boost/utility/in_place_factory.hpp> + +#include <boost/optional/optional_fwd.hpp>  #if BOOST_WORKAROUND(BOOST_MSVC, == 1200)  // VC6.0 has the following bug: @@ -76,6 +83,15 @@  #define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION  #endif +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) > 302 \ +    && !defined(__INTEL_COMPILER) +// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with +// regard to violation of the strict aliasing rules. The optional< T > storage type is marked +// with this attribute in order to let the compiler know that it will alias objects of type T +// and silence compilation warnings. +#define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS +#endif +  // Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>  // member template of a factory as used in the optional<> implementation.  // He proposed this simple fix which is to move the call to apply<> outside @@ -83,7 +99,7 @@  namespace boost_optional_detail  {    template <class T, class Factory> -  void construct(Factory const& factory, void* address) +  inline void construct(Factory const& factory, void* address)    {      factory.BOOST_NESTED_TEMPLATE apply<T>(address);    } @@ -95,6 +111,9 @@ namespace boost {  class in_place_factory_base ;  class typed_in_place_factory_base ; +// This forward is needed to refer to namespace scope swap from the member swap +template<class T> void swap ( optional<T>& x, optional<T>& y ); +  namespace optional_detail {  // This local class is used instead of that in "aligned_storage.hpp" @@ -105,7 +124,12 @@ template <class T>  class aligned_storage  {      // Borland ICEs if unnamed unions are used for this! -    union dummy_u +    union +    // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T* +#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) +    __attribute__((may_alias)) +#endif +    dummy_u      {          char data[ sizeof(T) ];          BOOST_DEDUCED_TYPENAME type_with_alignment< @@ -114,8 +138,13 @@ class aligned_storage    public: -    void const* address() const { return &dummy_.data[0]; } -    void      * address()       { return &dummy_.data[0]; } +#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) +    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> @@ -149,7 +178,7 @@ class optional_base : public optional_tag      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 ; @@ -200,7 +229,7 @@ class optional_base : public optional_tag      {        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 ) @@ -421,8 +450,22 @@ class optional_base : public optional_tag    private :      // internal_type can be either T or reference_content<T> +#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) +    // 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 ; } @@ -513,12 +556,12 @@ class optional : public optional_detail::optional_base<T>      // 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>      // Can throw if T::T(T const&) does -    optional ( optional const& rhs ) : base(rhs) {} +    optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}     // No-throw (assuming T::~T() doesn't)      ~optional() {} @@ -527,9 +570,9 @@ class optional : public optional_detail::optional_base<T>      // 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 @@ -552,7 +595,7 @@ class optional : public optional_detail::optional_base<T>      //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)      optional& operator= ( optional const& rhs )        { -        this->assign( rhs ) ; +        this->assign( static_cast<base const&>(rhs) ) ;          return *this ;        } @@ -573,6 +616,14 @@ class optional : public optional_detail::optional_base<T>          return *this ;        } +    void swap( optional & arg ) +      { +        // allow for Koenig lookup +        using boost::swap; +        swap(*this, arg); +      } + +      // Returns a reference to the value if this is initialized, otherwise,      // the behaviour is UNDEFINED      // No-throw @@ -582,7 +633,7 @@ class optional : public optional_detail::optional_base<T>      // 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 @@ -599,22 +650,22 @@ class optional : public optional_detail::optional_base<T>      // 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); @@ -867,58 +918,74 @@ inline  bool operator >= ( none_t x, optional<T> const& y )  { return !( x < y ) ; } -// -// The following swap implementation follows the GCC workaround as found in -//  "boost/detail/compressed_pair.hpp" -//  namespace optional_detail { -// GCC < 3.2 gets the using declaration at namespace scope (FLC, DWA) -#if BOOST_WORKAROUND(__GNUC__, < 3)                             \ -    || BOOST_WORKAROUND(__GNUC__, == 3) && __GNUC_MINOR__ <= 2 -   using std::swap; -#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE -#endif +template<bool use_default_constructor> struct swap_selector; -// optional's swap: -// If both are initialized, calls swap(T&, T&). If this swap throws, both will remain initialized but their values are now unspecified. -// If only one is initialized, calls U.reset(*I), THEN I.reset(). -// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I is never reset) -// If both are uninitialized, do nothing (no-throw) -template<class T> -inline -void optional_swap ( optional<T>& x, optional<T>& y ) +template<> +struct swap_selector<true>  { -  if ( !x && !!y ) -  { -    x.reset(*y); -    y.reset(); -  } -  else if ( !!x && !y ) -  { -    y.reset(*x); -    x.reset(); -  } -  else if ( !!x && !!y ) -  { -// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC) -#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE -    // allow for Koenig lookup -    using std::swap ; -#endif -    swap(*x,*y); -  } -} +    template<class T> +    static void optional_swap ( optional<T>& x, optional<T>& y ) +    { +        const bool hasX = !!x; +        const bool hasY = !!y; + +        if ( !hasX && !hasY ) +            return; + +        if( !hasX ) +            x = boost::in_place(); +        else if ( !hasY ) +            y = boost::in_place(); + +        // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers +        boost::swap(x.get(),y.get()); + +        if( !hasX ) +            y = boost::none ; +        else if( !hasY ) +            x = boost::none ; +    } +}; + +template<> +struct swap_selector<false> +{ +    template<class T> +    static void optional_swap ( optional<T>& x, optional<T>& y ) +    { +        const bool hasX = !!x; +        const bool hasY = !!y; + +        if ( !hasX && hasY ) +        { +            x = y.get(); +            y = boost::none ; +        } +        else if ( hasX && !hasY ) +        { +            y = x.get(); +            x = boost::none ; +        } +        else if ( hasX && hasY ) +        { +            // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers +            boost::swap(x.get(),y.get()); +        } +    } +};  } // namespace optional_detail +template<class T> +struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ; +  template<class T> inline void swap ( optional<T>& x, optional<T>& y )  { -  optional_detail::optional_swap(x,y); +    optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);  } -  } // namespace boost  #endif -  | 
 Swift