|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r85157 - in branches/release: boost/variant libs/variant/test
From: antoshkka_at_[hidden]
Date: 2013-07-25 04:42:44
Author: apolukhin
Date: 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013)
New Revision: 85157
URL: http://svn.boost.org/trac/boost/changeset/85157
Log:
Merge from trunk:
* make the library work on exception-disabled environments (fixes #8717)
* fix compilation of Boost.Variants move assignment for situations when one of the variant template classes has nothrow copy constructor and throwing move constructor (fixes #8772)
* mark move constructor of variant with BOOST_NOEXCEPT_IF (refs #7911)
Text files modified:
branches/release/boost/variant/get.hpp | 7 ++-
branches/release/boost/variant/variant.hpp | 68 +++++++++++++++++++++++++++++----------
branches/release/boost/variant/visitor_ptr.hpp | 3 +
branches/release/libs/variant/test/Jamfile.v2 | 11 ++++++
branches/release/libs/variant/test/recursive_variant_test.cpp | 35 ++++++++++++++++++-
branches/release/libs/variant/test/rvalue_test.cpp | 42 ++++++++++++++++++++++-
6 files changed, 138 insertions(+), 28 deletions(-)
Modified: branches/release/boost/variant/get.hpp
==============================================================================
--- branches/release/boost/variant/get.hpp Thu Jul 25 03:21:21 2013 (r85156)
+++ branches/release/boost/variant/get.hpp 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013) (r85157)
@@ -17,6 +17,7 @@
#include "boost/config.hpp"
#include "boost/detail/workaround.hpp"
+#include "boost/throw_exception.hpp"
#include "boost/utility/addressof.hpp"
#include "boost/variant/variant_fwd.hpp"
@@ -41,7 +42,7 @@
{
public: // std::exception implementation
- virtual const char * what() const throw()
+ virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
{
return "boost::bad_get: "
"failed value get using boost::get";
@@ -177,7 +178,7 @@
U_ptr result = get<U>(&operand);
if (!result)
- throw bad_get();
+ boost::throw_exception(bad_get());
return *result;
}
@@ -193,7 +194,7 @@
U_ptr result = get<const U>(&operand);
if (!result)
- throw bad_get();
+ boost::throw_exception(bad_get());
return *result;
}
Modified: branches/release/boost/variant/variant.hpp
==============================================================================
--- branches/release/boost/variant/variant.hpp Thu Jul 25 03:21:21 2013 (r85156)
+++ branches/release/boost/variant/variant.hpp 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013) (r85157)
@@ -3,13 +3,15 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
-// Copyright (c) 2002-2003
-// Eric Friedman, Itay Maman
+// Copyright (c) 2002-2003 Eric Friedman, Itay Maman
+// 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
// http://www.boost.org/LICENSE_1_0.txt)
+// Thanks to Adam Romanek for providing patches for exception-disabled env.
+
#ifndef BOOST_VARIANT_VARIANT_HPP
#define BOOST_VARIANT_VARIANT_HPP
@@ -37,6 +39,7 @@
#include "boost/variant/detail/generic_result_type.hpp"
#include "boost/variant/detail/move.hpp"
+#include "boost/detail/no_exceptions_support.hpp"
#include "boost/detail/reference_content.hpp"
#include "boost/aligned_storage.hpp"
#include "boost/blank.hpp"
@@ -226,6 +229,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
//
@@ -770,12 +792,12 @@
// ...destroy lhs content...
lhs_content.~LhsT(); // nothrow
- try
+ BOOST_TRY
{
// ...and attempt to copy rhs content into lhs storage:
copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
}
- catch (...)
+ BOOST_CATCH (...)
{
// In case of failure, restore backup content to lhs storage...
new(lhs_.storage_.address())
@@ -784,8 +806,9 @@
); // nothrow
// ...and rethrow:
- throw;
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
// In case of success, indicate new content type:
lhs_.indicate_which(rhs_which_); // nothrow
@@ -803,12 +826,12 @@
// ...destroy lhs content...
lhs_content.~LhsT(); // nothrow
- try
+ BOOST_TRY
{
// ...and attempt to copy rhs content into lhs storage:
copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
}
- catch (...)
+ BOOST_CATCH (...)
{
// In case of failure, copy backup pointer to lhs storage...
new(lhs_.storage_.address())
@@ -818,8 +841,9 @@
lhs_.indicate_backup_which( lhs_.which() ); // nothrow
// ...and rethrow:
- throw;
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
// In case of success, indicate new content type...
lhs_.indicate_which(rhs_which_); // nothrow
@@ -1289,6 +1313,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 +1405,7 @@
public: // structors
- ~variant()
+ ~variant() BOOST_NOEXCEPT
{
destroy_content();
}
@@ -1766,7 +1796,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() );
@@ -1860,13 +1890,13 @@
// Destroy lhs's content...
lhs_.destroy_content(); // nothrow
- try
+ BOOST_TRY
{
// ...and attempt to copy rhs's content into lhs's storage:
new(lhs_.storage_.address())
RhsT( rhs_content );
}
- catch (...)
+ BOOST_CATCH (...)
{
// In case of failure, default-construct fallback type in lhs's storage...
new (lhs_.storage_.address())
@@ -1878,8 +1908,9 @@
); // nothrow
// ...and rethrow:
- throw;
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
// In the event of success, indicate new content type:
lhs_.indicate_which(rhs_which_); // nothrow
@@ -1955,7 +1986,7 @@
private: // helpers, for internal visitor interface (below)
- template <typename RhsT, typename B1, typename B2>
+ template <typename RhsT, typename B2>
void assign_impl(
RhsT& rhs_content
, mpl::true_ // has_nothrow_copy
@@ -2004,13 +2035,13 @@
// Destroy lhs's content...
lhs_.destroy_content(); // nothrow
- try
+ BOOST_TRY
{
// ...and attempt to copy rhs's content into lhs's storage:
new(lhs_.storage_.address())
RhsT( detail::variant::move(rhs_content) );
}
- catch (...)
+ BOOST_CATCH (...)
{
// In case of failure, default-construct fallback type in lhs's storage...
new (lhs_.storage_.address())
@@ -2022,8 +2053,9 @@
); // nothrow
// ...and rethrow:
- throw;
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
// In the event of success, indicate new content type:
lhs_.indicate_which(rhs_which_); // nothrow
@@ -2177,7 +2209,7 @@
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- variant& operator=(variant&& rhs)
+ variant& operator=(variant&& rhs) // BOOST_NOEXCEPT_IF(variant_move_noexcept::type::value && all move assign operators are noexcept)
{
variant_assign( detail::variant::move(rhs) );
return *this;
Modified: branches/release/boost/variant/visitor_ptr.hpp
==============================================================================
--- branches/release/boost/variant/visitor_ptr.hpp Thu Jul 25 03:21:21 2013 (r85156)
+++ branches/release/boost/variant/visitor_ptr.hpp 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013) (r85157)
@@ -18,6 +18,7 @@
#include "boost/mpl/eval_if.hpp"
#include "boost/mpl/identity.hpp"
+#include "boost/throw_exception.hpp"
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/is_reference.hpp"
#include "boost/type_traits/is_void.hpp"
@@ -64,7 +65,7 @@
template <typename U>
result_type operator()(const U&) const
{
- throw bad_visit();
+ boost::throw_exception(bad_visit());
}
#if !defined(BOOST_NO_VOID_RETURNS)
Modified: branches/release/libs/variant/test/Jamfile.v2
==============================================================================
--- branches/release/libs/variant/test/Jamfile.v2 Thu Jul 25 03:21:21 2013 (r85156)
+++ branches/release/libs/variant/test/Jamfile.v2 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013) (r85157)
@@ -1,6 +1,7 @@
# Boost.Variant Library test Jamfile
#
# Copyright (C) 2003, Eric Friedman, Itay Maman.
+# Copyright (C) 2013, Antony Polukhin.
#
# This material is provided "as is", with absolutely no warranty expressed
# or implied. Any use is at your own risk.
@@ -35,6 +36,16 @@
[ run variant_multivisit_test.cpp ]
[ run hash_variant_test.cpp ]
[ run rvalue_test.cpp ]
+ [ run recursive_variant_test.cpp : : : <define>BOOST_NO_EXCEPTIONS
+ <toolset>gcc-4.3:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.4:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.5:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.6:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.7:<cxxflags>-fno-exceptions
+ <toolset>gcc-4.8:<cxxflags>-fno-exceptions
+ <toolset>clang:<cxxflags>-fno-exceptions
+ : variant_noexcept_test
+ ]
;
Modified: branches/release/libs/variant/test/recursive_variant_test.cpp
==============================================================================
--- branches/release/libs/variant/test/recursive_variant_test.cpp Thu Jul 25 03:21:21 2013 (r85156)
+++ branches/release/libs/variant/test/recursive_variant_test.cpp 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013) (r85157)
@@ -3,14 +3,43 @@
// See http://www.boost.org for updates, documentation, and revision history.
//-----------------------------------------------------------------------------
//
-// Copyright (c) 2003
-// Eric Friedman, Itay Maman
+// Copyright (c) 2003 Eric Friedman, Itay Maman
+// Copyright (c) 2013 Antony Polukhin
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
-#include "boost/test/minimal.hpp"
+
+// This file is used in two test cases:
+//
+// 1) recursive_variant_test.cpp that tests recursive usage of variant
+//
+// 2) variant_noexcept_test that tests Boost.Variant ability to compile
+// and work with disabled exceptions
+
+#ifdef BOOST_NO_EXCEPTIONS
+// `boost/test/minimal.hpp` cannot work with exceptions disabled,
+// so we need the following workarounds for that case:
+namespace boost {
+ int exit_success = 0;
+}
+
+int test_main(int , char* []);
+
+int main( int argc, char* argv[] )
+{
+ return test_main(argc, argv);
+}
+
+#include <stdlib.h>
+#define BOOST_CHECK(exp) if (!(exp)) exit(EXIT_FAILURE)
+
+#else // BOOST_NO_EXCEPTIONS
+# include "boost/test/minimal.hpp"
+#endif // BOOST_NO_EXCEPTIONS
+
+
#include "boost/variant.hpp"
#include "boost/mpl/vector.hpp"
#include "boost/mpl/copy.hpp"
Modified: branches/release/libs/variant/test/rvalue_test.cpp
==============================================================================
--- branches/release/libs/variant/test/rvalue_test.cpp Thu Jul 25 03:21:21 2013 (r85156)
+++ branches/release/libs/variant/test/rvalue_test.cpp 2013-07-25 04:42:44 EDT (Thu, 25 Jul 2013) (r85157)
@@ -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,44 @@
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
+
+struct nothrow_copyable_throw_movable {
+ nothrow_copyable_throw_movable(){}
+ nothrow_copyable_throw_movable(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT {}
+ nothrow_copyable_throw_movable& operator=(const nothrow_copyable_throw_movable&) BOOST_NOEXCEPT { return *this; }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ nothrow_copyable_throw_movable(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) {}
+ nothrow_copyable_throw_movable& operator=(nothrow_copyable_throw_movable&&) BOOST_NOEXCEPT_IF(false) { return *this; }
+#endif
+};
+
+// This test is created to cover the following situation:
+// https://svn.boost.org/trac/boost/ticket/8772
+void run_tricky_compilation_test()
+{
+ boost::variant<int, nothrow_copyable_throw_movable> v;
+ v = nothrow_copyable_throw_movable();
+}
int test_main(int , char* [])
{
run();
run1();
run_move_only();
+ run_moves_are_noexcept();
+ run_tricky_compilation_test();
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