Ticket #7718: rvalues2.patch
File rvalues2.patch, 8.8 KB (added by , 10 years ago) |
---|
-
detail/initializer.hpp
20 20 #include "boost/call_traits.hpp" 21 21 #include "boost/detail/reference_content.hpp" 22 22 #include "boost/variant/recursive_wrapper_fwd.hpp" 23 #include "boost/variant/detail/move.hpp" 23 24 24 25 #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) 25 26 # include "boost/mpl/aux_/value_wknd.hpp" … … 79 80 recursive_enabled_T; 80 81 typedef typename unwrap_recursive<recursive_enabled_T>::type 81 82 public_T; 83 84 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 85 typedef boost::is_reference<public_T> 86 is_reference_content_t; 87 88 typedef typename boost::mpl::if_<is_reference_content_t, public_T, const public_T& >::type 89 param_T; 90 91 template <class T> struct disable_overload{}; 92 93 typedef typename boost::mpl::if_<is_reference_content_t, disable_overload<public_T>, public_T&& >::type 94 param2_T; 95 #else 82 96 typedef typename call_traits<public_T>::param_type 83 97 param_T; 98 #endif 84 99 85 100 public: // static functions 86 101 … … 96 111 return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which 97 112 } 98 113 114 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 115 static int initialize(void* dest, param2_T operand) 116 { 117 // This assert must newer trigger, because all the reference contents are 118 // handled by the initilize(void* dest, param_T operand) function above 119 BOOST_ASSERT(!is_reference_content_t::value); 120 121 typedef typename boost::mpl::if_<is_reference_content_t, param2_T, public_T>::type value_T; 122 new(dest) value_T( boost::detail::variant::move(operand) ); 123 return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which 124 } 125 #endif 99 126 }; 100 127 101 128 friend class initializer_node; -
detail/backup_holder.hpp
13 13 #ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP 14 14 #define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP 15 15 16 #include "boost/config.hpp"17 16 #include "boost/assert.hpp" 18 17 19 18 namespace boost { … … 33 32 delete backup_; 34 33 } 35 34 36 explicit backup_holder(T* backup) BOOST_NOEXCEPT35 explicit backup_holder(T* backup) 37 36 : backup_(backup) 38 37 { 39 38 } … … 54 53 return *this; 55 54 } 56 55 57 void swap(backup_holder& rhs) BOOST_NOEXCEPT56 void swap(backup_holder& rhs) 58 57 { 59 58 T* tmp = rhs.backup_; 60 59 rhs.backup_ = this->backup_; … … 84 83 } 85 84 86 85 template <typename T> 87 void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) BOOST_NOEXCEPT86 void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) 88 87 { 89 88 lhs.swap(rhs); 90 89 } -
variant.hpp
1468 1468 1469 1469 friend class convert_copy_into; 1470 1470 1471 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1472 class convert_move_into 1473 : public static_visitor<int> 1474 { 1475 private: // representation 1476 1477 void* storage_; 1478 1479 public: // structors 1480 1481 explicit convert_move_into(void* storage) BOOST_NOEXCEPT 1482 : storage_(storage) 1483 { 1484 } 1485 1486 public: // internal visitor interfaces (below) 1487 1488 template <typename T> 1489 int internal_visit(T& operand, int) const 1490 { 1491 // NOTE TO USER : 1492 // Compile error here indicates one of the source variant's types 1493 // cannot be unambiguously converted to the destination variant's 1494 // types (or that no conversion exists). 1495 // 1496 return initializer::initialize(storage_, detail::variant::move(operand) ); 1497 } 1498 1499 template <typename T> 1500 int internal_visit(boost::detail::reference_content<T>& operand, long) const 1501 { 1502 return internal_visit( operand.get(), 1L ); 1503 } 1504 1505 template <typename T> 1506 int internal_visit(const boost::detail::reference_content<T>& operand, long) const 1507 { 1508 return internal_visit( operand.get(), 1L ); 1509 } 1510 1511 template <typename T> 1512 int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const 1513 { 1514 return internal_visit( operand.get(), 1L ); 1515 } 1516 1517 template <typename T> 1518 int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const 1519 { 1520 return internal_visit( operand.get(), 1L ); 1521 } 1522 1523 template <typename T> 1524 int internal_visit(boost::recursive_wrapper<T>& operand, long) const 1525 { 1526 return internal_visit( operand.get(), 1L ); 1527 } 1528 1529 template <typename T> 1530 int internal_visit(const boost::recursive_wrapper<T>& operand, long) const 1531 { 1532 return internal_visit( operand.get(), 1L ); 1533 } 1534 }; 1535 1536 friend class convert_move_into; 1537 #endif 1538 1471 1539 private: // helpers, for structors, below 1472 1540 1473 1541 template <typename T> … … 1490 1558 ); 1491 1559 } 1492 1560 1561 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1562 template <typename T> 1563 typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type convert_construct( 1564 T&& operand 1565 , int 1566 , mpl::false_ = mpl::false_() // is_foreign_variant 1567 ) 1568 { 1569 // NOTE TO USER : 1570 // Compile error here indicates that the given type is not 1571 // unambiguously convertible to one of the variant's types 1572 // (or that no conversion exists). 1573 // 1574 indicate_which( 1575 initializer::initialize( 1576 storage_.address() 1577 , detail::variant::move(operand) 1578 ) 1579 ); 1580 } 1581 #endif 1582 1493 1583 template <typename Variant> 1494 1584 void convert_construct( 1495 1585 Variant& operand … … 1503 1593 ); 1504 1594 } 1505 1595 1596 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1506 1597 template <typename Variant> 1598 typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct( 1599 Variant&& operand 1600 , long 1601 , mpl::true_// is_foreign_variant 1602 ) 1603 { 1604 convert_move_into visitor(storage_.address()); 1605 indicate_which( 1606 operand.internal_apply_visitor(visitor) 1607 ); 1608 } 1609 #endif 1610 1611 template <typename Variant> 1507 1612 void convert_construct_variant(Variant& operand) 1508 1613 { 1509 1614 // [Determine if the given variant is itself a bounded type, or if its … … 1530 1635 ); 1531 1636 } 1532 1637 1638 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1639 template <typename Variant> 1640 typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct_variant(Variant&& operand) 1641 { 1642 // [Determine if the given variant is itself a bounded type, or if its 1643 // content needs to be converted (i.e., it is a 'foreign' variant):] 1644 // 1645 1646 typedef typename mpl::find_if< 1647 types 1648 , is_same< 1649 add_const<mpl::_1> 1650 , const Variant 1651 > 1652 >::type found_it; 1653 1654 typedef typename mpl::end<types>::type not_found; 1655 typedef typename is_same< 1656 found_it, not_found 1657 >::type is_foreign_variant; 1658 1659 // Convert move construct from operand: 1660 convert_construct( 1661 detail::variant::move(operand), 1L 1662 , is_foreign_variant() 1663 ); 1664 } 1665 #endif 1666 1533 1667 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> 1534 1668 void convert_construct( 1535 1669 boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand … … 1548 1682 convert_construct_variant(operand); 1549 1683 } 1550 1684 1685 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1686 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> 1687 void convert_construct( 1688 boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&& operand 1689 , long 1690 ) 1691 { 1692 convert_construct_variant( detail::variant::move(operand) ); 1693 } 1694 #endif 1695 1551 1696 public: // structors, cont. 1552 1697 1553 1698 #if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) … … 1597 1742 { 1598 1743 convert_construct(operand, 1L); 1599 1744 } 1600 1601 1745 #endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds 1746 1747 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 1748 template <class T> 1749 variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0) 1750 { 1751 convert_construct( detail::variant::move(operand), 1L); 1752 } 1753 #endif 1602 1754 1603 1755 public: // structors, cont. 1604 1756