epoc32/include/stdapis/boost/optional.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 epoc32/include/stdapis/boost/optional/optional.hpp@2fe1408b6811
child 4 837f303aceeb
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
williamr@2
     2
//
williamr@2
     3
// Use, modification, and distribution is subject to the Boost Software
williamr@2
     4
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     5
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     6
//
williamr@2
     7
// See http://www.boost.org/lib/optional for documentation.
williamr@2
     8
//
williamr@2
     9
// You are welcome to contact the author at:
williamr@2
    10
//  fernando_cacciola@hotmail.com
williamr@2
    11
//
williamr@2
    12
#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
williamr@2
    13
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
williamr@2
    14
williamr@2
    15
#include<new>
williamr@2
    16
#include<algorithm>
williamr@2
    17
williamr@2
    18
#include "boost/config.hpp"
williamr@2
    19
#include "boost/assert.hpp"
williamr@2
    20
#include "boost/type.hpp"
williamr@2
    21
#include "boost/type_traits/alignment_of.hpp"
williamr@2
    22
#include "boost/type_traits/type_with_alignment.hpp"
williamr@2
    23
#include "boost/type_traits/remove_reference.hpp"
williamr@2
    24
#include "boost/type_traits/is_reference.hpp"
williamr@2
    25
#include "boost/mpl/if.hpp"
williamr@2
    26
#include "boost/mpl/bool.hpp"
williamr@2
    27
#include "boost/mpl/not.hpp"
williamr@2
    28
#include "boost/detail/reference_content.hpp"
williamr@2
    29
#include "boost/none.hpp"
williamr@2
    30
#include "boost/utility/compare_pointees.hpp"
williamr@2
    31
williamr@2
    32
#include "boost/optional/optional_fwd.hpp"
williamr@2
    33
williamr@2
    34
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
williamr@2
    35
// VC6.0 has the following bug:
williamr@2
    36
//   When a templated assignment operator exist, an implicit conversion
williamr@2
    37
//   constructing an optional<T> is used when assigment of the form:
williamr@2
    38
//     optional<T> opt ; opt = T(...);
williamr@2
    39
//   is compiled.
williamr@2
    40
//   However, optional's ctor is _explicit_ and the assignemt shouldn't compile.
williamr@2
    41
//   Therefore, for VC6.0 templated assignment is disabled.
williamr@2
    42
//
williamr@2
    43
#define BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
williamr@2
    44
#endif
williamr@2
    45
williamr@2
    46
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
williamr@2
    47
// VC7.0 has the following bug:
williamr@2
    48
//   When both a non-template and a template copy-ctor exist
williamr@2
    49
//   and the templated version is made 'explicit', the explicit is also
williamr@2
    50
//   given to the non-templated version, making the class non-implicitely-copyable.
williamr@2
    51
//
williamr@2
    52
#define BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
williamr@2
    53
#endif
williamr@2
    54
williamr@2
    55
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
williamr@2
    56
// AFAICT only VC7.1 correctly resolves the overload set
williamr@2
    57
// that includes the in-place factory taking functions,
williamr@2
    58
// so for the other VC versions, in-place factory support
williamr@2
    59
// is disabled
williamr@2
    60
#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
williamr@2
    61
#endif
williamr@2
    62
williamr@2
    63
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
williamr@2
    64
// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
williamr@2
    65
#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
williamr@2
    66
#endif
williamr@2
    67
williamr@2
    68
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
williamr@2
    69
    && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
williamr@2
    70
// BCB (up to 5.64) has the following bug:
williamr@2
    71
//   If there is a member function/operator template of the form
williamr@2
    72
//     template<class Expr> mfunc( Expr expr ) ;
williamr@2
    73
//   some calls are resolved to this even if there are other better matches.
williamr@2
    74
//   The effect of this bug is that calls to converting ctors and assignments
williamr@2
    75
//   are incrorrectly sink to this general catch-all member function template as shown above.
williamr@2
    76
#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
williamr@2
    77
#endif
williamr@2
    78
williamr@2
    79
// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
williamr@2
    80
// member template of a factory as used in the optional<> implementation.
williamr@2
    81
// He proposed this simple fix which is to move the call to apply<> outside
williamr@2
    82
// namespace boost.
williamr@2
    83
namespace boost_optional_detail
williamr@2
    84
{
williamr@2
    85
  template <class T, class Factory>
williamr@2
    86
  void construct(Factory const& factory, void* address)
williamr@2
    87
  {
williamr@2
    88
    factory.BOOST_NESTED_TEMPLATE apply<T>(address);
williamr@2
    89
  }
williamr@2
    90
}
williamr@2
    91
williamr@2
    92
williamr@2
    93
