Boost logo

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> &amp;&amp;</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-&gt;<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 &amp;&amp;</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> &amp;</type>
+
+ <parameter name="rhs">
+ <paramtype><classname>any</classname> &amp;&amp;</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-&gt;<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> &amp;</type>
+
+ <parameter name="rhs">
+ <paramtype>ValueType &amp;&amp;</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> &amp;</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