diff options
Diffstat (limited to '3rdParty/Boost/src/boost/optional')
-rw-r--r-- | 3rdParty/Boost/src/boost/optional/optional.hpp | 225 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/optional/optional_io.hpp | 84 |
2 files changed, 146 insertions, 163 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 - diff --git a/3rdParty/Boost/src/boost/optional/optional_io.hpp b/3rdParty/Boost/src/boost/optional/optional_io.hpp deleted file mode 100644 index 85a1857..0000000 --- a/3rdParty/Boost/src/boost/optional/optional_io.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2005, 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 -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#ifndef BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP -#define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP - -#if defined __GNUC__ -# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97) -# define BOOST_OPTIONAL_NO_TEMPLATED_STREAMS -# endif -#endif // __GNUC__ - -#if defined BOOST_OPTIONAL_NO_TEMPLATED_STREAMS -# include <iostream> -#else -# include <istream> -# include <ostream> -#endif - - -#include "boost/optional/optional.hpp" -#include "boost/utility/value_init.hpp" - -namespace boost -{ - -#if defined (BOOST_NO_TEMPLATED_STREAMS) -template<class T> -inline std::ostream& operator<<(std::ostream& out, optional<T> const& v) -#else -template<class CharType, class CharTrait, class T> -inline -std::basic_ostream<CharType, CharTrait>& -operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v) -#endif -{ - if ( out.good() ) - { - if ( !v ) - out << "--" ; - else out << ' ' << *v ; - } - - return out; -} - -#if defined (BOOST_NO_TEMPLATED_STREAMS) -template<class T> -inline std::istream& operator>>(std::istream& in, optional<T>& v) -#else -template<class CharType, class CharTrait, class T> -inline -std::basic_istream<CharType, CharTrait>& -operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v) -#endif -{ - if ( in.good() ) - { - int d = in.get(); - if ( d == ' ' ) - { - T x ; - in >> x; - v = x ; - } - else - v = optional<T>() ; - } - - return in; -} - -} // namespace boost - -#endif - |