namespace boost {
williamr@2
    94
williamr@2
    95
class in_place_factory_base ;
williamr@2
    96
class typed_in_place_factory_base ;
williamr@2
    97
williamr@2
    98
namespace optional_detail {
williamr@2
    99
williamr@2
   100
// This local class is used instead of that in "aligned_storage.hpp"
williamr@2
   101
// because I've found the 'official' class to ICE BCB5.5
williamr@2
   102
// when some types are used with optional<>
williamr@2
   103
// (due to sizeof() passed down as a non-type template parameter)
williamr@2
   104
template <class T>
williamr@2
   105
class aligned_storage
williamr@2
   106
{
williamr@2
   107
    // Borland ICEs if unnamed unions are used for this!
williamr@2
   108
    union dummy_u
williamr@2
   109
    {
williamr@2
   110
        char data[ sizeof(T) ];
williamr@2
   111
        BOOST_DEDUCED_TYPENAME type_with_alignment<
williamr@2
   112
          ::boost::alignment_of<T>::value >::type aligner_;
williamr@2
   113
    } dummy_ ;
williamr@2
   114
williamr@2
   115
  public:
williamr@2
   116
williamr@2
   117
    void const* address() const { return &dummy_.data[0]; }
williamr@2
   118
    void      * address()       { return &dummy_.data[0]; }
williamr@2
   119
} ;
williamr@2
   120
williamr@2
   121
template<class T>
williamr@2
   122
struct types_when_isnt_ref
williamr@2
   123
{
williamr@2
   124
  typedef T const& reference_const_type ;
williamr@2
   125
  typedef T &      reference_type ;
williamr@2
   126
  typedef T const* pointer_const_type ;
williamr@2
   127
  typedef T *      pointer_type ;
williamr@2
   128
  typedef T const& argument_type ;
williamr@2
   129
} ;
williamr@2
   130
template<class T>
williamr@2
   131
struct types_when_is_ref
williamr@2
   132
{
williamr@2
   133
  typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
williamr@2
   134
williamr@2
   135
  typedef raw_type& reference_const_type ;
williamr@2
   136
  typedef raw_type& reference_type ;
williamr@2
   137
  typedef raw_type* pointer_const_type ;
williamr@2
   138
  typedef raw_type* pointer_type ;
williamr@2
   139
  typedef raw_type& argument_type ;
williamr@2
   140
} ;
williamr@2
   141
williamr@2
   142
struct optional_tag {} ;
williamr@2
   143
williamr@2
   144
template<class T>
williamr@2
   145
class optional_base : public optional_tag
williamr@2
   146
{
williamr@2
   147
  private :
williamr@2
   148
williamr@2
   149
    typedef
williamr@2
   150
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
williamr@2
   151
    BOOST_DEDUCED_TYPENAME
williamr@2
   152
#endif 
williamr@2
   153
    ::boost::detail::make_reference_content<T>::type internal_type ;
williamr@2
   154
williamr@2
   155
    typedef aligned_storage<internal_type> storage_type ;
williamr@2
   156
williamr@2
   157
    typedef types_when_isnt_ref<T> types_when_not_ref ;
williamr@2
   158
    typedef types_when_is_ref<T>   types_when_ref   ;
williamr@2
   159
williamr@2
   160
    typedef optional_base<T> this_type ;
williamr@2
   161
williamr@2
   162
  protected :
williamr@2
   163
williamr@2
   164
    typedef T value_type ;
williamr@2
   165
williamr@2
   166
    typedef mpl::true_  is_reference_tag ;
williamr@2
   167
    typedef mpl::false_ is_not_reference_tag ;
williamr@2
   168
williamr@2
   169
    typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ;
williamr@2
   170
williamr@2
   171
    typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
williamr@2
   172
williamr@2
   173
    typedef bool (this_type::*unspecified_bool_type)() const;
williamr@2
   174
williamr@2
   175
    typedef BOOST_DEDUCED_TYPENAME types::reference_type       reference_type ;
williamr@2
   176
    typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
williamr@2
   177
    typedef BOOST_DEDUCED_TYPENAME types::pointer_type         pointer_type ;
williamr@2
   178
    typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type   pointer_const_type ;
williamr@2
   179
    typedef BOOST_DEDUCED_TYPENAME types::argument_type        argument_type ;
williamr@2
   180
williamr@2
   181
    // Creates an optional<T> uninitialized.
williamr@2
   182
    // No-throw
williamr@2
   183
    optional_base()
williamr@2
   184
      :
williamr@2
   185
      m_initialized(false) {}
williamr@2
   186
williamr@2
   187
    // Creates an optional<T> uninitialized.
williamr@2
   188
    // No-throw
williamr@2
   189
    optional_base ( none_t )
williamr@2
   190
      :
williamr@2
   191
      m_initialized(false) {}
williamr@2
   192
williamr@2
   193
    // Creates an optional<T> initialized with 'val'.
williamr@2
   194
    // Can throw if T::T(T const&) does
williamr@2
   195
    optional_base ( argument_type val )
williamr@2
   196
      :
williamr@2
   197
      m_initialized(false)
williamr@2
   198
    {
williamr@2
   199
      construct(val);
williamr@2
   200
    }
williamr@2
   201
    
williamr@2
   202
    // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
williamr@2
   203
    // Can throw if T::T(T const&) does
williamr@2
   204
    optional_base ( bool cond, argument_type val )
williamr@2
   205
      :
williamr@2
   206
      m_initialized(false)
williamr@2
   207
    {
williamr@2
   208
      if ( cond )
williamr@2
   209
        construct(val);
williamr@2
   210
    }
williamr@2
   211
williamr@2
   212
    // Creates a deep copy of another optional<T>
williamr@2
   213
    // Can throw if T::T(T const&) does
williamr@2
   214
    optional_base ( optional_base const& rhs )
williamr@2
   215
      :
williamr@2
   216
      m_initialized(false)
williamr@2
   217
    {
williamr@2
   218
      if ( rhs.is_initialized() )
williamr@2
   219
        construct(rhs.get_impl());
williamr@2
   220
    }
williamr@2
   221
williamr@2
   222
williamr@2
   223
    // This is used for both converting and in-place constructions.
williamr@2
   224
    // Derived classes use the 'tag' to select the appropriate
williamr@2
   225
    // implementation (the correct 'construct()' overload)
williamr@2
   226
    template<class Expr>
williamr@2
   227
    explicit optional_base ( Expr const& expr, Expr const* tag )
williamr@2
   228
      :
williamr@2
   229
      m_initialized(false)
williamr@2
   230
    {
williamr@2
   231
      construct(expr,tag);
williamr@2
   232
    }
williamr@2
   233
williamr@2
   234
williamr@2
   235
williamr@2
   236
    // No-throw (assuming T::~T() doesn't)
williamr@2
   237
    ~optional_base() { destroy() ; }
williamr@2
   238
williamr@2
   239
    // Assigns from another optional<T> (deep-copies the rhs value)
williamr@2
   240
    void assign ( optional_base const& rhs )
williamr@2
   241
    {
williamr@2
   242
      if (is_initialized())
williamr@2
   243
      {
williamr@2
   244
        if ( rhs.is_initialized() )
williamr@2
   245
             assign_value(rhs.get_impl(), is_reference_predicate() );
williamr@2
   246
        else destroy();
williamr@2
   247
      }
williamr@2
   248
      else
williamr@2
   249
      {
williamr@2
   250
        if ( rhs.is_initialized() )
williamr@2
   251
          construct(rhs.get_impl());
williamr@2
   252
      }
williamr@2
   253
    }
williamr@2
   254
williamr@2
   255
    // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
williamr@2
   256
    template<class U>
williamr@2
   257
    void assign ( optional<U> const& rhs )
williamr@2
   258
    {
williamr@2
   259
      if (is_initialized())
williamr@2
   260
      {
williamr@2
   261
        if ( rhs.is_initialized() )
williamr@2
   262
             assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
williamr@2
   263
        else destroy();
williamr@2
   264
      }
williamr@2
   265
      else
williamr@2
   266
      {
williamr@2
   267
        if ( rhs.is_initialized() )
williamr@2
   268
          construct(static_cast<value_type>(rhs.get()));
williamr@2
   269
      }
williamr@2
   270
    }
williamr@2
   271
williamr@2
   272
    // Assigns from a T (deep-copies the rhs value)
williamr@2
   273
    void assign ( argument_type val )
williamr@2
   274
    {
williamr@2
   275
      if (is_initialized())
williamr@2
   276
           assign_value(val, is_reference_predicate() );
williamr@2
   277
      else construct(val);
williamr@2
   278
    }
williamr@2
   279
williamr@2
   280
    // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
williamr@2
   281
    // No-throw (assuming T::~T() doesn't)
williamr@2
   282
    void assign ( none_t ) { destroy(); }
williamr@2
   283
williamr@2
   284
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
williamr@2
   285
    template<class Expr>
williamr@2
   286
    void assign_expr ( Expr const& expr, Expr const* tag )
williamr@2
   287
      {
williamr@2
   288
        if (is_initialized())
williamr@2
   289
             assign_expr_to_initialized(expr,tag);
williamr@2
   290
        else construct(expr,tag);
williamr@2
   291
      }
williamr@2
   292
#endif
williamr@2
   293
williamr@2
   294
  public :
williamr@2
   295
williamr@2
   296
    // Destroys the current value, if any, leaving this UNINITIALIZED
williamr@2
   297
    // No-throw (assuming T::~T() doesn't)
williamr@2
   298
    void reset() { destroy(); }
williamr@2
   299
williamr@2
   300
    // Replaces the current value -if any- with 'val'
williamr@2
   301
    void reset ( argument_type val ) { assign(val); }
williamr@2
   302
williamr@2
   303
    // Returns a pointer to the value if this is initialized, otherwise,
williamr@2
   304
    // returns NULL.
williamr@2
   305
    // No-throw
williamr@2
   306
    pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
williamr@2
   307
    pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
williamr@2
   308
williamr@2
   309
    bool is_initialized() const { return m_initialized ; }
williamr@2
   310
williamr@2
   311
  protected :
williamr@2
   312
williamr@2
   313
    void construct ( argument_type val )
williamr@2
   314
     {
williamr@2
   315
       new (m_storage.address()) internal_type(val) ;
williamr@2
   316
       m_initialized = true ;
williamr@2
   317
     }
williamr@2
   318
williamr@2
   319
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
williamr@2
   320
    // Constructs in-place using the given factory
williamr@2
   321
    template<class Expr>
williamr@2
   322
    void construct ( Expr const& factory, in_place_factory_base const* )
williamr@2
   323
     {
williamr@2
   324
       BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
williamr@2
   325
       boost_optional_detail::construct<value_type>(factory, m_storage.address());
williamr@2
   326
       m_initialized = true ;
williamr@2
   327
     }
williamr@2
   328
williamr@2
   329
    // Constructs in-place using the given typed factory
williamr@2
   330
    template<class Expr>
williamr@2
   331
    void construct ( Expr const& factory, typed_in_place_factory_base const* )
williamr@2
   332
     {
williamr@2
   333
       BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
williamr@2
   334
       factory.apply(m_storage.address()) ;
williamr@2
   335
       m_initialized = true ;
williamr@2
   336
     }
williamr@2
   337
williamr@2
   338
    template<class Expr>
williamr@2
   339
    void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
williamr@2
   340
     {
williamr@2
   341
       destroy();
williamr@2
   342
       construct(factory,tag);
williamr@2
   343
     }
williamr@2
   344
williamr@2
   345
    // Constructs in-place using the given typed factory
williamr@2
   346
    template<class Expr>
williamr@2
   347
    void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
williamr@2
   348
     {
williamr@2
   349
       destroy();
williamr@2
   350
       construct(factory,tag);
williamr@2
   351
     }
williamr@2
   352
#endif
williamr@2
   353
williamr@2
   354
    // Constructs using any expression implicitely convertible to the single argument
williamr@2
   355
    // of a one-argument T constructor.
williamr@2
   356
    // Converting constructions of optional<T> from optional<U> uses this function with
williamr@2
   357
    // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
williamr@2
   358
    template<class Expr>
williamr@2
   359
    void construct ( Expr const& expr, void const* )
williamr@2
   360
     {
williamr@2
   361
       new (m_storage.address()) internal_type(expr) ;
williamr@2
   362
       m_initialized = true ;
williamr@2
   363
     }
williamr@2
   364
williamr@2
   365
    // Assigns using a form any expression implicitely convertible to the single argument
williamr@2
   366
    // of a T's assignment operator.
williamr@2
   367
    // Converting assignments of optional<T> from optional<U> uses this function with
williamr@2
   368
    // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
williamr@2
   369
    template<class Expr>
williamr@2
   370
    void assign_expr_to_initialized ( Expr const& expr, void const* )
williamr@2
   371
     {
williamr@2
   372
       assign_value(expr, is_reference_predicate());
williamr@2
   373
     }
williamr@2
   374
williamr@2
   375
#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
williamr@2
   376
    // BCB5.64 (and probably lower versions) workaround.
williamr@2
   377
    //   The in-place factories are supported by means of catch-all constructors
williamr@2
   378
    //   and assignment operators (the functions are parameterized in terms of
williamr@2
   379
    //   an arbitrary 'Expr' type)
williamr@2
   380
    //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
williamr@2
   381
    //   to the 'Expr'-taking functions even though explicit overloads are present for them.
williamr@2
   382
    //   Thus, the following overload is needed to properly handle the case when the 'lhs'
williamr@2
   383
    //   is another optional.
williamr@2
   384
    //
williamr@2
   385
    // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
williamr@2
   386
    // instead of choosing the wrong overload
williamr@2
   387
    //
williamr@2
   388
    // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
williamr@2
   389
    template<class Expr>
williamr@2
   390
    void construct ( Expr const& expr, optional_tag const* )
williamr@2
   391
     {
williamr@2
   392
       if ( expr.is_initialized() )
williamr@2
   393
       {
williamr@2
   394
         // An exception can be thrown here.
williamr@2
   395
         // It it happens, THIS will be left uninitialized.
williamr@2
   396
         new (m_storage.address()) internal_type(expr.get()) ;
williamr@2
   397
         m_initialized = true ;
williamr@2
   398
       }
williamr@2
   399
     }
williamr@2
   400
#endif
williamr@2
   401
williamr@2
   402
    void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
williamr@2
   403
    void assign_value ( argument_type val, is_reference_tag     ) { construct(val); }
williamr@2
   404
williamr@2
   405
    void destroy()
williamr@2
   406
    {
williamr@2
   407
      if ( m_initialized )
williamr@2
   408
        destroy_impl(is_reference_predicate()) ;
williamr@2
   409
    }
williamr@2
   410
williamr@2
   411
    unspecified_bool_type safe_bool() const { return m_initialized ? &this_type::is_initialized : 0 ; }
williamr@2
   412
williamr@2
   413
    reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
williamr@2
   414
    reference_type       get_impl()       { return dereference(get_object(), is_reference_predicate() ) ; }
williamr@2
   415
williamr@2
   416
    pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
williamr@2
   417
    pointer_type       get_ptr_impl()       { return cast_ptr(get_object(), is_reference_predicate() ) ; }
williamr@2
   418
williamr@2
   419
  private :
williamr@2
   420
williamr@2
   421
    // internal_type can be either T or reference_content<T>
williamr@2
   422
    internal_type const* get_object() const { return static_cast<internal_type const*>(m_storage.address()); }
williamr@2
   423
    internal_type *      get_object()       { return static_cast<internal_type *>     (m_storage.address()); }
williamr@2
   424
williamr@2
   425
    // reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
williamr@2
   426
    reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
williamr@2
   427
    reference_type       dereference( internal_type*       p, is_not_reference_tag )       { return *p ; }
williamr@2
   428
    reference_const_type dereference( internal_type const* p, is_reference_tag     ) const { return p->get() ; }
williamr@2
   429
    reference_type       dereference( internal_type*       p, is_reference_tag     )       { return p->get() ; }
williamr@2
   430
williamr@2
   431
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
williamr@2
   432
    void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
williamr@2
   433
#else
williamr@2
   434
    void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->T::~T() ; m_initialized = false ; }
williamr@2
   435
#endif
williamr@2
   436
williamr@2
   437
    void destroy_impl ( is_reference_tag     ) { m_initialized = false ; }
williamr@2
   438
williamr@2
   439
    // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
williamr@2
   440
    // Decent compilers should disallow conversions from reference_content<T>* to T*, but just in case,
williamr@2
   441
    // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
williamr@2
   442
    pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
williamr@2
   443
    pointer_type       cast_ptr( internal_type *      p, is_not_reference_tag )       { return p ; }
williamr@2
   444
    pointer_const_type cast_ptr( internal_type const* p, is_reference_tag     ) const { return &p->get() ; }
williamr@2
   445
    pointer_type       cast_ptr( internal_type *      p, is_reference_tag     )       { return &p->get() ; }
williamr@2
   446
williamr@2
   447
    bool m_initialized ;
williamr@2
   448
    storage_type m_storage ;
williamr@2
   449
} ;
williamr@2
   450
williamr@2
   451
} // namespace optional_detail
williamr@2
   452
williamr@2
   453
template<class T>
williamr@2
   454
class optional : public optional_detail::optional_base<T>
williamr@2
   455
{
williamr@2
   456
    typedef optional_detail::optional_base<T> base ;
williamr@2
   457
williamr@2
   458
    typedef BOOST_DEDUCED_TYPENAME base::unspecified_bool_type  unspecified_bool_type ;
williamr@2
   459
williamr@2
   460
  public :
williamr@2
   461
williamr@2
   462
    typedef optional<T> this_type ;
williamr@2
   463
williamr@2
   464
    typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
williamr@2
   465
    typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
williamr@2
   466
    typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
williamr@2
   467
    typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
williamr@2
   468
    typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
williamr@2
   469
    typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
williamr@2
   470
williamr@2
   471
    // Creates an optional<T> uninitialized.
williamr@2
   472
    // No-throw
williamr@2
   473
    optional() : base() {}
williamr@2
   474
williamr@2
   475
    // Creates an optional<T> uninitialized.
williamr@2
   476
    // No-throw
williamr@2
   477
    optional( none_t none_ ) : base(none_) {}
williamr@2
   478
williamr@2
   479
    // Creates an optional<T> initialized with 'val'.
williamr@2
   480
    // Can throw if T::T(T const&) does
williamr@2
   481
    optional ( argument_type val ) : base(val) {}
williamr@2
   482
williamr@2
   483
    // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
williamr@2
   484
    // Can throw if T::T(T const&) does
williamr@2
   485
    optional ( bool cond, argument_type val ) : base(cond,val) {}
williamr@2
   486
williamr@2
   487
#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
williamr@2
   488
    // NOTE: MSVC needs templated versions first
williamr@2
   489
williamr@2
   490
    // Creates a deep copy of another convertible optional<U>
williamr@2
   491
    // Requires a valid conversion from U to T.
williamr@2
   492
    // Can throw if T::T(U const&) does
williamr@2
   493
    template<class U>
williamr@2
   494
    explicit optional ( optional<U> const& rhs )
williamr@2
   495
      :
williamr@2
   496
      base()
williamr@2
   497
    {
williamr@2
   498
      if ( rhs.is_initialized() )
williamr@2
   499
        this->construct(rhs.get());
williamr@2
   500
    }
williamr@2
   501
#endif
williamr@2
   502
williamr@2
   503
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
williamr@2
   504
    // Creates an optional<T> with an expression which can be either
williamr@2
   505
    //  (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
williamr@2
   506
    //  (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
williamr@2
   507
    //  (c) Any expression implicitely convertible to the single type
williamr@2
   508
    //      of a one-argument T's constructor.
williamr@2
   509
    //  (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
williamr@2
   510
    //       even though explicit overloads are present for these.
williamr@2
   511
    // Depending on the above some T ctor is called.
williamr@2
   512
    // Can throw is the resolved T ctor throws.
williamr@2
   513
    template<class Expr>
williamr@2
   514
    explicit optional ( Expr const& expr ) : base(expr,&expr) {}
williamr@2
   515
#endif
williamr@2
   516
williamr@2
   517
    // Creates a deep copy of another optional<T>
williamr@2
   518
    // Can throw if T::T(T const&) does
williamr@2
   519
    optional ( optional const& rhs ) : base(rhs) {}
williamr@2
   520
williamr@2
   521
   // No-throw (assuming T::~T() doesn't)
williamr@2
   522
    ~optional() {}
williamr@2
   523
williamr@2
   524
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
williamr@2
   525
    // Assigns from an expression. See corresponding constructor.
williamr@2
   526
    // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
williamr@2
   527
    template<class Expr>
williamr@2
   528
    optional& operator= ( Expr expr )
williamr@2
   529
      {
williamr@2
   530
        this->assign_expr(expr,&expr);
williamr@2
   531
        return *this ;
williamr@2
   532
      }
williamr@2
   533
#endif
williamr@2
   534
williamr@2
   535
williamr@2
   536
#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
williamr@2
   537
    // Assigns from another convertible optional<U> (converts && deep-copies the rhs value)
williamr@2
   538
    // Requires a valid conversion from U to T.
williamr@2
   539
    // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
williamr@2
   540
    template<class U>
williamr@2
   541
    optional& operator= ( optional<U> const& rhs )
williamr@2
   542
      {
williamr@2
   543
        this->assign(rhs);
williamr@2
   544
        return *this ;
williamr@2
   545
      }
williamr@2
   546
#endif
williamr@2
   547
williamr@2
   548
    // Assigns from another optional<T> (deep-copies the rhs value)
williamr@2
   549
    // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
williamr@2
   550
    //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
williamr@2
   551
    optional& operator= ( optional const& rhs )
williamr@2
   552
      {
williamr@2
   553
        this->assign( rhs ) ;
williamr@2
   554
        return *this ;
williamr@2
   555
      }
williamr@2
   556
williamr@2
   557
    // Assigns from a T (deep-copies the rhs value)
williamr@2
   558
    // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
williamr@2
   559
    optional& operator= ( argument_type val )
williamr@2
   560
      {
williamr@2
   561
        this->assign( val ) ;
williamr@2
   562
        return *this ;
williamr@2
   563
      }
williamr@2
   564
williamr@2
   565
    // Assigns from a "none"
williamr@2
   566
    // Which destroys the current value, if any, leaving this UNINITIALIZED
williamr@2
   567
    // No-throw (assuming T::~T() doesn't)
williamr@2
   568
    optional& operator= ( none_t none_ )
williamr@2
   569
      {
williamr@2
   570
        this->assign( none_ ) ;
williamr@2
   571
        return *this ;
williamr@2
   572
      }
williamr@2
   573
williamr@2
   574
    // Returns a reference to the value if this is initialized, otherwise,
williamr@2
   575
    // the behaviour is UNDEFINED
williamr@2
   576
    // No-throw
williamr@2
   577
    reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
williamr@2
   578
    reference_type       get()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
williamr@2
   579
williamr@2
   580
    // Returns a copy of the value if this is initialized, 'v' otherwise
williamr@2
   581
    reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
williamr@2
   582
    reference_type       get_value_or ( reference_type       v )       { return this->is_initialized() ? get() : v ; }
williamr@2
   583
    
williamr@2
   584
    // Returns a pointer to the value if this is initialized, otherwise,
williamr@2
   585
    // the behaviour is UNDEFINED
williamr@2
   586
    // No-throw
williamr@2
   587
    pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
williamr@2
   588
    pointer_type       operator->()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
williamr@2
   589
williamr@2
   590
    // Returns a reference to the value if this is initialized, otherwise,
williamr@2
   591
    // the behaviour is UNDEFINED
williamr@2
   592
    // No-throw
williamr@2
   593
    reference_const_type operator *() const { return this->get() ; }
williamr@2
   594
    reference_type       operator *()       { return this->get() ; }
williamr@2
   595
williamr@2
   596
    // implicit conversion to "bool"
williamr@2
   597
    // No-throw
williamr@2
   598
    operator unspecified_bool_type() const { return this->safe_bool() ; }
williamr@2
   599
williamr@2
   600
       // This is provided for those compilers which don't like the conversion to bool
williamr@2
   601
       // on some contexts.
williamr@2
   602
       bool operator!() const { return !this->is_initialized() ; }
williamr@2
   603
} ;
williamr@2
   604
