[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost-commit
Subject:    [Boost-commit] svn:boost r85151 - in branches/release: boost libs/any libs/any/test
From:       antoshkka () gmail ! com
Date:       2013-07-24 15:01:41
Message-ID: 20130724150141.E3D461601FA () wowbagger ! crest ! iu ! edu
[Download RAW message or body]

Author: apolukhin
Date: 2013-07-24 11:01:41 EDT (Wed, 24 Jul 2013)
New Revision: 85151
URL: http://svn.boost.org/trac/boost/changeset/85151

Log:
Merge from trunk:
* bad_any_cast exception is now visible across modules (fixes #8751)
* portion of optimizations and tests for rvalues
* added ability to call any_cast<T&&> (which is equivalent to \
                std::move(any_cast<T&>))
* added clear() member function
* added missing BOOST_NOEXCEPT

Text files modified: 
   branches/release/boost/any.hpp                 |    60 \
++++++++++++++++++++++++++++++++++------  branches/release/libs/any/any_test.cpp      \
|    56 ++++++++++++++++++++++++++++++++++++      \
branches/release/libs/any/test/any_test_rv.cpp |    39 +++++++++++++++++++++++++      \
  3 files changed, 144 insertions(+), 11 deletions(-)

Modified: branches/release/boost/any.hpp
==============================================================================
--- branches/release/boost/any.hpp	Wed Jul 24 09:14:00 2013	(r85150)
+++ branches/release/boost/any.hpp	2013-07-24 11:01:41 EDT (Wed, 24 Jul \
2013)	(r85151) @@ -12,14 +12,17 @@
 //        with features contributed and bugs found by
 //        Antony Polukhin, Ed Brey, Mark Rodgers, 
 //        Peter Dimov, and James Curran
-// when:  July 2001, Aplril 2013
+// when:  July 2001, April 2013 - May 2013
 
 #include <algorithm>
 #include <typeinfo>
 
 #include "boost/config.hpp"
 #include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/add_reference.hpp>
 #include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_const.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/utility/enable_if.hpp>
@@ -36,6 +39,11 @@
 #include <cstring>
 # endif 
 
+#if defined(_MSC_VER) 
+#pragma warning(push)
+#pragma warning(disable: 4172) // Mistakenly warns: returning address of local \
variable or temporary +#endif
+
 namespace boost
 {
     class any
@@ -49,7 +57,7 @@
 
         template<typename ValueType>
         any(const ValueType & value)
-          : content(new holder<ValueType>(value))
+          : content(new holder<BOOST_DEDUCED_TYPENAME decay<const \
ValueType>::type>(value))  {
         }
 
@@ -69,7 +77,7 @@
         // 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))) +          : content(new holder< typename \
> decay<ValueType>::type >(static_cast<ValueType&&>(value)))
         {
         }
 #endif
@@ -133,7 +141,12 @@
             return !content;
         }
 
-        const std::type_info & type() const
+        void clear() BOOST_NOEXCEPT
+        {
+            any().swap(*this);
+        }
+
+        const std::type_info & type() const BOOST_NOEXCEPT
         {
             return content ? content->type() : typeid(void);
         }
@@ -154,7 +167,7 @@
 
         public: // queries
 
-            virtual const std::type_info & type() const = 0;
+            virtual const std::type_info & type() const BOOST_NOEXCEPT = 0;
 
             virtual placeholder * clone() const = 0;
 
@@ -178,7 +191,7 @@
 #endif
         public: // queries
 
-            virtual const std::type_info & type() const
+            virtual const std::type_info & type() const BOOST_NOEXCEPT
             {
                 return typeid(ValueType);
             }
@@ -221,10 +234,10 @@
         lhs.swap(rhs);
     }
 
-    class bad_any_cast : public std::bad_cast
+    class BOOST_SYMBOL_VISIBLE bad_any_cast : public std::bad_cast
     {
     public:
-        virtual const char * what() const throw()
+        virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
         {
             return "boost::bad_any_cast: "
                    "failed conversion using boost::any_cast";
@@ -268,7 +281,18 @@
         nonref * result = any_cast<nonref>(&operand);
         if(!result)
             boost::throw_exception(bad_any_cast());
-        return *result;
+
+        // Attempt to avoid construction of a temporary object in cases when 
+        // `ValueType` is not a reference. Example:
+        // `static_cast<std::string>(*result);` 
+        // which is equal to `std::string(*result);`
+        typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
+            boost::is_reference<ValueType>,
+            ValueType,
+            BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
+        >::type ref_type;
+
+        return static_cast<ref_type>(*result);
     }
 
     template<typename ValueType>
@@ -285,6 +309,20 @@
         return any_cast<const nonref &>(const_cast<any &>(operand));
     }
 
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template<typename ValueType>
+    inline ValueType&& any_cast(any&& operand)
+    {
+        BOOST_STATIC_ASSERT_MSG(
+            boost::is_rvalue_reference<ValueType&&>::value 
+            || boost::is_const< typename boost::remove_reference<ValueType>::type \
>::value, +            "boost::any_cast shall not be used for getting nonconst \
> references to temporary objects" 
+        );
+        return any_cast<ValueType&&>(operand);
+    }
+#endif
+
+
     // Note: The "unsafe" versions of any_cast are not part of the
     // public interface and may be removed at any time. They are
     // required where we know what type is stored in the any and can't
