Index: boost/variant/variant.hpp =================================================================== --- boost/variant/variant.hpp (revision 85007) +++ boost/variant/variant.hpp (working copy) @@ -226,7 +226,26 @@ #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 +struct is_variant_move_noexcept { + typedef typename boost::mpl::find_if< + Types, mpl::not_ > + >::type iterator_t; + + typedef typename boost::mpl::end::type end_t; + typedef typename boost::is_same< + iterator_t, end_t + >::type type; +}; +#endif // BOOST_NO_CXX11_NOEXCEPT + +/////////////////////////////////////////////////////////////////////////////// // (detail) metafunction make_storage // // Provides an aligned storage type capable of holding any of the types @@ -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; Index: libs/variant/test/rvalue_test.cpp =================================================================== --- libs/variant/test/rvalue_test.cpp (revision 85007) +++ libs/variant/test/rvalue_test.cpp (working copy) @@ -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,13 +182,26 @@ BOOST_CHECK(vi.which() == 1); } +void run_moves_are_noexcept() { +#ifndef BOOST_NO_CXX11_NOEXCEPT + typedef boost::variant variant_noexcept_t; + BOOST_CHECK(boost::is_nothrow_move_assignable::value); + BOOST_CHECK(boost::is_nothrow_move_constructible::value); + + typedef boost::variant variant_except_t; + BOOST_CHECK(!boost::is_nothrow_move_assignable::value); + BOOST_CHECK(!boost::is_nothrow_move_constructible::value); #endif +} +#endif + int test_main(int , char* []) { run(); run1(); run_move_only(); + run_moves_are_noexcept(); return 0; -} \ No newline at end of file +}