williamr@2
   605
// Returns optional<T>(v)
williamr@2
   606
template<class T> 
williamr@2
   607
inline 
williamr@2
   608
optional<T> make_optional ( T const& v  )
williamr@2
   609
{
williamr@2
   610
  return optional<T>(v);
williamr@2
   611
}
williamr@2
   612
williamr@2
   613
// Returns optional<T>(cond,v)
williamr@2
   614
template<class T> 
williamr@2
   615
inline 
williamr@2
   616
optional<T> make_optional ( bool cond, T const& v )
williamr@2
   617
{
williamr@2
   618
  return optional<T>(cond,v);
williamr@2
   619
}
williamr@2
   620
williamr@2
   621
// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
williamr@2
   622
// No-throw
williamr@2
   623
template<class T>
williamr@2
   624
inline
williamr@2
   625
BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
williamr@2
   626
get ( optional<T> const& opt )
williamr@2
   627
{
williamr@2
   628
  return opt.get() ;
williamr@2
   629
}
williamr@2
   630
williamr@2
   631
template<class T>
williamr@2
   632
inline
williamr@2
   633
BOOST_DEDUCED_TYPENAME optional<T>::reference_type
williamr@2
   634
get ( optional<T>& opt )
williamr@2
   635
{
williamr@2
   636
  return opt.get() ;
williamr@2
   637
}
williamr@2
   638
