Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r85079 - in trunk: boost/variant libs/variant/test
From: antoshkka_at_[hidden]
Date: 2013-07-19 03:43:03


Author: apolukhin
Date: 2013-07-19 03:43:03 EDT (Fri, 19 Jul 2013)
New Revision: 85079
URL: http://svn.boost.org/trac/boost/changeset/85079

Log:
Added code (and tests) to mark move constructors and move assignemnt of Boost.Variant as noexcept if possible (refs #7911)

Text files modified:
   trunk/boost/variant/variant.hpp | 31 ++++++++++++++++++++++++++++---
   trunk/libs/variant/test/rvalue_test.cpp | 24 +++++++++++++++++++++---
   2 files changed, 49 insertions(+), 6 deletions(-)

Modified: trunk/boost/variant/variant.hpp
==============================================================================
--- trunk/boost/variant/variant.hpp Fri Jul 19 03:04:40 2013 (r85078)
+++ trunk/boost/variant/variant.hpp 2013-07-19 03:43:03 EDT (Fri, 19 Jul 2013) (r85079)
@@ -226,6 +226,25 @@
 
 #endif // BOOST_MPL_CFG_MSVC_60_ETI_BUG workaround
 
+#ifndef BOOST_NO_CXX11_NOEXCEPT
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction is_variant_move_noexcept
+//
+// Returns true_type if all the types are nothrow move constructible.
+//
+template <class Types>
+struct is_variant_move_noexcept {
+ typedef typename boost::mpl::find_if<
+ Types, mpl::not_<boost::is_nothrow_move_constructible<boost::mpl::_1> >
+ >::type iterator_t;
+
+ typedef typename boost::mpl::end<Types>::type end_t;
+ typedef typename boost::is_same<
+ iterator_t, end_t
+ >::type type;
+};
+#endif // BOOST_NO_CXX11_NOEXCEPT
+
 ///////////////////////////////////////////////////////////////////////////////
 // (detail) metafunction make_storage
 //
@@ -1289,6 +1308,12 @@
           internal_types, never_uses_backup_flag
>::type storage_t;
 
+#ifndef BOOST_NO_CXX11_NOEXCEPT
+ typedef typename detail::variant::is_variant_move_noexcept<
+ internal_types
+ > variant_move_noexcept;
+#endif
+
 private: // helpers, for representation (below)
 
     // which_ on:
@@ -1375,7 +1400,7 @@
 
 public: // structors
 
- ~variant()
+ ~variant() BOOST_NOEXCEPT
     {
         destroy_content();
     }
@@ -1766,7 +1791,7 @@
     }
     
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- variant(variant&& operand)
+ variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept::type::value)
     {
         // Move the value of operand into *this...
         detail::variant::move_into visitor( storage_.address() );
@@ -2177,7 +2202,7 @@
     }
 
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- variant& operator=(variant&& rhs)
+ variant& operator=(variant&& rhs) BOOST_NOEXCEPT_IF(variant_move_noexcept::type::value)
     {
         variant_assign( detail::variant::move(rhs) );
         return *this;

Modified: trunk/libs/variant/test/rvalue_test.cpp
==============================================================================
--- trunk/libs/variant/test/rvalue_test.cpp Fri Jul 19 03:04:40 2013 (r85078)
+++ trunk/libs/variant/test/rvalue_test.cpp 2013-07-19 03:43:03 EDT (Fri, 19 Jul 2013) (r85079)
@@ -3,8 +3,7 @@
 // See http://www.boost.org for updates, documentation, and revision history.
 //-----------------------------------------------------------------------------
 //
-// Copyright (c) 2012
-// Antony Polukhin
+// Copyright (c) 2012-2013 Antony Polukhin
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -14,6 +13,7 @@
 
 #include "boost/test/minimal.hpp"
 #include "boost/variant.hpp"
+#include "boost/type_traits/is_nothrow_move_assignable.hpp"
 
 // This test requires rvalue references support
 
@@ -34,6 +34,11 @@
     BOOST_CHECK(true);
 }
 
+void run_moves_are_noexcept()
+{
+ BOOST_CHECK(true);
+}
+
 #else
 
 class move_copy_conting_class {
@@ -177,6 +182,18 @@
     BOOST_CHECK(vi.which() == 1);
 }
 
+void run_moves_are_noexcept() {
+#ifndef BOOST_NO_CXX11_NOEXCEPT
+ typedef boost::variant<int, short, double> variant_noexcept_t;
+ BOOST_CHECK(boost::is_nothrow_move_assignable<variant_noexcept_t>::value);
+ BOOST_CHECK(boost::is_nothrow_move_constructible<variant_noexcept_t>::value);
+
+ typedef boost::variant<int, short, double, move_only_structure> variant_except_t;
+ BOOST_CHECK(!boost::is_nothrow_move_assignable<variant_except_t>::value);
+ BOOST_CHECK(!boost::is_nothrow_move_constructible<variant_except_t>::value);
+#endif
+}
+
 #endif
 
 
@@ -185,5 +202,6 @@
    run();
    run1();
    run_move_only();
+ run_moves_are_noexcept();
    return 0;
-}
\ No newline at end of file
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk