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