williamr@2
   639
// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
williamr@2
   640
// No-throw
williamr@2
   641
template<class T>
williamr@2
   642
inline
williamr@2
   643
BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
williamr@2
   644
get ( optional<T> const* opt )
williamr@2
   645
{
williamr@2
   646
  return opt->get_ptr() ;
williamr@2
   647
}
williamr@2
   648
williamr@2
   649
template<class T>
williamr@2
   650
inline
williamr@2
   651
BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
williamr@2
   652
get ( optional<T>* opt )
williamr@2
   653
{
williamr@2
   654
  return opt->get_ptr() ;
williamr@2
   655
}
williamr@2
   656
williamr@2
   657
// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
williamr@2
   658
// No-throw
williamr@2
   659
template<class T>
williamr@2
   660
inline
williamr@2
   661
BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
williamr@2
   662
get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
williamr@2
   663
{
williamr@2
   664
  return opt.get_value_or(v) ;
williamr@2
   665
}
williamr@2
   666
williamr@2
   667
template<class T>
williamr@2
   668
inline
williamr@2
   669
BOOST_DEDUCED_TYPENAME optional<T>::reference_type
williamr@2
   670
get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
williamr@2
   671
{
williamr@2
   672
  return opt.get_value_or(v) ;
williamr@2
   673
}
williamr@2
   674