@@ -309,4 +347,8 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
 #endif

Modified: branches/release/libs/any/any_test.cpp
==============================================================================
--- branches/release/libs/any/any_test.cpp	Wed Jul 24 09:14:00 2013	(r85150)
+++ branches/release/libs/any/any_test.cpp	2013-07-24 11:01:41 EDT (Wed, 24 Jul \
2013)	(r85151) @@ -36,6 +36,8 @@
     void test_swap();
     void test_null_copying();
     void test_cast_to_reference();
+    void test_with_array();
+    void test_with_func();
 
     const test_case test_cases[] =
     {
@@ -47,7 +49,9 @@
         { "failed custom keyword cast",     test_bad_cast          },
         { "swap member function",           test_swap              },
         { "copying operations on a null",   test_null_copying      },
-        { "cast to reference types",        test_cast_to_reference }
+        { "cast to reference types",        test_cast_to_reference },
+        { "storing an array inside",        test_with_array        },
+        { "implicit cast of returned value",test_with_func         }
     };
 
     const test_case_iterator begin = test_cases;
@@ -249,6 +253,56 @@
             "any_cast to incorrect const reference type");
     }
 
+    void test_with_array()
+    {
+        any value1("Char array");
+        any value2;
+        value2 = "Char array";
+
+        check_false(value1.empty(), "type");
+        check_false(value2.empty(), "type");
+
+        check_equal(value1.type(), typeid(const char*), "type");
+        check_equal(value2.type(), typeid(const char*), "type");
+        
+        check_non_null(any_cast<const char*>(&value1), "any_cast<const char*>");
+        check_non_null(any_cast<const char*>(&value2), "any_cast<const char*>");
+    }
+
+    const std::string& returning_string1() 
+    {
+        static const std::string ret("foo"); 
+        return ret;
+    }
+
+    std::string returning_string2() 
+    {
+        static const std::string ret("foo"); 
+        return ret;
+    }
+
+    void test_with_func()
+    {
+        std::string s;
+        s = any_cast<std::string>(returning_string1());
+        s = any_cast<const std::string&>(returning_string1());
+        //s = any_cast<std::string&>(returning_string1());
+
+        s = any_cast<std::string>(returning_string2());
+        s = any_cast<const std::string&>(returning_string2());
+        //s = any_cast<std::string&>(returning_string2());
+
+#if !defined(_MSC_VER) || _MSC_VER != 1600
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+        //s = static_cast<std::string&&>(any_cast<std::string&>(returning_string1()));
 +        s = any_cast<std::string&&>(returning_string1());
+
+        //s = static_cast<std::string&&>(any_cast<std::string&>(returning_string2()));
 +        s = any_cast<std::string&&>(returning_string2());
+#endif
+#endif
+    }
+
 }
 
 // Copyright Kevlin Henney, 2000, 2001. All rights reserved.

Modified: branches/release/libs/any/test/any_test_rv.cpp
==============================================================================
--- branches/release/libs/any/test/any_test_rv.cpp	Wed Jul 24 09:14:00 2013	(r85150)
+++ branches/release/libs/any/test/any_test_rv.cpp	2013-07-24 11:01:41 EDT (Wed, 24 \
Jul 2013)	(r85151) @@ -51,6 +51,7 @@
     void test_move_assignment_from_value();
     void test_copy_construction_from_value();
     void test_copy_assignment_from_value();
+    void test_cast_to_rv();
     
 
     const test_case test_cases[] =
@@ -63,7 +64,8 @@
         { "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  }
+        { "copy assignment from value",           test_copy_assignment_from_value },
+        { "casting to rvalue reference",          test_cast_to_rv }
     };
 
     const test_case_iterator begin = test_cases;
@@ -272,6 +274,41 @@
             move_copy_conting_class::moves_count, 0u, 
             "checking move counts");
     }
+
+    void test_cast_to_rv()
+    {
+        move_copy_conting_class value0;
+        any value;
+        value = value0;
+        move_copy_conting_class::copy_count = 0; 
+        move_copy_conting_class::moves_count = 0;
+
+        move_copy_conting_class value1 = any_cast<move_copy_conting_class&&>(value);
+
+        check_equal(
+            move_copy_conting_class::copy_count, 0u, 
+            "checking copy counts");
+        check_equal(
+            move_copy_conting_class::moves_count, 1u, 
+            "checking move counts");
+        (void)value1;
+/* Following code shall fail to compile
+        const any cvalue = value0;
+        move_copy_conting_class::copy_count = 0; 
+        move_copy_conting_class::moves_count = 0;
+
+        move_copy_conting_class value2 = \
any_cast<move_copy_conting_class&&>(cvalue); +
+        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)value2;
+*/
+    }
+    
 }
 
 #endif
_______________________________________________
Boost-commit mailing list
Boost-commit@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-commit


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic