Ticket #1841: 14-optional-partial-rvalue.patch

File 14-optional-partial-rvalue.patch, 6.2 KB (added by mlcreech@…, 12 years ago)

Partial move support

  • boost/optional/optional.hpp

    diff -purN orig/boost/optional/optional.hpp boost_1_46_0_beta1/boost/optional/optional.hpp
    old new struct types_when_isnt_ref  
    152152{
    153153  typedef T const& reference_const_type ;
    154154  typedef T &      reference_type ;
     155#ifdef BOOST_HAS_RVALUE_REFS
     156  typedef T &&     rreference_type ;
     157#endif
    155158  typedef T const* pointer_const_type ;
    156159  typedef T *      pointer_type ;
    157160  typedef T const& argument_type ;
    struct types_when_is_ref  
    163166
    164167  typedef raw_type& reference_const_type ;
    165168  typedef raw_type& reference_type ;
     169#ifdef BOOST_HAS_RVALUE_REFS
     170  typedef raw_type&& rreference_type ;
     171#endif
    166172  typedef raw_type* pointer_const_type ;
    167173  typedef raw_type* pointer_type ;
    168174  typedef raw_type& argument_type ;
    class optional_base : public optional_ta  
    205211
    206212    typedef BOOST_DEDUCED_TYPENAME types::reference_type       reference_type ;
    207213    typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
     214#ifdef BOOST_HAS_RVALUE_REFS
     215    typedef BOOST_DEDUCED_TYPENAME types::rreference_type      rreference_type ;
     216#endif
    208217    typedef BOOST_DEDUCED_TYPENAME types::pointer_type         pointer_type ;
    209218    typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type   pointer_const_type ;
    210219    typedef BOOST_DEDUCED_TYPENAME types::argument_type        argument_type ;
    class optional_base : public optional_ta  
    240249        construct(val);
    241250    }
    242251
     252#ifdef BOOST_HAS_RVALUE_REFS
     253    // Creates an optional<T> move-constructed from 'val'
     254    // Can throw if T::T(T &&) does
     255    optional_base ( rreference_type val )
     256      :
     257      m_initialized(false)
     258    {
     259      construct(std::forward<T>(val));
     260    }
     261
     262    // Creates an optional<T> move-constructed from 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
     263    // Can throw if T::T(T &&) does
     264    optional_base ( bool cond, rreference_type val )
     265      :
     266      m_initialized(false)
     267    {
     268      if ( cond )
     269        construct(std::forward<T>(val));
     270    }
     271#endif
     272
    243273    // Creates a deep copy of another optional<T>
    244274    // Can throw if T::T(T const&) does
    245275    optional_base ( optional_base const& rhs )
    class optional_base : public optional_ta  
    308338      else construct(val);
    309339    }
    310340
     341#ifdef BOOST_HAS_RVALUE_REFS
     342    // Assigns from a T (moves the rhs value)
     343    void assign ( rreference_type val )
     344    {
     345      if (is_initialized())
     346           assign_value(std::forward<T>(val), is_reference_predicate() );
     347      else construct(std::forward<T>(val));
     348    }
     349#endif
     350
    311351    // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
    312352    // No-throw (assuming T::~T() doesn't)
    313353    void assign ( none_t ) { destroy(); }
    class optional_base : public optional_ta  
    347387       m_initialized = true ;
    348388     }
    349389
     390#ifdef BOOST_HAS_RVALUE_REFS
     391     void construct ( rreference_type val )
     392     {
     393       new (m_storage.address()) internal_type(std::forward<T>(val)) ;
     394       m_initialized = true ;
     395     }
     396#endif
     397
    350398#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
    351399    // Constructs in-place using the given factory
    352400    template<class Expr>
    class optional_base : public optional_ta  
    432480
    433481    void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
    434482    void assign_value ( argument_type val, is_reference_tag     ) { construct(val); }
     483#ifdef BOOST_HAS_RVALUE_REFS
     484    void assign_value ( rreference_type val, is_not_reference_tag ) { get_impl() = std::forward<T>(val); }
     485    void assign_value ( rreference_type val, is_reference_tag     ) { construct(std::forward<T>(val)); }
     486#endif
    435487
    436488    void destroy()
    437489    {
    class optional : public optional_detail:  
    509561    typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
    510562    typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
    511563    typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
     564#ifdef BOOST_HAS_RVALUE_REFS
     565    typedef BOOST_DEDUCED_TYPENAME base::rreference_type      rreference_type ;
     566#endif
    512567    typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
    513568    typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
    514569    typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
    class optional : public optional_detail:  
    529584    // Can throw if T::T(T const&) does
    530585    optional ( bool cond, argument_type val ) : base(cond,val) {}
    531586
     587#ifdef BOOST_HAS_RVALUE_REFS
     588    // Creates an optional<T> moved from 'val'.
     589    // Can throw if T::T(T &&) does
     590    optional ( rreference_type val ) : base(std::forward<value_type>(val)) {}
     591
     592    // Creates an optional<T> moved from 'val' IFF cond is true, otherwise creates an uninitialized optional.
     593    // Can throw if T::T(T &&) does
     594    optional ( bool cond, rreference_type val ) : base(cond,std::forward<value_type>(val)) {}
     595#endif
     596
    532597#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
    533598    // NOTE: MSVC needs templated versions first
    534599
    class optional : public optional_detail:  
    607672        return *this ;
    608673      }
    609674
     675#ifdef BOOST_HAS_RVALUE_REFS
     676    // Assigns from a T (moves the rhs value)
     677    // Basic Guarantee: If T::( T && ) throws, this is left UNINITIALIZED
     678    optional& operator= ( rreference_type val )
     679      {
     680        this->assign( std::forward<T>(val) ) ;
     681        return *this ;
     682      }
     683#endif
     684
    610685    // Assigns from a "none"
    611686    // Which destroys the current value, if any, leaving this UNINITIALIZED
    612687    // No-throw (assuming T::~T() doesn't)
    optional<T> make_optional ( bool cond, T  
    671746  return optional<T>(cond,v);
    672747}
    673748
     749#ifdef BOOST_HAS_RVALUE_REFS
     750// Returns optional<T>(v)
     751template<class T>
     752inline
     753optional<T> make_optional ( T && v  )
     754{
     755  return optional<T>(std::forward<T>(v));
     756}
     757
     758// Returns optional<T>(cond,v)
     759template<class T>
     760inline
     761optional<T> make_optional ( bool cond, T && v )
     762{
     763  return optional<T>(cond,std::forward<T>(v));
     764}
     765#endif
     766
    674767// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
    675768// No-throw
    676769template<class T>