1.1 --- a/epoc32/include/stdapis/boost/optional/optional.hpp Tue Mar 16 16:12:26 2010 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,922 +0,0 @@
1.4 -// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
1.5 -//
1.6 -// Use, modification, and distribution is subject to the Boost Software
1.7 -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
1.8 -// http://www.boost.org/LICENSE_1_0.txt)
1.9 -//
1.10 -// See http://www.boost.org/lib/optional for documentation.
1.11 -//
1.12 -// You are welcome to contact the author at:
1.13 -// fernando_cacciola@hotmail.com
1.14 -//
1.15 -#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
1.16 -#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
1.17 -
1.18 -#include<new>
1.19 -#include<algorithm>
1.20 -
1.21 -#include "boost/config.hpp"
1.22 -#include "boost/assert.hpp"
1.23 -#include "boost/type.hpp"
1.24 -#include "boost/type_traits/alignment_of.hpp"
1.25 -#include "boost/type_traits/type_with_alignment.hpp"
1.26 -#include "boost/type_traits/remove_reference.hpp"
1.27 -#include "boost/type_traits/is_reference.hpp"
1.28 -#include "boost/mpl/if.hpp"
1.29 -#include "boost/mpl/bool.hpp"
1.30 -#include "boost/mpl/not.hpp"
1.31 -#include "boost/detail/reference_content.hpp"
1.32 -#include "boost/none.hpp"
1.33 -#include "boost/utility/compare_pointees.hpp"
1.34 -
1.35 -#include "boost/optional/optional_fwd.hpp"
1.36 -
1.37 -#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
1.38 -// VC6.0 has the following bug:
1.39 -// When a templated assignment operator exist, an implicit conversion
1.40 -// constructing an optional<T> is used when assigment of the form:
1.41 -// optional<T> opt ; opt = T(...);
1.42 -// is compiled.
1.43 -// However, optional's ctor is _explicit_ and the assignemt shouldn't compile.
1.44 -// Therefore, for VC6.0 templated assignment is disabled.
1.45 -//
1.46 -#define BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
1.47 -#endif
1.48 -
1.49 -#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
1.50 -// VC7.0 has the following bug:
1.51 -// When both a non-template and a template copy-ctor exist
1.52 -// and the templated version is made 'explicit', the explicit is also
1.53 -// given to the non-templated version, making the class non-implicitely-copyable.
1.54 -//
1.55 -#define BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
1.56 -#endif
1.57 -
1.58 -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
1.59 -// AFAICT only VC7.1 correctly resolves the overload set
1.60 -// that includes the in-place factory taking functions,
1.61 -// so for the other VC versions, in-place factory support
1.62 -// is disabled
1.63 -#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
1.64 -#endif
1.65 -
1.66 -#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
1.67 -// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
1.68 -#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
1.69 -#endif
1.70 -
1.71 -#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
1.72 - && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
1.73 -// BCB (up to 5.64) has the following bug:
1.74 -// If there is a member function/operator template of the form
1.75 -// template<class Expr> mfunc( Expr expr ) ;
1.76 -// some calls are resolved to this even if there are other better matches.
1.77 -// The effect of this bug is that calls to converting ctors and assignments
1.78 -// are incrorrectly sink to this general catch-all member function template as shown above.
1.79 -#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
1.80 -#endif
1.81 -
1.82 -// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
1.83 -// member template of a factory as used in the optional<> implementation.
1.84 -// He proposed this simple fix which is to move the call to apply<> outside
1.85 -// namespace boost.
1.86 -namespace boost_optional_detail
1.87 -{
1.88 - template <class T, class Factory>
1.89 - void construct(Factory const& factory, void* address)
1.90 - {
1.91 - factory.BOOST_NESTED_TEMPLATE apply<T>(address);
1.92 - }
1.93 -}
1.94 -
1.95 -
1.96 -namespace boost {
1.97 -
1.98 -class in_place_factory_base ;
1.99 -class typed_in_place_factory_base ;
1.100 -
1.101 -namespace optional_detail {
1.102 -
1.103 -// This local class is used instead of that in "aligned_storage.hpp"
1.104 -// because I've found the 'official' class to ICE BCB5.5
1.105 -// when some types are used with optional<>
1.106 -// (due to sizeof() passed down as a non-type template parameter)
1.107 -template <class T>
1.108 -class aligned_storage
1.109 -{
1.110 - // Borland ICEs if unnamed unions are used for this!
1.111 - union dummy_u
1.112 - {
1.113 - char data[ sizeof(T) ];
1.114 - BOOST_DEDUCED_TYPENAME type_with_alignment<
1.115 - ::boost::alignment_of<T>::value >::type aligner_;
1.116 - } dummy_ ;
1.117 -
1.118 - public:
1.119 -
1.120 - void const* address() const { return &dummy_.data[0]; }
1.121 - void * address() { return &dummy_.data[0]; }
1.122 -} ;
1.123 -
1.124 -template<class T>
1.125 -struct types_when_isnt_ref
1.126 -{
1.127 - typedef T const& reference_const_type ;
1.128 - typedef T & reference_type ;
1.129 - typedef T const* pointer_const_type ;
1.130 - typedef T * pointer_type ;
1.131 - typedef T const& argument_type ;
1.132 -} ;
1.133 -template<class T>
1.134 -struct types_when_is_ref
1.135 -{
1.136 - typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
1.137 -
1.138 - typedef raw_type& reference_const_type ;
1.139 - typedef raw_type& reference_type ;
1.140 - typedef raw_type* pointer_const_type ;
1.141 - typedef raw_type* pointer_type ;
1.142 - typedef raw_type& argument_type ;
1.143 -} ;
1.144 -
1.145 -struct optional_tag {} ;
1.146 -
1.147 -template<class T>
1.148 -class optional_base : public optional_tag
1.149 -{
1.150 - private :
1.151 -
1.152 - typedef
1.153 -#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.154 - BOOST_DEDUCED_TYPENAME
1.155 -#endif
1.156 - ::boost::detail::make_reference_content<T>::type internal_type ;
1.157 -
1.158 - typedef aligned_storage<internal_type> storage_type ;
1.159 -
1.160 - typedef types_when_isnt_ref<T> types_when_not_ref ;
1.161 - typedef types_when_is_ref<T> types_when_ref ;
1.162 -
1.163 - typedef optional_base<T> this_type ;
1.164 -
1.165 - protected :
1.166 -
1.167 - typedef T value_type ;
1.168 -
1.169 - typedef mpl::true_ is_reference_tag ;
1.170 - typedef mpl::false_ is_not_reference_tag ;
1.171 -
1.172 - typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ;
1.173 -
1.174 - typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
1.175 -
1.176 - typedef bool (this_type::*unspecified_bool_type)() const;
1.177 -
1.178 - typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
1.179 - typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
1.180 - typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
1.181 - typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
1.182 - typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
1.183 -
1.184 - // Creates an optional<T> uninitialized.
1.185 - // No-throw
1.186 - optional_base()
1.187 - :
1.188 - m_initialized(false) {}
1.189 -
1.190 - // Creates an optional<T> uninitialized.
1.191 - // No-throw
1.192 - optional_base ( none_t )
1.193 - :
1.194 - m_initialized(false) {}
1.195 -
1.196 - // Creates an optional<T> initialized with 'val'.
1.197 - // Can throw if T::T(T const&) does
1.198 - optional_base ( argument_type val )
1.199 - :
1.200 - m_initialized(false)
1.201 - {
1.202 - construct(val);
1.203 - }
1.204 -
1.205 - // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
1.206 - // Can throw if T::T(T const&) does
1.207 - optional_base ( bool cond, argument_type val )
1.208 - :
1.209 - m_initialized(false)
1.210 - {
1.211 - if ( cond )
1.212 - construct(val);
1.213 - }
1.214 -
1.215 - // Creates a deep copy of another optional<T>
1.216 - // Can throw if T::T(T const&) does
1.217 - optional_base ( optional_base const& rhs )
1.218 - :
1.219 - m_initialized(false)
1.220 - {
1.221 - if ( rhs.is_initialized() )
1.222 - construct(rhs.get_impl());
1.223 - }
1.224 -
1.225 -
1.226 - // This is used for both converting and in-place constructions.
1.227 - // Derived classes use the 'tag' to select the appropriate
1.228 - // implementation (the correct 'construct()' overload)
1.229 - template<class Expr>
1.230 - explicit optional_base ( Expr const& expr, Expr const* tag )
1.231 - :
1.232 - m_initialized(false)
1.233 - {
1.234 - construct(expr,tag);
1.235 - }
1.236 -
1.237 -
1.238 -
1.239 - // No-throw (assuming T::~T() doesn't)
1.240 - ~optional_base() { destroy() ; }
1.241 -
1.242 - // Assigns from another optional<T> (deep-copies the rhs value)
1.243 - void assign ( optional_base const& rhs )
1.244 - {
1.245 - if (is_initialized())
1.246 - {
1.247 - if ( rhs.is_initialized() )
1.248 - assign_value(rhs.get_impl(), is_reference_predicate() );
1.249 - else destroy();
1.250 - }
1.251 - else
1.252 - {
1.253 - if ( rhs.is_initialized() )
1.254 - construct(rhs.get_impl());
1.255 - }
1.256 - }
1.257 -
1.258 - // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
1.259 - template<class U>
1.260 - void assign ( optional<U> const& rhs )
1.261 - {
1.262 - if (is_initialized())
1.263 - {
1.264 - if ( rhs.is_initialized() )
1.265 - assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
1.266 - else destroy();
1.267 - }
1.268 - else
1.269 - {
1.270 - if ( rhs.is_initialized() )
1.271 - construct(static_cast<value_type>(rhs.get()));
1.272 - }
1.273 - }
1.274 -
1.275 - // Assigns from a T (deep-copies the rhs value)
1.276 - void assign ( argument_type val )
1.277 - {
1.278 - if (is_initialized())
1.279 - assign_value(val, is_reference_predicate() );
1.280 - else construct(val);
1.281 - }
1.282 -
1.283 - // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
1.284 - // No-throw (assuming T::~T() doesn't)
1.285 - void assign ( none_t ) { destroy(); }
1.286 -
1.287 -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
1.288 - template<class Expr>
1.289 - void assign_expr ( Expr const& expr, Expr const* tag )
1.290 - {
1.291 - if (is_initialized())
1.292 - assign_expr_to_initialized(expr,tag);
1.293 - else construct(expr,tag);
1.294 - }
1.295 -#endif
1.296 -
1.297 - public :
1.298 -
1.299 - // Destroys the current value, if any, leaving this UNINITIALIZED
1.300 - // No-throw (assuming T::~T() doesn't)
1.301 - void reset() { destroy(); }
1.302 -
1.303 - // Replaces the current value -if any- with 'val'
1.304 - void reset ( argument_type val ) { assign(val); }
1.305 -
1.306 - // Returns a pointer to the value if this is initialized, otherwise,
1.307 - // returns NULL.
1.308 - // No-throw
1.309 - pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
1.310 - pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; }
1.311 -
1.312 - bool is_initialized() const { return m_initialized ; }
1.313 -
1.314 - protected :
1.315 -
1.316 - void construct ( argument_type val )
1.317 - {
1.318 - new (m_storage.address()) internal_type(val) ;
1.319 - m_initialized = true ;
1.320 - }
1.321 -
1.322 -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
1.323 - // Constructs in-place using the given factory
1.324 - template<class Expr>
1.325 - void construct ( Expr const& factory, in_place_factory_base const* )
1.326 - {
1.327 - BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
1.328 - boost_optional_detail::construct<value_type>(factory, m_storage.address());
1.329 - m_initialized = true ;
1.330 - }
1.331 -
1.332 - // Constructs in-place using the given typed factory
1.333 - template<class Expr>
1.334 - void construct ( Expr const& factory, typed_in_place_factory_base const* )
1.335 - {
1.336 - BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
1.337 - factory.apply(m_storage.address()) ;
1.338 - m_initialized = true ;
1.339 - }
1.340 -
1.341 - template<class Expr>
1.342 - void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
1.343 - {
1.344 - destroy();
1.345 - construct(factory,tag);
1.346 - }
1.347 -
1.348 - // Constructs in-place using the given typed factory
1.349 - template<class Expr>
1.350 - void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
1.351 - {
1.352 - destroy();
1.353 - construct(factory,tag);
1.354 - }
1.355 -#endif
1.356 -
1.357 - // Constructs using any expression implicitely convertible to the single argument
1.358 - // of a one-argument T constructor.
1.359 - // Converting constructions of optional<T> from optional<U> uses this function with
1.360 - // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
1.361 - template<class Expr>
1.362 - void construct ( Expr const& expr, void const* )
1.363 - {
1.364 - new (m_storage.address()) internal_type(expr) ;
1.365 - m_initialized = true ;
1.366 - }
1.367 -
1.368 - // Assigns using a form any expression implicitely convertible to the single argument
1.369 - // of a T's assignment operator.
1.370 - // Converting assignments of optional<T> from optional<U> uses this function with
1.371 - // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
1.372 - template<class Expr>
1.373 - void assign_expr_to_initialized ( Expr const& expr, void const* )
1.374 - {
1.375 - assign_value(expr, is_reference_predicate());
1.376 - }
1.377 -
1.378 -#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
1.379 - // BCB5.64 (and probably lower versions) workaround.
1.380 - // The in-place factories are supported by means of catch-all constructors
1.381 - // and assignment operators (the functions are parameterized in terms of
1.382 - // an arbitrary 'Expr' type)
1.383 - // This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
1.384 - // to the 'Expr'-taking functions even though explicit overloads are present for them.
1.385 - // Thus, the following overload is needed to properly handle the case when the 'lhs'
1.386 - // is another optional.
1.387 - //
1.388 - // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
1.389 - // instead of choosing the wrong overload
1.390 - //
1.391 - // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
1.392 - template<class Expr>
1.393 - void construct ( Expr const& expr, optional_tag const* )
1.394 - {
1.395 - if ( expr.is_initialized() )
1.396 - {
1.397 - // An exception can be thrown here.
1.398 - // It it happens, THIS will be left uninitialized.
1.399 - new (m_storage.address()) internal_type(expr.get()) ;
1.400 - m_initialized = true ;
1.401 - }
1.402 - }
1.403 -#endif
1.404 -
1.405 - void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
1.406 - void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
1.407 -
1.408 - void destroy()
1.409 - {
1.410 - if ( m_initialized )
1.411 - destroy_impl(is_reference_predicate()) ;
1.412 - }
1.413 -
1.414 - unspecified_bool_type safe_bool() const { return m_initialized ? &this_type::is_initialized : 0 ; }
1.415 -
1.416 - reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
1.417 - reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; }
1.418 -
1.419 - pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
1.420 - pointer_type get_ptr_impl() { return cast_ptr(get_object(), is_reference_predicate() ) ; }
1.421 -
1.422 - private :
1.423 -
1.424 - // internal_type can be either T or reference_content<T>
1.425 - internal_type const* get_object() const { return static_cast<internal_type const*>(m_storage.address()); }
1.426 - internal_type * get_object() { return static_cast<internal_type *> (m_storage.address()); }
1.427 -
1.428 - // reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
1.429 - reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
1.430 - reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
1.431 - reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
1.432 - reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
1.433 -
1.434 -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
1.435 - void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
1.436 -#else
1.437 - void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->T::~T() ; m_initialized = false ; }
1.438 -#endif
1.439 -
1.440 - void destroy_impl ( is_reference_tag ) { m_initialized = false ; }
1.441 -
1.442 - // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
1.443 - // Decent compilers should disallow conversions from reference_content<T>* to T*, but just in case,
1.444 - // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
1.445 - pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
1.446 - pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; }
1.447 - pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; }
1.448 - pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; }
1.449 -
1.450 - bool m_initialized ;
1.451 - storage_type m_storage ;
1.452 -} ;
1.453 -
1.454 -} // namespace optional_detail
1.455 -
1.456 -template<class T>
1.457 -class optional : public optional_detail::optional_base<T>
1.458 -{
1.459 - typedef optional_detail::optional_base<T> base ;
1.460 -
1.461 - typedef BOOST_DEDUCED_TYPENAME base::unspecified_bool_type unspecified_bool_type ;
1.462 -
1.463 - public :
1.464 -
1.465 - typedef optional<T> this_type ;
1.466 -
1.467 - typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
1.468 - typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
1.469 - typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
1.470 - typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
1.471 - typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
1.472 - typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
1.473 -
1.474 - // Creates an optional<T> uninitialized.
1.475 - // No-throw
1.476 - optional() : base() {}
1.477 -
1.478 - // Creates an optional<T> uninitialized.
1.479 - // No-throw
1.480 - optional( none_t none_ ) : base(none_) {}
1.481 -
1.482 - // Creates an optional<T> initialized with 'val'.
1.483 - // Can throw if T::T(T const&) does
1.484 - optional ( argument_type val ) : base(val) {}
1.485 -
1.486 - // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
1.487 - // Can throw if T::T(T const&) does
1.488 - optional ( bool cond, argument_type val ) : base(cond,val) {}
1.489 -
1.490 -#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
1.491 - // NOTE: MSVC needs templated versions first
1.492 -
1.493 - // Creates a deep copy of another convertible optional<U>
1.494 - // Requires a valid conversion from U to T.
1.495 - // Can throw if T::T(U const&) does
1.496 - template<class U>
1.497 - explicit optional ( optional<U> const& rhs )
1.498 - :
1.499 - base()
1.500 - {
1.501 - if ( rhs.is_initialized() )
1.502 - this->construct(rhs.get());
1.503 - }
1.504 -#endif
1.505 -
1.506 -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
1.507 - // Creates an optional<T> with an expression which can be either
1.508 - // (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
1.509 - // (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
1.510 - // (c) Any expression implicitely convertible to the single type
1.511 - // of a one-argument T's constructor.
1.512 - // (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
1.513 - // even though explicit overloads are present for these.
1.514 - // Depending on the above some T ctor is called.
1.515 - // Can throw is the resolved T ctor throws.
1.516 - template<class Expr>
1.517 - explicit optional ( Expr const& expr ) : base(expr,&expr) {}
1.518 -#endif
1.519 -
1.520 - // Creates a deep copy of another optional<T>
1.521 - // Can throw if T::T(T const&) does
1.522 - optional ( optional const& rhs ) : base(rhs) {}
1.523 -
1.524 - // No-throw (assuming T::~T() doesn't)
1.525 - ~optional() {}
1.526 -
1.527 -#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
1.528 - // Assigns from an expression. See corresponding constructor.
1.529 - // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
1.530 - template<class Expr>
1.531 - optional& operator= ( Expr expr )
1.532 - {
1.533 - this->assign_expr(expr,&expr);
1.534 - return *this ;
1.535 - }
1.536 -#endif
1.537 -
1.538 -
1.539 -#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
1.540 - // Assigns from another convertible optional<U> (converts && deep-copies the rhs value)
1.541 - // Requires a valid conversion from U to T.
1.542 - // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
1.543 - template<class U>
1.544 - optional& operator= ( optional<U> const& rhs )
1.545 - {
1.546 - this->assign(rhs);
1.547 - return *this ;
1.548 - }
1.549 -#endif
1.550 -
1.551 - // Assigns from another optional<T> (deep-copies the rhs value)
1.552 - // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
1.553 - // (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
1.554 - optional& operator= ( optional const& rhs )
1.555 - {
1.556 - this->assign( rhs ) ;
1.557 - return *this ;
1.558 - }
1.559 -
1.560 - // Assigns from a T (deep-copies the rhs value)
1.561 - // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
1.562 - optional& operator= ( argument_type val )
1.563 - {
1.564 - this->assign( val ) ;
1.565 - return *this ;
1.566 - }
1.567 -
1.568 - // Assigns from a "none"
1.569 - // Which destroys the current value, if any, leaving this UNINITIALIZED
1.570 - // No-throw (assuming T::~T() doesn't)
1.571 - optional& operator= ( none_t none_ )
1.572 - {
1.573 - this->assign( none_ ) ;
1.574 - return *this ;
1.575 - }
1.576 -
1.577 - // Returns a reference to the value if this is initialized, otherwise,
1.578 - // the behaviour is UNDEFINED
1.579 - // No-throw
1.580 - reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
1.581 - reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
1.582 -
1.583 - // Returns a copy of the value if this is initialized, 'v' otherwise
1.584 - reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
1.585 - reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; }
1.586 -
1.587 - // Returns a pointer to the value if this is initialized, otherwise,
1.588 - // the behaviour is UNDEFINED
1.589 - // No-throw
1.590 - pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
1.591 - pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
1.592 -
1.593 - // Returns a reference to the value if this is initialized, otherwise,
1.594 - // the behaviour is UNDEFINED
1.595 - // No-throw
1.596 - reference_const_type operator *() const { return this->get() ; }
1.597 - reference_type operator *() { return this->get() ; }
1.598 -
1.599 - // implicit conversion to "bool"
1.600 - // No-throw
1.601 - operator unspecified_bool_type() const { return this->safe_bool() ; }
1.602 -
1.603 - // This is provided for those compilers which don't like the conversion to bool
1.604 - // on some contexts.
1.605 - bool operator!() const { return !this->is_initialized() ; }
1.606 -} ;
1.607 -
1.608 -// Returns optional<T>(v)
1.609 -template<class T>
1.610 -inline
1.611 -optional<T> make_optional ( T const& v )
1.612 -{
1.613 - return optional<T>(v);
1.614 -}
1.615 -
1.616 -// Returns optional<T>(cond,v)
1.617 -template<class T>
1.618 -inline
1.619 -optional<T> make_optional ( bool cond, T const& v )
1.620 -{
1.621 - return optional<T>(cond,v);
1.622 -}
1.623 -
1.624 -// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
1.625 -// No-throw
1.626 -template<class T>
1.627 -inline
1.628 -BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1.629 -get ( optional<T> const& opt )
1.630 -{
1.631 - return opt.get() ;
1.632 -}
1.633 -
1.634 -template<class T>
1.635 -inline
1.636 -BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1.637 -get ( optional<T>& opt )
1.638 -{
1.639 - return opt.get() ;
1.640 -}
1.641 -
1.642 -// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
1.643 -// No-throw
1.644 -template<class T>
1.645 -inline
1.646 -BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1.647 -get ( optional<T> const* opt )
1.648 -{
1.649 - return opt->get_ptr() ;
1.650 -}
1.651 -
1.652 -template<class T>
1.653 -inline
1.654 -BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1.655 -get ( optional<T>* opt )
1.656 -{
1.657 - return opt->get_ptr() ;
1.658 -}
1.659 -
1.660 -// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
1.661 -// No-throw
1.662 -template<class T>
1.663 -inline
1.664 -BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1.665 -get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
1.666 -{
1.667 - return opt.get_value_or(v) ;
1.668 -}
1.669 -
1.670 -template<class T>
1.671 -inline
1.672 -BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1.673 -get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
1.674 -{
1.675 - return opt.get_value_or(v) ;
1.676 -}
1.677 -
1.678 -// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
1.679 -// No-throw
1.680 -template<class T>
1.681 -inline
1.682 -BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1.683 -get_pointer ( optional<T> const& opt )
1.684 -{
1.685 - return opt.get_ptr() ;
1.686 -}
1.687 -
1.688 -template<class T>
1.689 -inline
1.690 -BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1.691 -get_pointer ( optional<T>& opt )
1.692 -{
1.693 - return opt.get_ptr() ;
1.694 -}
1.695 -
1.696 -// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
1.697 -// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
1.698 -
1.699 -
1.700 -//
1.701 -// optional<T> vs optional<T> cases
1.702 -//
1.703 -
1.704 -template<class T>
1.705 -inline
1.706 -bool operator == ( optional<T> const& x, optional<T> const& y )
1.707 -{ return equal_pointees(x,y); }
1.708 -
1.709 -template<class T>
1.710 -inline
1.711 -bool operator < ( optional<T> const& x, optional<T> const& y )
1.712 -{ return less_pointees(x,y); }
1.713 -
1.714 -template<class T>
1.715 -inline
1.716 -bool operator != ( optional<T> const& x, optional<T> const& y )
1.717 -{ return !( x == y ) ; }
1.718 -
1.719 -template<class T>
1.720 -inline
1.721 -bool operator > ( optional<T> const& x, optional<T> const& y )
1.722 -{ return y < x ; }
1.723 -
1.724 -template<class T>
1.725 -inline
1.726 -bool operator <= ( optional<T> const& x, optional<T> const& y )
1.727 -{ return !( y < x ) ; }
1.728 -
1.729 -template<class T>
1.730 -inline
1.731 -bool operator >= ( optional<T> const& x, optional<T> const& y )
1.732 -{ return !( x < y ) ; }
1.733 -
1.734 -
1.735 -//
1.736 -// optional<T> vs T cases
1.737 -//
1.738 -template<class T>
1.739 -inline
1.740 -bool operator == ( optional<T> const& x, T const& y )
1.741 -{ return equal_pointees(x, optional<T>(y)); }
1.742 -
1.743 -template<class T>
1.744 -inline
1.745 -bool operator < ( optional<T> const& x, T const& y )
1.746 -{ return less_pointees(x, optional<T>(y)); }
1.747 -
1.748 -template<class T>
1.749 -inline
1.750 -bool operator != ( optional<T> const& x, T const& y )
1.751 -{ return !( x == y ) ; }
1.752 -
1.753 -template<class T>
1.754 -inline
1.755 -bool operator > ( optional<T> const& x, T const& y )
1.756 -{ return y < x ; }
1.757 -
1.758 -template<class T>
1.759 -inline
1.760 -bool operator <= ( optional<T> const& x, T const& y )
1.761 -{ return !( y < x ) ; }
1.762 -
1.763 -template<class T>
1.764 -inline
1.765 -bool operator >= ( optional<T> const& x, T const& y )
1.766 -{ return !( x < y ) ; }
1.767 -
1.768 -//
1.769 -// T vs optional<T> cases
1.770 -//
1.771 -
1.772 -template<class T>
1.773 -inline
1.774 -bool operator == ( T const& x, optional<T> const& y )
1.775 -{ return equal_pointees( optional<T>(x), y ); }
1.776 -
1.777 -template<class T>
1.778 -inline
1.779 -bool operator < ( T const& x, optional<T> const& y )
1.780 -{ return less_pointees( optional<T>(x), y ); }
1.781 -
1.782 -template<class T>
1.783 -inline
1.784 -bool operator != ( T const& x, optional<T> const& y )
1.785 -{ return !( x == y ) ; }
1.786 -
1.787 -template<class T>
1.788 -inline
1.789 -bool operator > ( T const& x, optional<T> const& y )
1.790 -{ return y < x ; }
1.791 -
1.792 -template<class T>
1.793 -inline
1.794 -bool operator <= ( T const& x, optional<T> const& y )
1.795 -{ return !( y < x ) ; }
1.796 -
1.797 -template<class T>
1.798 -inline
1.799 -bool operator >= ( T const& x, optional<T> const& y )
1.800 -{ return !( x < y ) ; }
1.801 -
1.802 -
1.803 -//
1.804 -// optional<T> vs none cases
1.805 -//
1.806 -
1.807 -template<class T>
1.808 -inline
1.809 -bool operator == ( optional<T> const& x, none_t )
1.810 -{ return equal_pointees(x, optional<T>() ); }
1.811 -
1.812 -template<class T>
1.813 -inline
1.814 -bool operator < ( optional<T> const& x, none_t )
1.815 -{ return less_pointees(x,optional<T>() ); }
1.816 -
1.817 -template<class T>
1.818 -inline
1.819 -bool operator != ( optional<T> const& x, none_t y )
1.820 -{ return !( x == y ) ; }
1.821 -
1.822 -template<class T>
1.823 -inline
1.824 -bool operator > ( optional<T> const& x, none_t y )
1.825 -{ return y < x ; }
1.826 -
1.827 -template<class T>
1.828 -inline
1.829 -bool operator <= ( optional<T> const& x, none_t y )
1.830 -{ return !( y < x ) ; }
1.831 -
1.832 -template<class T>
1.833 -inline
1.834 -bool operator >= ( optional<T> const& x, none_t y )
1.835 -{ return !( x < y ) ; }
1.836 -
1.837 -//
1.838 -// none vs optional<T> cases
1.839 -//
1.840 -
1.841 -template<class T>
1.842 -inline
1.843 -bool operator == ( none_t x, optional<T> const& y )
1.844 -{ return equal_pointees(optional<T>() ,y); }
1.845 -
1.846 -template<class T>
1.847 -inline
1.848 -bool operator < ( none_t x, optional<T> const& y )
1.849 -{ return less_pointees(optional<T>() ,y); }
1.850 -
1.851 -template<class T>
1.852 -inline
1.853 -bool operator != ( none_t x, optional<T> const& y )
1.854 -{ return !( x == y ) ; }
1.855 -
1.856 -template<class T>
1.857 -inline
1.858 -bool operator > ( none_t x, optional<T> const& y )
1.859 -{ return y < x ; }
1.860 -
1.861 -template<class T>
1.862 -inline
1.863 -bool operator <= ( none_t x, optional<T> const& y )
1.864 -{ return !( y < x ) ; }
1.865 -
1.866 -template<class T>
1.867 -inline
1.868 -bool operator >= ( none_t x, optional<T> const& y )
1.869 -{ return !( x < y ) ; }
1.870 -
1.871 -//
1.872 -// The following swap implementation follows the GCC workaround as found in
1.873 -// "boost/detail/compressed_pair.hpp"
1.874 -//
1.875 -namespace optional_detail {
1.876 -
1.877 -// GCC < 3.2 gets the using declaration at namespace scope (FLC, DWA)
1.878 -#if BOOST_WORKAROUND(__GNUC__, < 3) \
1.879 - || BOOST_WORKAROUND(__GNUC__, == 3) && __GNUC_MINOR__ <= 2
1.880 - using std::swap;
1.881 -#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
1.882 -#endif
1.883 -
1.884 -// optional's swap:
1.885 -// If both are initialized, calls swap(T&, T&). If this swap throws, both will remain initialized but their values are now unspecified.
1.886 -// If only one is initialized, calls U.reset(*I), THEN I.reset().
1.887 -// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I is never reset)
1.888 -// If both are uninitialized, do nothing (no-throw)
1.889 -template<class T>
1.890 -inline
1.891 -void optional_swap ( optional<T>& x, optional<T>& y )
1.892 -{
1.893 - if ( !x && !!y )
1.894 - {
1.895 - x.reset(*y);
1.896 - y.reset();
1.897 - }
1.898 - else if ( !!x && !y )
1.899 - {
1.900 - y.reset(*x);
1.901 - x.reset();
1.902 - }
1.903 - else if ( !!x && !!y )
1.904 - {
1.905 -// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
1.906 -#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
1.907 - // allow for Koenig lookup
1.908 - using std::swap ;
1.909 -#endif
1.910 - swap(*x,*y);
1.911 - }
1.912 -}
1.913 -
1.914 -} // namespace optional_detail
1.915 -
1.916 -template<class T> inline void swap ( optional<T>& x, optional<T>& y )
1.917 -{
1.918 - optional_detail::optional_swap(x,y);
1.919 -}
1.920 -
1.921 -
1.922 -} // namespace boost
1.923 -
1.924 -#endif
1.925 -