williamr@2
   675
// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
williamr@2
   676
// No-throw
williamr@2
   677
template<class T>
williamr@2
   678
inline
williamr@2
   679
BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
williamr@2
   680
get_pointer ( optional<T> const& opt )
williamr@2
   681
{
williamr@2
   682
  return opt.get_ptr() ;
williamr@2
   683
}
williamr@2
   684
williamr@2
   685
template<class T>
williamr@2
   686
inline
williamr@2
   687
BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
williamr@2
   688
get_pointer ( optional<T>& opt )
williamr@2
   689
{
williamr@2
   690
  return opt.get_ptr() ;
williamr@2
   691
}
williamr@2
   692
williamr@2
   693
// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
williamr@2
   694
// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
williamr@2
   695
williamr@2
   696
williamr@2
   697
//
williamr@2
   698
// optional<T> vs optional<T> cases
williamr@2
   699
//
williamr@2
   700
williamr@2
   701
template<class T>
williamr@2
   702
inline
williamr@2
   703
bool operator == ( optional<T> const& x, optional<T> const& y )
williamr@2
   704
{ return equal_pointees(x,y); }
williamr@2
   705
williamr@2
   706
template<class T>
williamr@2
   707
inline
williamr@2
   708
bool operator < ( optional<T> const& x, optional<T> const& y )
williamr@2
   709
{ return less_pointees(x,y); }
williamr@2
   710
