|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84086 - in branches/release: boost libs/any/doc libs/any/test
From: antoshkka_at_[hidden]
Date: 2013-04-29 14:34:45
Author: apolukhin
Date: 2013-04-29 14:34:42 EDT (Mon, 29 Apr 2013)
New Revision: 84086
URL: http://svn.boost.org/trac/boost/changeset/84086
Log:
Merge Boost.Any from trunk (fixes #6999)
Added:
branches/release/libs/any/doc/Jamfile.v2 (contents, props changed)
branches/release/libs/any/test/any_test_rv.cpp (contents, props changed)
Text files modified:
branches/release/boost/any.hpp | 84 ++++++++++++++++++++++++++++++++-------
branches/release/libs/any/doc/any.xml | 85 ++++++++++++++++++++++++++++++++++++---
branches/release/libs/any/test/Jamfile.v2 | 1
3 files changed, 147 insertions(+), 23 deletions(-)
Modified: branches/release/boost/any.hpp
==============================================================================
--- branches/release/boost/any.hpp (original)
+++ branches/release/boost/any.hpp 2013-04-29 14:34:42 EDT (Mon, 29 Apr 2013)
@@ -3,12 +3,16 @@
#ifndef BOOST_ANY_INCLUDED
#define BOOST_ANY_INCLUDED
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
// what: variant type boost::any
// who: contributed by Kevlin Henney,
// with features contributed and bugs found by
-// Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
-// when: July 2001
-// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
+// Antony Polukhin, Ed Brey, Mark Rodgers,
+// Peter Dimov, and James Curran
+// when: July 2001, Aplril 2013
#include <algorithm>
#include <typeinfo>
@@ -18,6 +22,8 @@
#include <boost/type_traits/is_reference.hpp>
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
// See boost/python/type_id.hpp
// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
@@ -36,7 +42,7 @@
{
public: // structors
- any()
+ any() BOOST_NOEXCEPT
: content(0)
{
}
@@ -52,19 +58,37 @@
{
}
- ~any()
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ // Move constructor
+ any(any&& other) BOOST_NOEXCEPT
+ : content(other.content)
+ {
+ other.content = 0;
+ }
+
+ // Perfect forwarding of ValueType
+ template<typename ValueType>
+ any(ValueType&& value, typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0)
+ : content(new holder< typename remove_reference<ValueType>::type >(static_cast<ValueType&&>(value)))
+ {
+ }
+#endif
+
+ ~any() BOOST_NOEXCEPT
{
delete content;
}
public: // modifiers
- any & swap(any & rhs)
+ any & swap(any & rhs) BOOST_NOEXCEPT
{
std::swap(content, rhs.content);
return *this;
}
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
template<typename ValueType>
any & operator=(const ValueType & rhs)
{
@@ -74,13 +98,37 @@
any & operator=(any rhs)
{
+ any(rhs).swap(*this);
+ return *this;
+ }
+
+#else
+ any & operator=(const any& rhs)
+ {
+ any(rhs).swap(*this);
+ return *this;
+ }
+
+ // move assignement
+ any & operator=(any&& rhs) BOOST_NOEXCEPT
+ {
rhs.swap(*this);
+ any().swap(rhs);
return *this;
}
+ // Perfect forwarding of ValueType
+ template <class ValueType>
+ any & operator=(ValueType&& rhs)
+ {
+ any(static_cast<ValueType&&>(rhs)).swap(*this);
+ return *this;
+ }
+#endif
+
public: // queries
- bool empty() const
+ bool empty() const BOOST_NOEXCEPT
{
return !content;
}
@@ -122,6 +170,12 @@
{
}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ holder(ValueType&& value)
+ : held(static_cast< ValueType&& >(value))
+ {
+ }
+#endif
public: // queries
virtual const std::type_info & type() const
@@ -147,10 +201,10 @@
private: // representation
template<typename ValueType>
- friend ValueType * any_cast(any *);
+ friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
template<typename ValueType>
- friend ValueType * unsafe_any_cast(any *);
+ friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
#else
@@ -161,8 +215,8 @@
placeholder * content;
};
-
- inline void swap(any & lhs, any & rhs)
+
+ inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
{
lhs.swap(rhs);
}
@@ -178,7 +232,7 @@
};
template<typename ValueType>
- ValueType * any_cast(any * operand)
+ ValueType * any_cast(any * operand) BOOST_NOEXCEPT
{
return operand &&
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
@@ -191,7 +245,7 @@
}
template<typename ValueType>
- inline const ValueType * any_cast(const any * operand)
+ inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
{
return any_cast<ValueType>(const_cast<any *>(operand));
}
@@ -237,13 +291,13 @@
// use typeid() comparison, e.g., when our types may travel across
// different shared libraries.
template<typename ValueType>
- inline ValueType * unsafe_any_cast(any * operand)
+ inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
{
return &static_cast<any::holder<ValueType> *>(operand->content)->held;
}
template<typename ValueType>
- inline const ValueType * unsafe_any_cast(const any * operand)
+ inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
{
return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
}
Added: branches/release/libs/any/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/release/libs/any/doc/Jamfile.v2 2013-04-29 14:34:42 EDT (Mon, 29 Apr 2013)
@@ -0,0 +1,9 @@
+# Copyright Antony Polukhin 2013. Use, modification, and distribution are
+# subject to 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)
+
+using boostbook ;
+
+boostbook standalone
+ : any.xml
+ : <xsl:param>boost.root=../../../.. ;
Modified: branches/release/libs/any/doc/any.xml
==============================================================================
--- branches/release/libs/any/doc/any.xml (original)
+++ branches/release/libs/any/doc/any.xml 2013-04-29 14:34:42 EDT (Mon, 29 Apr 2013)
@@ -237,13 +237,8 @@
<itemizedlist spacing="compact">
<listitem><simpara>A <emphasis>ValueType</emphasis> is
- <emphasis>CopyConstructible</emphasis> [20.1.3].</simpara>
- </listitem>
-
- <listitem><simpara>A <emphasis>ValueType</emphasis> is
- optionally <emphasis>Assignable</emphasis> [23.1]. The strong
- exception-safety guarantee is required for all forms of
- assignment.</simpara>
+ <emphasis>CopyConstructible</emphasis> [20.1.3] or
+ <emphasis>MoveConstructible</emphasis> in C++11.</simpara>
</listitem>
<listitem><simpara>The destructor for a
@@ -296,6 +291,19 @@
</constructor>
<constructor>
+ <parameter name="other">
+ <paramtype><classname>any</classname> &&</paramtype>
+ </parameter>
+
+ <effects><simpara> Move constructor that moves content of
+ <code>other</code> into new instance and leaves <code>other</code>
+ empty. </simpara></effects>
+ <precondition>C++11 compatible compiler.</precondition>
+ <postconditions><simpara><code>other-><methodname>empty</methodname>()</code></simpara></postconditions>
+ <throws><simpara>Nothing.</simpara></throws>
+ </constructor>
+
+ <constructor>
<template>
<template-type-parameter name="ValueType"/>
</template>
@@ -313,6 +321,26 @@
or any exceptions arising from the copy constructor of the
contained type.</simpara></throws>
</constructor>
+
+ <constructor>
+ <template>
+ <template-type-parameter name="ValueType"/>
+ </template>
+
+ <parameter name="value">
+ <paramtype>ValueType &&</paramtype>
+ </parameter>
+
+ <effects><simpara>Forwards <code>value</code>, so
+ that the initial content of the new instance is equivalent
+ in both type and value to
+ <code>value</code> before the forward.</simpara></effects>
+
+ <precondition>C++11 compatible compiler.</precondition>
+ <throws><simpara><code><classname>std::bad_alloc</classname></code>
+ or any exceptions arising from the copy constructor of the
+ contained type.</simpara></throws>
+ </constructor>
<destructor>
<effects><simpara>Releases any and all resources used in
@@ -338,6 +366,24 @@
contained type. Assignment satisfies the strong guarantee
of exception safety.</simpara></throws>
</copy-assignment>
+
+ <copy-assignment>
+ <type><classname>any</classname> &</type>
+
+ <parameter name="rhs">
+ <paramtype><classname>any</classname> &&</paramtype>
+ </parameter>
+
+ <effects><simpara>Moves content of <code>rhs</code> into
+ current instance, discarding previous content, so that the
+ new content is equivalent in both type and value to the
+ content of <code>rhs</code> before move, or empty if
+ <code>rhs.<methodname>empty</methodname>()</code>.</simpara></effects>
+
+ <precondition>C++11 compatible compiler.</precondition>
+ <postconditions><simpara><code>rhs-><methodname>empty</methodname>()</code></simpara></postconditions>
+ <throws><simpara>Nothing.</simpara></throws>
+ </copy-assignment>
<copy-assignment>
<template>
@@ -361,6 +407,29 @@
of exception safety.</simpara></throws>
</copy-assignment>
+ <copy-assignment>
+ <template>
+ <template-type-parameter name="ValueType"/>
+ </template>
+
+ <type><classname>any</classname> &</type>
+
+ <parameter name="rhs">
+ <paramtype>ValueType &&</paramtype>
+ </parameter>
+
+ <effects><simpara>Forwards <code>rhs</code>,
+ discarding previous content, so that the new content of is
+ equivalent in both type and value to
+ <code>rhs</code> before forward.</simpara></effects>
+
+ <precondition>C++11 compatible compiler.</precondition>
+ <throws><simpara><code><classname>std::bad_alloc</classname></code>
+ or any exceptions arising from the move or copy constructor of the
+ contained type. Assignment satisfies the strong guarantee
+ of exception safety.</simpara></throws>
+ </copy-assignment>
+
<method-group name="modifiers">
<method name="swap">
<type><classname>any</classname> &</type>
@@ -386,7 +455,7 @@
<returns><simpara><code>true</code> if instance is
empty, otherwise <code>false</code>.</simpara></returns>
- <throws><simpara>Will not throw.</simpara></throws>
+ <throws><simpara>Nothing.</simpara></throws>
</method>
<method name="type" cv="const">
Modified: branches/release/libs/any/test/Jamfile.v2
==============================================================================
--- branches/release/libs/any/test/Jamfile.v2 (original)
+++ branches/release/libs/any/test/Jamfile.v2 2013-04-29 14:34:42 EDT (Mon, 29 Apr 2013)
@@ -8,6 +8,7 @@
test-suite any :
[ run ../any_test.cpp ]
+ [ run any_test_rv.cpp ]
[ compile-fail any_cast_cv_failed.cpp ]
;
Added: branches/release/libs/any/test/any_test_rv.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/any/test/any_test_rv.cpp 2013-04-29 14:34:42 EDT (Mon, 29 Apr 2013)
@@ -0,0 +1,278 @@
+// Unit test for boost::any.
+//
+// See http://www.boost.org for most recent version, including documentation.
+//
+// Copyright Antony Polukhin, 2013.
+//
+// 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 <cstdlib>
+#include <string>
+#include <utility>
+
+#include "boost/any.hpp"
+#include "../test.hpp"
+#include <boost/move/move.hpp>
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+int main()
+{
+ return EXIT_SUCCESS;
+}
+
+#else
+
+namespace any_tests
+{
+ typedef test<const char *, void (*)()> test_case;
+ typedef const test_case * test_case_iterator;
+
+ extern const test_case_iterator begin, end;
+}
+
+int main()
+{
+ using namespace any_tests;
+ tester<test_case_iterator> test_suite(begin, end);
+ return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+namespace any_tests // test suite
+{
+ void test_move_construction();
+ void test_move_assignment();
+ void test_copy_construction();
+ void test_copy_assignment();
+
+ void test_move_construction_from_value();
+ void test_move_assignment_from_value();
+ void test_copy_construction_from_value();
+ void test_copy_assignment_from_value();
+
+
+ const test_case test_cases[] =
+ {
+ { "move construction of any", test_move_construction },
+ { "move assignment of any", test_move_assignment },
+ { "copy construction of any", test_copy_construction },
+ { "copy assignment of any", test_copy_assignment },
+
+ { "move construction from value", test_move_construction_from_value },
+ { "move assignment from value", test_move_assignment_from_value },
+ { "copy construction from value", test_copy_construction_from_value },
+ { "copy assignment from value", test_copy_assignment_from_value }
+ };
+
+ const test_case_iterator begin = test_cases;
+ const test_case_iterator end =
+ test_cases + (sizeof test_cases / sizeof *test_cases);
+
+
+ class move_copy_conting_class {
+ public:
+ static unsigned int moves_count;
+ static unsigned int copy_count;
+
+ move_copy_conting_class(){}
+ move_copy_conting_class(move_copy_conting_class&& /*param*/) {
+ ++ moves_count;
+ }
+
+ move_copy_conting_class& operator=(move_copy_conting_class&& /*param*/) {
+ ++ moves_count;
+ return *this;
+ }
+
+ move_copy_conting_class(const move_copy_conting_class&) {
+ ++ copy_count;
+ }
+ move_copy_conting_class& operator=(const move_copy_conting_class& /*param*/) {
+ ++ copy_count;
+ return *this;
+ }
+ };
+
+ unsigned int move_copy_conting_class::moves_count = 0;
+ unsigned int move_copy_conting_class::copy_count = 0;
+}
+
+namespace any_tests // test definitions
+{
+ using namespace boost;
+
+ void test_move_construction()
+ {
+ any value0 = move_copy_conting_class();
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+ any value(boost::move(value0));
+
+ check(value0.empty(), "moved away value is empty");
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+ check_equal(
+ move_copy_conting_class::copy_count, 0u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 0u,
+ "checking move counts");
+ }
+
+ void test_move_assignment()
+ {
+ any value0 = move_copy_conting_class();
+ any value = move_copy_conting_class();
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+ value = boost::move(value0);
+
+ check(value0.empty(), "moved away is empty");
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+ check_equal(
+ move_copy_conting_class::copy_count, 0u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 0u,
+ "checking move counts");
+ }
+
+ void test_copy_construction()
+ {
+ any value0 = move_copy_conting_class();
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+ any value(value0);
+
+ check_false(value0.empty(), "copyed value is not empty");
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+ check_equal(
+ move_copy_conting_class::copy_count, 1u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 0u,
+ "checking move counts");
+ }
+
+ void test_copy_assignment()
+ {
+ any value0 = move_copy_conting_class();
+ any value = move_copy_conting_class();
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+ value = value0;
+
+ check_false(value0.empty(), "copyied value is not empty");
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+ check_equal(
+ move_copy_conting_class::copy_count, 1u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 0u,
+ "checking move counts");
+ }
+
+ void test_move_construction_from_value()
+ {
+ move_copy_conting_class value0;
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ any value(boost::move(value0));
+#else
+ any value(value0);
+#endif
+
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ check_equal(
+ move_copy_conting_class::copy_count, 0u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 1u,
+ "checking move counts");
+#endif
+
+ }
+
+ void test_move_assignment_from_value()
+ {
+ move_copy_conting_class value0;
+ any value;
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ value = boost::move(value0);
+#else
+ value = value0;
+#endif
+
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ check_equal(
+ move_copy_conting_class::copy_count, 0u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 1u,
+ "checking move counts");
+#endif
+
+ }
+
+ void test_copy_construction_from_value()
+ {
+ move_copy_conting_class value0;
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+ any value(value0);
+
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+
+ check_equal(
+ move_copy_conting_class::copy_count, 1u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 0u,
+ "checking move counts");
+ }
+
+ void test_copy_assignment_from_value()
+ {
+ move_copy_conting_class value0;
+ any value;
+ move_copy_conting_class::copy_count = 0;
+ move_copy_conting_class::moves_count = 0;
+ value = value0;
+
+ check_false(value.empty(), "empty");
+ check_equal(value.type(), typeid(move_copy_conting_class), "type");
+ check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
+
+ check_equal(
+ move_copy_conting_class::copy_count, 1u,
+ "checking copy counts");
+ check_equal(
+ move_copy_conting_class::moves_count, 0u,
+ "checking move counts");
+ }
+}
+
+#endif
+
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