forked from boostorg/optional
https://svn.boost.org/svn/boost/trunk ........ r41270 | dgregor | 2007-11-20 21:50:21 -0800 (Tue, 20 Nov 2007) | 1 line Fixes #1456 ........ r41271 | johnmaddock | 2007-11-21 01:39:00 -0800 (Wed, 21 Nov 2007) | 1 line Added super/subscript styling as per boost-docs mailing list discussion. ........ r41272 | johnmaddock | 2007-11-21 01:46:36 -0800 (Wed, 21 Nov 2007) | 1 line Fix << iostream operator for the NTL bindings. ........ r41273 | anthonyw | 2007-11-21 02:44:22 -0800 (Wed, 21 Nov 2007) | 1 line changed platform split to allow bjam to track includes and check dependencies ........ r41274 | schoepflin | 2007-11-21 03:00:18 -0800 (Wed, 21 Nov 2007) | 2 lines Added myself to the platform maintainers file. ........ r41276 | bgubenko | 2007-11-21 03:43:00 -0800 (Wed, 21 Nov 2007) | 1 line fix typo in the marking of function_types library tests ........ r41277 | johnmaddock | 2007-11-21 04:09:28 -0800 (Wed, 21 Nov 2007) | 1 line Change warning suppression, to suppress warnings for VC8 as well. ........ r41278 | johnmaddock | 2007-11-21 06:03:16 -0800 (Wed, 21 Nov 2007) | 1 line Apply warning fix for VC8 and later only: earlier versions warn about the warning suppression :-( ........ r41279 | schoepflin | 2007-11-21 07:21:53 -0800 (Wed, 21 Nov 2007) | 2 lines Marked function_types failures depending on stdcall as expected on Tru64/CXX. ........ r41280 | igaztanaga | 2007-11-21 08:18:29 -0800 (Wed, 21 Nov 2007) | 1 line Added offset_ptr test ........ r41281 | igaztanaga | 2007-11-21 08:19:19 -0800 (Wed, 21 Nov 2007) | 1 line Fixed offset_ptr issues with volatile values. ........ r41282 | igaztanaga | 2007-11-21 08:39:48 -0800 (Wed, 21 Nov 2007) | 1 line Changed precalculated sqrt(2) values selection to use enable_if. ........ r41284 | igaztanaga | 2007-11-21 09:32:20 -0800 (Wed, 21 Nov 2007) | 1 line Added performance Jamfile to the project ........ r41285 | hkaiser | 2007-11-21 09:53:37 -0800 (Wed, 21 Nov 2007) | 1 line Wave: Fixed #line statements in generated files not to contain Windows paths anymore. ........ r41286 | marshall | 2007-11-21 11:20:15 -0800 (Wed, 21 Nov 2007) | 1 line Bug fixes #284, #836, #991 ........ r41287 | grafik | 2007-11-21 11:29:55 -0800 (Wed, 21 Nov 2007) | 1 line Fix search for Boost.Build so that it only finds the approved version. ........ r41288 | djowel | 2007-11-21 14:24:37 -0800 (Wed, 21 Nov 2007) | 1 line updated the master css ........ r41289 | matias | 2007-11-21 20:55:54 -0800 (Wed, 21 Nov 2007) | 1 line Explicit failure markup for Bimap ........ r41290 | matias | 2007-11-21 21:18:38 -0800 (Wed, 21 Nov 2007) | 1 line remove wrong placed typename ........ r41297 | joaquin | 2007-11-21 23:59:28 -0800 (Wed, 21 Nov 2007) | 1 line included an exe filename modifying rule to avoid interference problems with Vista UAC (fixes #1429) ........ r41299 | djowel | 2007-11-22 00:39:46 -0800 (Thu, 22 Nov 2007) | 1 line bug fix ........ r41300 | schoepflin | 2007-11-22 01:32:15 -0800 (Thu, 22 Nov 2007) | 3 lines Marked failures for kolmogorov_max_flow_test and max_flow_test in the graph library as expected for cxx and acc. ........ r41301 | johnmaddock | 2007-11-22 01:59:38 -0800 (Thu, 22 Nov 2007) | 1 line Added try...catch around TSS initialisation. ........ r41302 | johnmaddock | 2007-11-22 02:38:48 -0800 (Thu, 22 Nov 2007) | 1 line Fixes #501 #1334. ........ r41303 | bgubenko | 2007-11-22 03:33:09 -0800 (Thu, 22 Nov 2007) | 1 line fix typo in r41302 causing validation error ........ r41304 | rogeeff | 2007-11-22 11:44:12 -0800 (Thu, 22 Nov 2007) | 1 line Try to make it work in release build ........ r41305 | rogeeff | 2007-11-22 11:56:58 -0800 (Thu, 22 Nov 2007) | 1 line new file ........ r41308 | rogeeff | 2007-11-22 12:56:07 -0800 (Thu, 22 Nov 2007) | 2 lines negative chars test added some statements added to the online_test ........ r41310 | rogeeff | 2007-11-22 13:57:16 -0800 (Thu, 22 Nov 2007) | 1 line issue with class base test cases addressed ........ r41311 | anthonyw | 2007-11-22 14:01:30 -0800 (Thu, 22 Nov 2007) | 1 line Removed thread::self in favour of allowing interruption through a thread::id; no longer requires DuplicateHandle ........ r41312 | rogeeff | 2007-11-22 14:06:59 -0800 (Thu, 22 Nov 2007) | 1 line comments cleanup ........ r41313 | grafik | 2007-11-22 18:57:42 -0800 (Thu, 22 Nov 2007) | 1 line Produce less regression reports to reduce the cycle time for test reporting. ........ r41314 | grafik | 2007-11-22 18:58:14 -0800 (Thu, 22 Nov 2007) | 1 line Produce less regression reports to reduce the cycle time for test reporting. ........ r41315 | joaquin | 2007-11-22 23:57:15 -0800 (Thu, 22 Nov 2007) | 1 line added .exe suffix missing at rev 41297 ........ r41317 | johnmaddock | 2007-11-23 09:05:25 -0800 (Fri, 23 Nov 2007) | 1 line Remove the log files, we don't need these in SVN Trunk. ........ r41318 | grafik | 2007-11-23 12:43:38 -0800 (Fri, 23 Nov 2007) | 1 line Add --skip-script-download option to run.py to avoid repeated regression script downloads. Thanks to _m_ for the changes. ........ r41319 | bemandawes | 2007-11-23 14:55:48 -0800 (Fri, 23 Nov 2007) | 1 line Add the instructions formerly in the (now deleted) runner sub-directory ........ r41320 | anthonyw | 2007-11-23 15:09:36 -0800 (Fri, 23 Nov 2007) | 1 line Integrate TSS with thread data; test to ensure cleanup done for native threads as well as boost::thread-launched threads now runs for pthread API as well as win32 API ........ r41324 | grafik | 2007-11-23 18:16:50 -0800 (Fri, 23 Nov 2007) | 1 line Allow use of "conditional" to multiply a condition that already has the full condition in it. ........ r41325 | igaztanaga | 2007-11-24 01:44:30 -0800 (Sat, 24 Nov 2007) | 1 line Marked msvc-8.0-wm5 as unusable ........ r41326 | niels_dekker | 2007-11-24 03:51:03 -0800 (Sat, 24 Nov 2007) | 1 line Checked the result of value_init test function, hoping to pinpoint exactly for what particular type T value_initialized<T> might fail, on some platforms ........ r41327 | johnmaddock | 2007-11-24 04:25:25 -0800 (Sat, 24 Nov 2007) | 1 line Apply patches for building regex on WinCE see: http://lists.boost.org/Archives/boost/2007/11/130839.php ........ r41328 | bemandawes | 2007-11-24 05:15:03 -0800 (Sat, 24 Nov 2007) | 1 line Bring required compilers list closer into sync with actual testers and list discussion ........ r41330 | bemandawes | 2007-11-24 06:59:08 -0800 (Sat, 24 Nov 2007) | 1 line Remove mingw plus some compilers no longer being tested from required list ........ r41331 | nasonov | 2007-11-24 07:22:52 -0800 (Sat, 24 Nov 2007) | 1 line minor changes ........ r41333 | bemandawes | 2007-11-24 08:39:30 -0800 (Sat, 24 Nov 2007) | 1 line Change long name inspection to follow ISO 9660:1997, thus replacing all length requirements with a single 207 maximum path length requirement. ........ r41338 | garcia | 2007-11-24 10:19:22 -0800 (Sat, 24 Nov 2007) | 2 lines A bunch of review dates have been added. ........ r41339 | johnmaddock | 2007-11-24 10:34:17 -0800 (Sat, 24 Nov 2007) | 1 line Changed meaning of "at_end" needs copy-constructor fix. ........ r41341 | noel_belcourt | 2007-11-24 11:09:56 -0800 (Sat, 24 Nov 2007) | 6 lines Replace mpi wrappers with native pathscale compilers. Fixed how we invoke f77 (pathf90 -f77). Thanks to Alain Miniussi for reporting this. ........ r41342 | igaztanaga | 2007-11-24 11:47:58 -0800 (Sat, 24 Nov 2007) | 1 line Added workaround for systems without SEM_FAILED and semaphores based on filesystem ........ r41343 | rogeeff | 2007-11-24 11:49:24 -0800 (Sat, 24 Nov 2007) | 5 lines switch to nasic_cstring.hpp instead of fwd header added failed expression to the system error system_error is caught and reported in cpp_main.ipp 64 bit compatibility issue in debug.ipp fixed missing headers in algorithm.hpp added ........ r41344 | davedeakins | 2007-11-24 12:30:50 -0800 (Sat, 24 Nov 2007) | 1 line Define the BOOST_NO_SWPRINTF macro for WinCE. WinCE's CRT does not have a conforming swprintf signature. ........ r41348 | igaztanaga | 2007-11-24 16:55:14 -0800 (Sat, 24 Nov 2007) | 1 line Marked pathscale and vacpp as unusable for Interprocess/Intrusive ........ r41350 | davedeakins | 2007-11-24 20:30:02 -0800 (Sat, 24 Nov 2007) | 1 line A few corrections to the WinCE patches ........ r41352 | dave | 2007-11-25 01:02:01 -0800 (Sun, 25 Nov 2007) | 2 lines Attempt SunPro workaround ........ r41353 | guwi17 | 2007-11-25 05:34:20 -0800 (Sun, 25 Nov 2007) | 6 lines - fix and close #1237 - symmetric resize used wrong internal resize method -- Dese und die folgenden Zeilen werden ignoriert -- M symmetric.hpp ........ r41355 | bemandawes | 2007-11-25 05:56:09 -0800 (Sun, 25 Nov 2007) | 1 line Remove extra ) from prior commit ........ r41356 | danieljames | 2007-11-25 06:10:05 -0800 (Sun, 25 Nov 2007) | 2 lines Deleting the BoostCon* files. Fixes #1256 ........ r41357 | bemandawes | 2007-11-25 07:08:28 -0800 (Sun, 25 Nov 2007) | 1 line clear # 1230, mbstate uninitialized ........ r41358 | igaztanaga | 2007-11-25 07:18:04 -0800 (Sun, 25 Nov 2007) | 1 line Marked intel-linux-8.* as unusable for Interprocess and Intrusive ........ r41359 | johnmaddock | 2007-11-25 07:47:58 -0800 (Sun, 25 Nov 2007) | 1 line Oops, previous commit messed up POSIX timing code, now fixed. ........ r41361 | johnmaddock | 2007-11-25 08:26:36 -0800 (Sun, 25 Nov 2007) | 1 line Redirection file. ........ r41362 | grafik | 2007-11-25 09:06:17 -0800 (Sun, 25 Nov 2007) | 1 line Move buildbot support to sandbox until we decide what to do with it. ........ r41363 | grafik | 2007-11-25 09:12:42 -0800 (Sun, 25 Nov 2007) | 1 line Some cleanup of tools documentation. Add boostbook redir file. Delete duplicate time_string.hpp. Repoint regression instructions to web site. ........ r41364 | johnmaddock | 2007-11-25 09:23:25 -0800 (Sun, 25 Nov 2007) | 1 line Fix date. ........ r41378 | bemandawes | 2007-11-25 11:56:10 -0800 (Sun, 25 Nov 2007) | 1 line remove hp_cxx-71_006_tru64 as required. ........ r41380 | grafik | 2007-11-25 12:10:10 -0800 (Sun, 25 Nov 2007) | 1 line Add --build-type option to root build. Two choices possible at the moment "minimal" and "complete". With minimal as the default we only build the common release variant. The old behavior of building many variants is available with "complete". ........ r41381 | fcacciola | 2007-11-25 12:26:14 -0800 (Sun, 25 Nov 2007) | 1 line Cast to base added to avoid a call to the convertir constructor/assignment (see Tickes 1419 and 1420) ........ r41383 | burbelgruff | 2007-11-25 13:16:46 -0800 (Sun, 25 Nov 2007) | 1 line Revert to old sizeof based solution for retrieving the type from a typeof hack. This is in order to overcome problems with the code analysis module introduced in Visual Studio 2005. ........ r41384 | davedeakins | 2007-11-25 13:53:26 -0800 (Sun, 25 Nov 2007) | 1 line Added a primitive tmpnam function for WinCE (which does not supply any kind of tmpnam in its CRT) ........ r41385 | nasonov | 2007-11-25 14:28:16 -0800 (Sun, 25 Nov 2007) | 3 lines Pass unsigned type to lcast_put_unsigned. ........ r41387 | nasonov | 2007-11-25 15:08:50 -0800 (Sun, 25 Nov 2007) | 2 lines Support for string with non-default char_traits and allocator. ........ r41391 | davedeakins | 2007-11-25 22:36:55 -0800 (Sun, 25 Nov 2007) | 1 line Nearly all test for the intrusive library pass on the MSVC8/WM5 platform. ........ r41394 | joaquin | 2007-11-26 03:52:03 -0800 (Mon, 26 Nov 2007) | 1 line added missing traits template arg to a lexical_stream instantiation ........ r41395 | anthonyw | 2007-11-26 04:17:45 -0800 (Mon, 26 Nov 2007) | 1 line workaround for Borland compiler ........ r41396 | anthonyw | 2007-11-26 05:29:15 -0800 (Mon, 26 Nov 2007) | 1 line Don't compare native_handle_t against 0 --- do appropriate checks in create_native_thread for platforms where pthread_t is not comparable ........ r41397 | joaquin | 2007-11-26 05:48:36 -0800 (Mon, 26 Nov 2007) | 1 line ADL-based swap call moved to an utility function (after mistaken attempt at rev 41220 to solve name-hiding issues) ........ r41398 | anthonyw | 2007-11-26 07:44:07 -0800 (Mon, 26 Nov 2007) | 1 line fixed import/export declarations so new once code works with pthread-win32 ........ [SVN r41399]
923 lines
28 KiB
C++
923 lines
28 KiB
C++
// Copyright (C) 2003, 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/lib/optional for documentation.
|
|
//
|
|
// You are welcome to contact the author at:
|
|
// fernando_cacciola@hotmail.com
|
|
//
|
|
#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"
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
|
|
// VC6.0 has the following bug:
|
|
// When a templated assignment operator exist, an implicit conversion
|
|
// constructing an optional<T> is used when assigment of the form:
|
|
// optional<T> opt ; opt = T(...);
|
|
// is compiled.
|
|
// However, optional's ctor is _explicit_ and the assignemt shouldn't compile.
|
|
// Therefore, for VC6.0 templated assignment is disabled.
|
|
//
|
|
#define BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
|
#endif
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
|
// VC7.0 has the following bug:
|
|
// When both a non-template and a template copy-ctor exist
|
|
// and the templated version is made 'explicit', the explicit is also
|
|
// given to the non-templated version, making the class non-implicitely-copyable.
|
|
//
|
|
#define BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
|
#endif
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
|
|
// AFAICT only VC7.1 correctly resolves the overload set
|
|
// that includes the in-place factory taking functions,
|
|
// so for the other VC versions, in-place factory support
|
|
// is disabled
|
|
#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
|
#endif
|
|
|
|
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
|
|
// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
|
|
#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
|
#endif
|
|
|
|
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
|
|
&& BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
|
|
// BCB (up to 5.64) has the following bug:
|
|
// If there is a member function/operator template of the form
|
|
// template<class Expr> mfunc( Expr expr ) ;
|
|
// some calls are resolved to this even if there are other better matches.
|
|
// The effect of this bug is that calls to converting ctors and assignments
|
|
// are incrorrectly sink to this general catch-all member function template as shown above.
|
|
#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
|
|
#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
|
|
// namespace boost.
|
|
namespace boost_optional_detail
|
|
{
|
|
template <class T, class Factory>
|
|
void construct(Factory const& factory, void* address)
|
|
{
|
|
factory.BOOST_NESTED_TEMPLATE apply<T>(address);
|
|
}
|
|
}
|
|
|
|
|
|
namespace boost {
|
|
|
|
class in_place_factory_base ;
|
|
class typed_in_place_factory_base ;
|
|
|
|
namespace optional_detail {
|
|
|
|
// This local class is used instead of that in "aligned_storage.hpp"
|
|
// because I've found the 'official' class to ICE BCB5.5
|
|
// when some types are used with optional<>
|
|
// (due to sizeof() passed down as a non-type template parameter)
|
|
template <class T>
|
|
class aligned_storage
|
|
{
|
|
// Borland ICEs if unnamed unions are used for this!
|
|
union dummy_u
|
|
{
|
|
char data[ sizeof(T) ];
|
|
BOOST_DEDUCED_TYPENAME type_with_alignment<
|
|
::boost::alignment_of<T>::value >::type aligner_;
|
|
} dummy_ ;
|
|
|
|
public:
|
|
|
|
void const* address() const { return &dummy_.data[0]; }
|
|
void * address() { return &dummy_.data[0]; }
|
|
} ;
|
|
|
|
template<class T>
|
|
struct types_when_isnt_ref
|
|
{
|
|
typedef T const& reference_const_type ;
|
|
typedef T & reference_type ;
|
|
typedef T const* pointer_const_type ;
|
|
typedef T * pointer_type ;
|
|
typedef T const& argument_type ;
|
|
} ;
|
|
template<class T>
|
|
struct types_when_is_ref
|
|
{
|
|
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
|
|
|
|
typedef raw_type& reference_const_type ;
|
|
typedef raw_type& reference_type ;
|
|
typedef raw_type* pointer_const_type ;
|
|
typedef raw_type* pointer_type ;
|
|
typedef raw_type& argument_type ;
|
|
} ;
|
|
|
|
struct optional_tag {} ;
|
|
|
|
template<class T>
|
|
class optional_base : public optional_tag
|
|
{
|
|
private :
|
|
|
|
typedef
|
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
|
BOOST_DEDUCED_TYPENAME
|
|
#endif
|
|
::boost::detail::make_reference_content<T>::type internal_type ;
|
|
|
|
typedef aligned_storage<internal_type> storage_type ;
|
|
|
|
typedef types_when_isnt_ref<T> types_when_not_ref ;
|
|
typedef types_when_is_ref<T> types_when_ref ;
|
|
|
|
typedef optional_base<T> this_type ;
|
|
|
|
protected :
|
|
|
|
typedef T value_type ;
|
|
|
|
typedef mpl::true_ is_reference_tag ;
|
|
typedef mpl::false_ is_not_reference_tag ;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
|
|
|
|
typedef bool (this_type::*unspecified_bool_type)() const;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
|
|
|
|
// Creates an optional<T> uninitialized.
|
|
// No-throw
|
|
optional_base()
|
|
:
|
|
m_initialized(false) {}
|
|
|
|
// Creates an optional<T> uninitialized.
|
|
// No-throw
|
|
optional_base ( none_t )
|
|
:
|
|
m_initialized(false) {}
|
|
|
|
// Creates an optional<T> initialized with 'val'.
|
|
// Can throw if T::T(T const&) does
|
|
optional_base ( argument_type val )
|
|
:
|
|
m_initialized(false)
|
|
{
|
|
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 )
|
|
:
|
|
m_initialized(false)
|
|
{
|
|
if ( cond )
|
|
construct(val);
|
|
}
|
|
|
|
// Creates a deep copy of another optional<T>
|
|
// Can throw if T::T(T const&) does
|
|
optional_base ( optional_base const& rhs )
|
|
:
|
|
m_initialized(false)
|
|
{
|
|
if ( rhs.is_initialized() )
|
|
construct(rhs.get_impl());
|
|
}
|
|
|
|
|
|
// This is used for both converting and in-place constructions.
|
|
// Derived classes use the 'tag' to select the appropriate
|
|
// implementation (the correct 'construct()' overload)
|
|
template<class Expr>
|
|
explicit optional_base ( Expr const& expr, Expr const* tag )
|
|
:
|
|
m_initialized(false)
|
|
{
|
|
construct(expr,tag);
|
|
}
|
|
|
|
|
|
|
|
// No-throw (assuming T::~T() doesn't)
|
|
~optional_base() { destroy() ; }
|
|
|
|
// Assigns from another optional<T> (deep-copies the rhs value)
|
|
void assign ( optional_base const& rhs )
|
|
{
|
|
if (is_initialized())
|
|
{
|
|
if ( rhs.is_initialized() )
|
|
assign_value(rhs.get_impl(), is_reference_predicate() );
|
|
else destroy();
|
|
}
|
|
else
|
|
{
|
|
if ( rhs.is_initialized() )
|
|
construct(rhs.get_impl());
|
|
}
|
|
}
|
|
|
|
// Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
|
|
template<class U>
|
|
void assign ( optional<U> const& rhs )
|
|
{
|
|
if (is_initialized())
|
|
{
|
|
if ( rhs.is_initialized() )
|
|
assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
|
|
else destroy();
|
|
}
|
|
else
|
|
{
|
|
if ( rhs.is_initialized() )
|
|
construct(static_cast<value_type>(rhs.get()));
|
|
}
|
|
}
|
|
|
|
// Assigns from a T (deep-copies the rhs value)
|
|
void assign ( argument_type val )
|
|
{
|
|
if (is_initialized())
|
|
assign_value(val, is_reference_predicate() );
|
|
else construct(val);
|
|
}
|
|
|
|
// Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
|
|
// No-throw (assuming T::~T() doesn't)
|
|
void assign ( none_t ) { destroy(); }
|
|
|
|
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
|
template<class Expr>
|
|
void assign_expr ( Expr const& expr, Expr const* tag )
|
|
{
|
|
if (is_initialized())
|
|
assign_expr_to_initialized(expr,tag);
|
|
else construct(expr,tag);
|
|
}
|
|
#endif
|
|
|
|
public :
|
|
|
|
// Destroys the current value, if any, leaving this UNINITIALIZED
|
|
// No-throw (assuming T::~T() doesn't)
|
|
void reset() { destroy(); }
|
|
|
|
// Replaces the current value -if any- with 'val'
|
|
void reset ( argument_type val ) { assign(val); }
|
|
|
|
// Returns a pointer to the value if this is initialized, otherwise,
|
|
// returns NULL.
|
|
// No-throw
|
|
pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
|
|
pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; }
|
|
|
|
bool is_initialized() const { return m_initialized ; }
|
|
|
|
protected :
|
|
|
|
void construct ( argument_type val )
|
|
{
|
|
new (m_storage.address()) internal_type(val) ;
|
|
m_initialized = true ;
|
|
}
|
|
|
|
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
|
// Constructs in-place using the given factory
|
|
template<class Expr>
|
|
void construct ( Expr const& factory, in_place_factory_base const* )
|
|
{
|
|
BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
|
|
boost_optional_detail::construct<value_type>(factory, m_storage.address());
|
|
m_initialized = true ;
|
|
}
|
|
|
|
// Constructs in-place using the given typed factory
|
|
template<class Expr>
|
|
void construct ( Expr const& factory, typed_in_place_factory_base const* )
|
|
{
|
|
BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
|
|
factory.apply(m_storage.address()) ;
|
|
m_initialized = true ;
|
|
}
|
|
|
|
template<class Expr>
|
|
void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
|
|
{
|
|
destroy();
|
|
construct(factory,tag);
|
|
}
|
|
|
|
// Constructs in-place using the given typed factory
|
|
template<class Expr>
|
|
void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
|
|
{
|
|
destroy();
|
|
construct(factory,tag);
|
|
}
|
|
#endif
|
|
|
|
// Constructs using any expression implicitely convertible to the single argument
|
|
// of a one-argument T constructor.
|
|
// Converting constructions of optional<T> from optional<U> uses this function with
|
|
// 'Expr' being of type 'U' and relying on a converting constructor of T from U.
|
|
template<class Expr>
|
|
void construct ( Expr const& expr, void const* )
|
|
{
|
|
new (m_storage.address()) internal_type(expr) ;
|
|
m_initialized = true ;
|
|
}
|
|
|
|
// Assigns using a form any expression implicitely convertible to the single argument
|
|
// of a T's assignment operator.
|
|
// Converting assignments of optional<T> from optional<U> uses this function with
|
|
// 'Expr' being of type 'U' and relying on a converting assignment of T from U.
|
|
template<class Expr>
|
|
void assign_expr_to_initialized ( Expr const& expr, void const* )
|
|
{
|
|
assign_value(expr, is_reference_predicate());
|
|
}
|
|
|
|
#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
|
|
// BCB5.64 (and probably lower versions) workaround.
|
|
// The in-place factories are supported by means of catch-all constructors
|
|
// and assignment operators (the functions are parameterized in terms of
|
|
// an arbitrary 'Expr' type)
|
|
// This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
|
|
// to the 'Expr'-taking functions even though explicit overloads are present for them.
|
|
// Thus, the following overload is needed to properly handle the case when the 'lhs'
|
|
// is another optional.
|
|
//
|
|
// For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
|
|
// instead of choosing the wrong overload
|
|
//
|
|
// Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
|
|
template<class Expr>
|
|
void construct ( Expr const& expr, optional_tag const* )
|
|
{
|
|
if ( expr.is_initialized() )
|
|
{
|
|
// An exception can be thrown here.
|
|
// It it happens, THIS will be left uninitialized.
|
|
new (m_storage.address()) internal_type(expr.get()) ;
|
|
m_initialized = true ;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
|
|
void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
|
|
|
|
void destroy()
|
|
{
|
|
if ( m_initialized )
|
|
destroy_impl(is_reference_predicate()) ;
|
|
}
|
|
|
|
unspecified_bool_type safe_bool() const { return m_initialized ? &this_type::is_initialized : 0 ; }
|
|
|
|
reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
|
|
reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; }
|
|
|
|
pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
|
|
pointer_type get_ptr_impl() { return cast_ptr(get_object(), is_reference_predicate() ) ; }
|
|
|
|
private :
|
|
|
|
// internal_type can be either T or reference_content<T>
|
|
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()); }
|
|
|
|
// 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 ; }
|
|
reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; }
|
|
reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; }
|
|
reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; }
|
|
|
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
|
|
void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
|
|
#else
|
|
void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->T::~T() ; m_initialized = false ; }
|
|
#endif
|
|
|
|
void destroy_impl ( is_reference_tag ) { m_initialized = false ; }
|
|
|
|
// If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
|
|
// Decent compilers should disallow conversions from reference_content<T>* to T*, but just in case,
|
|
// the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
|
|
pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
|
|
pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; }
|
|
pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; }
|
|
pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; }
|
|
|
|
bool m_initialized ;
|
|
storage_type m_storage ;
|
|
} ;
|
|
|
|
} // namespace optional_detail
|
|
|
|
template<class T>
|
|
class optional : public optional_detail::optional_base<T>
|
|
{
|
|
typedef optional_detail::optional_base<T> base ;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME base::unspecified_bool_type unspecified_bool_type ;
|
|
|
|
public :
|
|
|
|
typedef optional<T> this_type ;
|
|
|
|
typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
|
|
typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
|
|
|
|
// Creates an optional<T> uninitialized.
|
|
// No-throw
|
|
optional() : base() {}
|
|
|
|
// Creates an optional<T> uninitialized.
|
|
// No-throw
|
|
optional( none_t none_ ) : base(none_) {}
|
|
|
|
// Creates an optional<T> initialized with 'val'.
|
|
// Can throw if T::T(T const&) does
|
|
optional ( argument_type val ) : base(val) {}
|
|
|
|
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
|
|
// Can throw if T::T(T const&) does
|
|
optional ( bool cond, argument_type val ) : base(cond,val) {}
|
|
|
|
#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
|
// NOTE: MSVC needs templated versions first
|
|
|
|
// Creates a deep copy of another convertible optional<U>
|
|
// Requires a valid conversion from U to T.
|
|
// Can throw if T::T(U const&) does
|
|
template<class U>
|
|
explicit optional ( optional<U> const& rhs )
|
|
:
|
|
base()
|
|
{
|
|
if ( rhs.is_initialized() )
|
|
this->construct(rhs.get());
|
|
}
|
|
#endif
|
|
|
|
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
|
// Creates an optional<T> with an expression which can be either
|
|
// (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
|
|
// (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
|
|
// (c) Any expression implicitely convertible to the single type
|
|
// of a one-argument T's constructor.
|
|
// (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
|
|
// even though explicit overloads are present for these.
|
|
// 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) {}
|
|
#endif
|
|
|
|
// Creates a deep copy of another optional<T>
|
|
// Can throw if T::T(T const&) does
|
|
optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
|
|
|
|
// No-throw (assuming T::~T() doesn't)
|
|
~optional() {}
|
|
|
|
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
|
|
// 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 )
|
|
{
|
|
this->assign_expr(expr,&expr);
|
|
return *this ;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
|
// Assigns from another convertible optional<U> (converts && deep-copies the rhs value)
|
|
// Requires a valid conversion from U to T.
|
|
// Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
|
|
template<class U>
|
|
optional& operator= ( optional<U> const& rhs )
|
|
{
|
|
this->assign(rhs);
|
|
return *this ;
|
|
}
|
|
#endif
|
|
|
|
// Assigns from another optional<T> (deep-copies the rhs value)
|
|
// Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
|
|
// (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( static_cast<base const&>(rhs) ) ;
|
|
return *this ;
|
|
}
|
|
|
|
// Assigns from a T (deep-copies the rhs value)
|
|
// Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
|
|
optional& operator= ( argument_type val )
|
|
{
|
|
this->assign( val ) ;
|
|
return *this ;
|
|
}
|
|
|
|
// Assigns from a "none"
|
|
// Which destroys the current value, if any, leaving this UNINITIALIZED
|
|
// No-throw (assuming T::~T() doesn't)
|
|
optional& operator= ( none_t none_ )
|
|
{
|
|
this->assign( none_ ) ;
|
|
return *this ;
|
|
}
|
|
|
|
// Returns a reference to the value if this is initialized, otherwise,
|
|
// the behaviour is UNDEFINED
|
|
// No-throw
|
|
reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
|
|
reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
|
|
|
|
// 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
|
|
pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
|
|
pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
|
|
|
|
// Returns a reference to the value if this is initialized, otherwise,
|
|
// the behaviour is UNDEFINED
|
|
// No-throw
|
|
reference_const_type operator *() const { return this->get() ; }
|
|
reference_type operator *() { return this->get() ; }
|
|
|
|
// implicit conversion to "bool"
|
|
// 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() ; }
|
|
} ;
|
|
|
|
// Returns optional<T>(v)
|
|
template<class T>
|
|
inline
|
|
optional<T> make_optional ( T const& v )
|
|
{
|
|
return optional<T>(v);
|
|
}
|
|
|
|
// Returns optional<T>(cond,v)
|
|
template<class T>
|
|
inline
|
|
optional<T> make_optional ( bool cond, T const& v )
|
|
{
|
|
return optional<T>(cond,v);
|
|
}
|
|
|
|
// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
|
|
// No-throw
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
|
|
get ( optional<T> const& opt )
|
|
{
|
|
return opt.get() ;
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::reference_type
|
|
get ( optional<T>& opt )
|
|
{
|
|
return opt.get() ;
|
|
}
|
|
|
|
// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
|
|
// No-throw
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
|
|
get ( optional<T> const* opt )
|
|
{
|
|
return opt->get_ptr() ;
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
|
|
get ( optional<T>* opt )
|
|
{
|
|
return opt->get_ptr() ;
|
|
}
|
|
|
|
// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
|
|
// No-throw
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
|
|
get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
|
|
{
|
|
return opt.get_value_or(v) ;
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::reference_type
|
|
get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
|
|
{
|
|
return opt.get_value_or(v) ;
|
|
}
|
|
|
|
// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
|
|
// No-throw
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
|
|
get_pointer ( optional<T> const& opt )
|
|
{
|
|
return opt.get_ptr() ;
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
|
|
get_pointer ( optional<T>& opt )
|
|
{
|
|
return opt.get_ptr() ;
|
|
}
|
|
|
|
// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
|
|
// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
|
|
|
|
|
|
//
|
|
// optional<T> vs optional<T> cases
|
|
//
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator == ( optional<T> const& x, optional<T> const& y )
|
|
{ return equal_pointees(x,y); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator < ( optional<T> const& x, optional<T> const& y )
|
|
{ return less_pointees(x,y); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator != ( optional<T> const& x, optional<T> const& y )
|
|
{ return !( x == y ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator > ( optional<T> const& x, optional<T> const& y )
|
|
{ return y < x ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator <= ( optional<T> const& x, optional<T> const& y )
|
|
{ return !( y < x ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator >= ( optional<T> const& x, optional<T> const& y )
|
|
{ return !( x < y ) ; }
|
|
|
|
|
|
//
|
|
// optional<T> vs T cases
|
|
//
|
|
template<class T>
|
|
inline
|
|
bool operator == ( optional<T> const& x, T const& y )
|
|
{ return equal_pointees(x, optional<T>(y)); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator < ( optional<T> const& x, T const& y )
|
|
{ return less_pointees(x, optional<T>(y)); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator != ( optional<T> const& x, T const& y )
|
|
{ return !( x == y ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator > ( optional<T> const& x, T const& y )
|
|
{ return y < x ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator <= ( optional<T> const& x, T const& y )
|
|
{ return !( y < x ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator >= ( optional<T> const& x, T const& y )
|
|
{ return !( x < y ) ; }
|
|
|
|
//
|
|
// T vs optional<T> cases
|
|
//
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator == ( T const& x, optional<T> const& y )
|
|
{ return equal_pointees( optional<T>(x), y ); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator < ( T const& x, optional<T> const& y )
|
|
{ return less_pointees( optional<T>(x), y ); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator != ( T const& x, optional<T> const& y )
|
|
{ return !( x == y ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator > ( T const& x, optional<T> const& y )
|
|
{ return y < x ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator <= ( T const& x, optional<T> const& y )
|
|
{ return !( y < x ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator >= ( T const& x, optional<T> const& y )
|
|
{ return !( x < y ) ; }
|
|
|
|
|
|
//
|
|
// optional<T> vs none cases
|
|
//
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator == ( optional<T> const& x, none_t )
|
|
{ return equal_pointees(x, optional<T>() ); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator < ( optional<T> const& x, none_t )
|
|
{ return less_pointees(x,optional<T>() ); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator != ( optional<T> const& x, none_t y )
|
|
{ return !( x == y ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator > ( optional<T> const& x, none_t y )
|
|
{ return y < x ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator <= ( optional<T> const& x, none_t y )
|
|
{ return !( y < x ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator >= ( optional<T> const& x, none_t y )
|
|
{ return !( x < y ) ; }
|
|
|
|
//
|
|
// none vs optional<T> cases
|
|
//
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator == ( none_t x, optional<T> const& y )
|
|
{ return equal_pointees(optional<T>() ,y); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator < ( none_t x, optional<T> const& y )
|
|
{ return less_pointees(optional<T>() ,y); }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator != ( none_t x, optional<T> const& y )
|
|
{ return !( x == y ) ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator > ( none_t x, optional<T> const& y )
|
|
{ return y < x ; }
|
|
|
|
template<class T>
|
|
inline
|
|
bool operator <= ( none_t x, optional<T> const& y )
|
|
{ return !( y < x ) ; }
|
|
|
|
template<class T>
|
|
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
|
|
|
|
// 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 )
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
} // namespace optional_detail
|
|
|
|
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
|
{
|
|
optional_detail::optional_swap(x,y);
|
|
}
|
|
|
|
|
|
} // namespace boost
|
|
|
|
#endif
|
|
|