williamr@2
   711
template<class T>
williamr@2
   712
inline
williamr@2
   713
bool operator != ( optional<T> const& x, optional<T> const& y )
williamr@2
   714
{ return !( x == y ) ; }
williamr@2
   715
williamr@2
   716
template<class T>
williamr@2
   717
inline
williamr@2
   718
bool operator > ( optional<T> const& x, optional<T> const& y )
williamr@2
   719
{ return y < x ; }
williamr@2
   720
williamr@2
   721
template<class T>
williamr@2
   722
inline
williamr@2
   723
bool operator <= ( optional<T> const& x, optional<T> const& y )
williamr@2
   724
{ return !( y < x ) ; }
williamr@2
   725
williamr@2
   726
template<class T>
williamr@2
   727
inline
williamr@2
   728
bool operator >= ( optional<T> const& x, optional<T> const& y )
williamr@2
   729
{ return !( x < y ) ; }
williamr@2
   730
williamr@2
   731
williamr@2
   732
//
williamr@2
   733
// optional<T> vs T cases
williamr@2
   734
//
williamr@2
   735
template<class T>
williamr@2
   736
inline
williamr@2
   737
bool operator == ( optional<T> const& x, T const& y )
williamr@2
   738
{ return equal_pointees(x, optional<T>(y)); }
williamr@2
   739
williamr@2
   740
template<class T>
williamr@2
   741
inline
williamr@2
   742
bool operator < ( optional<T> const& x, T const& y )
williamr@2
   743
{ return less_pointees(x, optional<T>(y)); }
williamr@2
   744
williamr@2
   745
template<class T>
williamr@2
   746
inline
williamr@2
   747
bool operator != ( optional<T> const& x, T const& y )
williamr@2
   748
{ return !( x == y ) ; }
williamr@2
   749
williamr@2
   750
template<class T>
williamr@2
   751
inline
williamr@2
   752
bool operator > ( optional<T> const& x, T const& y )
williamr@2
   753
{ return y < x ; }
williamr@2
   754
williamr@2
   755
template<class T>
williamr@2
   756
inline
williamr@2
   757
bool operator <= ( optional<T> const& x, T const& y )
williamr@2
   758
{ return !( y < x ) ; }
williamr@2
   759
williamr@2
   760
template<class T>
williamr@2
   761
inline
williamr@2
   762
bool operator >= ( optional<T> const& x, T const& y )
williamr@2
   763
{ return !( x < y ) ; }
williamr@2
   764
williamr@2
   765
//
williamr@2
   766
// T vs optional<T> cases
williamr@2
   767
//
williamr@2
   768
williamr@2
   769
template<class T>
williamr@2
   770
inline
williamr@2
   771
bool operator == ( T const& x, optional<T> const& y )
williamr@2
   772
{ return equal_pointees( optional<T>(x), y ); }
williamr@2
   773
williamr@2
   774
template<class T>
williamr@2
   775
inline
williamr@2
   776
bool operator < ( T const& x, optional<T> const& y )
williamr@2
   777
{ return less_pointees( optional<T>(x), y ); }
williamr@2
   778
williamr@2
   779
template<class T>
williamr@2
   780
inline
williamr@2
   781
bool operator != ( T const& x, optional<T> const& y )
williamr@2
   782
{ return !( x == y ) ; }
williamr@2
   783
williamr@2
   784
template<class T>
williamr@2
   785
inline
williamr@2
   786
bool operator > ( T const& x, optional<T> const& y )
williamr@2
   787
{ return y < x ; }
williamr@2
   788
williamr@2
   789
template<class T>
williamr@2
   790
inline
williamr@2
   791
bool operator <= ( T const& x, optional<T> const& y )
williamr@2
   792
{ return !( y < x ) ; }
williamr@2
   793
williamr@2
   794
template<class T>
williamr@2
   795
inline
williamr@2
   796
bool operator >= ( T const& x, optional<T> const& y )
williamr@2
   797
{ return !( x < y ) ; }
williamr@2
   798
williamr@2
   799
williamr@2
   800
//
williamr@2
   801
// optional<T> vs none cases
williamr@2
   802
//
williamr@2
   803
