*** /usr/include/boost/optional/optional.hpp	2012-11-16 01:54:00.000000000 +0100
--- optional.hpp	2013-02-05 15:02:07.917622463 +0100
***************
*** 11,16 ****
--- 11,17 ----
  //
  // Revisions:
  // 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
+ // 5 Feb 2013 (move construction/assignment) Diggory Hardy
  //
  #ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
  #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
*************** struct types_when_isnt_ref
*** 155,160 ****
--- 156,162 ----
    typedef T const* pointer_const_type ;
    typedef T *      pointer_type ;
    typedef T const& argument_type ;
+   typedef T && argument_move_type;
  } ;
  template<class T>
  struct types_when_is_ref
*************** struct types_when_is_ref
*** 166,171 ****
--- 168,174 ----
    typedef raw_type* pointer_const_type ;
    typedef raw_type* pointer_type ;
    typedef raw_type& argument_type ;
+   typedef raw_type&& argument_move_type;
  } ;
  
  struct optional_tag {} ;
*************** class optional_base : public optional_ta
*** 208,213 ****
--- 211,217 ----
      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 ;
+     typedef BOOST_DEDUCED_TYPENAME types::argument_move_type        argument_move_type ;
  
      // Creates an optional<T> uninitialized.
      // No-throw
*************** class optional_base : public optional_ta
*** 230,235 ****
--- 234,248 ----
        construct(val);
      }
  
+     // Creates an optional<T> move-constructed from 'val'.
+     // Can throw if T::T(T const&) does
+     optional_base ( argument_move_type val )
+       :
+       m_initialized(false)
+     {
+       construct(std::move(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 )
*************** class optional_base : public optional_ta
*** 240,245 ****
--- 253,268 ----
          construct(val);
      }
  
+     // Creates an optional<T> move-construted 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_move_type val )
+       :
+       m_initialized(false)
+     {
+       if ( cond )
+         construct(std::move(val));
+     }
+ 
      // Creates a deep copy of another optional<T>
      // Can throw if T::T(T const&) does
      optional_base ( optional_base const& rhs )
*************** class optional_base : public optional_ta
*** 250,255 ****
--- 273,291 ----
          construct(rhs.get_impl());
      }
  
+     // Move-constructs from another optional<T>
+     // Can throw if T::T(T &&) does
+ #if 0
+     //TODO: non-trivial to implement and possibly not needed
+     optional_base ( optional_base && rhs )
+       :
+       m_initialized(false)
+     {
+       if ( rhs.is_initialized() )
+         construct(rhs.release_impl());  // something like "release" needed
+     }
+ #endif
+ 
  
      // This is used for both converting and in-place constructions.
      // Derived classes use the 'tag' to select the appropriate
*************** class optional_base : public optional_ta
*** 308,313 ****
--- 344,357 ----
        else construct(val);
      }
  
+     // Assigns from a T (move-copies the rhs value)
+     void assign ( argument_move_type val )
+     {
+       if (is_initialized())
+            assign_value(std::move(val), is_reference_predicate() );
+       else construct(std::move(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(); }
*************** class optional_base : public optional_ta
*** 331,336 ****
--- 375,383 ----
      // Replaces the current value -if any- with 'val'
      void reset ( argument_type val ) { assign(val); }
  
+     // Replaces the current value -if any- with 'val'
+     void reset ( argument_move_type val ) { assign(std::move(val)); }
+ 
      // Returns a pointer to the value if this is initialized, otherwise,
      // returns NULL.
      // No-throw
*************** class optional_base : public optional_ta
*** 347,352 ****
--- 394,405 ----
         m_initialized = true ;
       }
  
+     void construct ( argument_move_type val )
+      {
+        new (m_storage.address()) internal_type(std::move(val)) ;
+        m_initialized = true ;
+      }
+ 
  #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
      // Constructs in-place using the given factory
      template<class Expr>
*************** class optional_base : public optional_ta
*** 430,437 ****
       }
  #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()
      {
--- 483,496 ----
       }
  #endif
  
!     void assign_value ( argument_type val, is_not_reference_tag ) {
!         get_impl() = val; }
!     void assign_value ( argument_move_type val, is_not_reference_tag ) {
!         get_impl() = std::move(val); }
!     void assign_value ( argument_type val, is_reference_tag ) {
!         construct(val); }
!     void assign_value ( argument_move_type val, is_reference_tag ) {
!         construct(std::move(val)); }
  
      void destroy()
      {
*************** class optional : public optional_detail:
*** 512,517 ****
--- 571,577 ----
      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 ;
+     typedef BOOST_DEDUCED_TYPENAME base::argument_move_type        argument_move_type ;
  
      // Creates an optional<T> uninitialized.
      // No-throw
*************** class optional : public optional_detail:
*** 525,534 ****
--- 585,602 ----
      // Can throw if T::T(T const&) does
      optional ( argument_type val ) : base(val) {}
  
+     // Creates an optional<T> move-constructed from 'val'.
+     // Can throw if T::T(T const&) does
+     optional ( argument_move_type val ) : base(std::move(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) {}
  
+     // Creates an optional<T> move-constructed from 'val' IFF cond is true, otherwise creates an uninitialized optional.
+     // Can throw if T::T(T const&) does
+     optional ( bool cond, argument_move_type val ) : base(cond,std::move(val)) {}
+ 
  #ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
      // NOTE: MSVC needs templated versions first
  
*************** class optional : public optional_detail:
*** 563,568 ****
--- 631,643 ----
      // Can throw if T::T(T const&) does
      optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
  
+     // Moves from another optional<T>, leaving that uninitialised
+     // Can throw if T::T(T const&) does
+     optional ( optional && rhs ) : base() {
+         *this = std::move( rhs.get() );
+         rhs = boost::none;
+     }
+ 
     // No-throw (assuming T::~T() doesn't)
      ~optional() {}
  
*************** class optional : public optional_detail:
*** 606,611 ****
--- 681,694 ----
          this->assign( val ) ;
          return *this ;
        }
+     // Assigns from a T (move-copies the rhs value)
+     // Basic Guarantee: If T::( T && ) throws, this is left UNINITIALIZED
+     optional& operator= ( argument_move_type val )
+       {
+         this->assign( std::move(val) ) ;
+         return *this ;
+       }
+ 
  
      // Assigns from a "none"
      // Which destroys the current value, if any, leaving this UNINITIALIZED
*************** struct swap_selector<false>
*** 960,971 ****
  
          if ( !hasX && hasY )
          {
!             x = y.get();
              y = boost::none ;
          }
          else if ( hasX && !hasY )
          {
!             y = x.get();
              x = boost::none ;
          }
          else if ( hasX && hasY )
--- 1043,1054 ----
  
          if ( !hasX && hasY )
          {
!             x = std::move(y.get());
              y = boost::none ;
          }
          else if ( hasX && !hasY )
          {
!             y = std::move(x.get());
              x = boost::none ;
          }
          else if ( hasX && hasY )