williamr@2
   804
template<class T>
williamr@2
   805
inline
williamr@2
   806
bool operator == ( optional<T> const& x, none_t )
williamr@2
   807
{ return equal_pointees(x, optional<T>() ); }
williamr@2
   808
williamr@2
   809
template<class T>
williamr@2
   810
inline
williamr@2
   811
bool operator < ( optional<T> const& x, none_t )
williamr@2
   812
{ return less_pointees(x,optional<T>() ); }
williamr@2
   813
williamr@2
   814
template<class T>
williamr@2
   815
inline
williamr@2
   816
bool operator != ( optional<T> const& x, none_t y )
williamr@2
   817
{ return !( x == y ) ; }
williamr@2
   818
williamr@2
   819
template<class T>
williamr@2
   820
inline
williamr@2
   821
bool operator > ( optional<T> const& x, none_t y )
williamr@2
   822
{ return y < x ; }
williamr@2
   823
williamr@2
   824
template<class T>
williamr@2
   825
inline
williamr@2
   826
bool operator <= ( optional<T> const& x, none_t y )
williamr@2
   827
{ return !( y < x ) ; }
williamr@2
   828
williamr@2
   829
template<class T>
williamr@2
   830
inline
williamr@2
   831
bool operator >= ( optional<T> const& x, none_t y )
williamr@2
   832
{ return !( x < y ) ; }
williamr@2
   833
williamr@2
   834
//
williamr@2
   835
// none vs optional<T> cases
williamr@2
   836
//
williamr@2
   837
williamr@2
   838
template<class T>
williamr@2
   839
inline
williamr@2
   840
bool operator == ( none_t x, optional<T> const& y )
williamr@2
   841
{ return equal_pointees(optional<T>() ,y); }
williamr@2
   842
williamr@2
   843
template<class T>
williamr@2
   844
inline
williamr@2
   845
bool operator < ( none_t x, optional<T> const& y )
williamr@2
   846
{ return less_pointees(optional<T>() ,y); }
williamr@2
   847
williamr@2
   848
template<class T>
williamr@2
   849
inline
williamr@2
   850
bool operator != ( none_t x, optional<T> const& y )
williamr@2
   851
{ return !( x == y ) ; }
williamr@2
   852
williamr@2
   853
template<class T>
williamr@2
   854
inline
williamr@2
   855
bool operator > ( none_t x, optional<T> const& y )
williamr@2
   856
{ return y < x ; }
williamr@2
   857
williamr@2
   858
template<class T>
williamr@2
   859
inline
williamr@2
   860
bool operator <= ( none_t x, optional<T> const& y )
williamr@2
   861
{ return !( y < x ) ; }
williamr@2
   862
williamr@2
   863
template<class T>
williamr@2
   864
inline
williamr@2
   865
bool operator >= ( none_t x, optional<T> const& y )
williamr@2
   866
{ return !( x < y ) ; }
williamr@2
   867
williamr@2
   868
//
williamr@2
   869
// The following swap implementation follows the GCC workaround as found in
williamr@2
   870
//  "boost/detail/compressed_pair.hpp"
williamr@2
   871
//
williamr@2
   872
namespace optional_detail {
williamr@2
   873
williamr@2
   874
// GCC < 3.2 gets the using declaration at namespace scope (FLC, DWA)
williamr@2
   875
#if BOOST_WORKAROUND(__GNUC__, < 3)                             \
williamr@2
   876
    || BOOST_WORKAROUND(__GNUC__, == 3) && __GNUC_MINOR__ <= 2
williamr@2
   877
   using std::swap;
williamr@2
   878
#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
williamr@2
   879
#endif
williamr@2
   880
williamr@2
   881
// optional's swap:
williamr@2
   882
// If both are initialized, calls swap(T&, T&). If this swap throws, both will remain initialized but their values are now unspecified.
williamr@2
   883
// If only one is initialized, calls U.reset(*I), THEN I.reset().
williamr@2
   884
// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I is never reset)
williamr@2
   885
// If both are uninitialized, do nothing (no-throw)
williamr@2
   886
template<class T>
williamr@2
   887
inline
williamr@2
   888
void optional_swap ( optional<T>& x, optional<T>& y )
williamr@2
   889
{
williamr@2
   890
  if ( !x && !!y )
williamr@2
   891
  {
williamr@2
   892
    x.reset(*y);
williamr@2
   893
    y.reset();
williamr@2
   894
  }
williamr@2
   895
  else if ( !!x && !y )
williamr@2
   896
  {
williamr@2
   897
    y.reset(*x);
williamr@2
   898
    x.reset();
williamr@2
   899
  }
williamr@2
   900
  else if ( !!x && !!y )
williamr@2
   901
  {
williamr@2
   902
// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
williamr@2
   903
#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
williamr@2
   904
    // allow for Koenig lookup
williamr@2
   905
    using std::swap ;
williamr@2
   906
#endif
williamr@2
   907
    swap(*x,*y);
williamr@2
   908
  }
williamr@2
   909
}
williamr@2
   910
williamr@2
   911
} // namespace optional_detail
williamr@2
   912
williamr@2
   913
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
williamr@2
   914
{
williamr@2
   915
  optional_detail::optional_swap(x,y);
williamr@2
   916
}
williamr@2
   917
williamr@2
   918
williamr@2
   919
} // namespace boost
williamr@2
   920
williamr@2
   921
#endif
williamr@2
   922