]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/any.hpp
Cmake export tests: More tests to be inverted, suspended or made non-standard
[lyx.git] / boost / boost / any.hpp
index 483daca32e62e306ba8e9512178a3e1efec49f08..437de2c02316010d8e7be56597ca97da75091432 100644 (file)
@@ -3,21 +3,33 @@
 #ifndef BOOST_ANY_INCLUDED
 #define BOOST_ANY_INCLUDED
 
+#if defined(_MSC_VER)
+# 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, April 2013 - May 2013
 
 #include <algorithm>
-#include <typeinfo>
 
 #include "boost/config.hpp"
+#include <boost/type_index.hpp>
 #include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/remove_cv.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>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/mpl/if.hpp>
 
 namespace boost
 {
@@ -25,14 +37,16 @@ namespace boost
     {
     public: // structors
 
-        any()
+        any() BOOST_NOEXCEPT
           : content(0)
         {
         }
 
         template<typename ValueType>
         any(const ValueType & value)
-          : content(new holder<ValueType>(value))
+          : content(new holder<
+                BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
+            >(value))
         {
         }
 
@@ -41,19 +55,39 @@ namespace boost
         {
         }
 
-        ~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 // disable if value has type `any&`
+            , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
+          : content(new holder< typename decay<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)
         {
@@ -61,22 +95,51 @@ namespace boost
             return *this;
         }
 
-        any & operator=(const any & rhs)
+        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;
         }
 
-        const std::type_info & type() const
+        void clear() BOOST_NOEXCEPT
+        {
+            any().swap(*this);
+        }
+
+        const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
         {
-            return content ? content->type() : typeid(void);
+            return content ? content->type() : boost::typeindex::type_id<void>().type_info();
         }
 
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -95,7 +158,7 @@ namespace boost
 
         public: // queries
 
-            virtual const std::type_info & type() const = 0;
+            virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;
 
             virtual placeholder * clone() const = 0;
 
@@ -111,11 +174,17 @@ namespace boost
             {
             }
 
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+            holder(ValueType&& value)
+              : held(static_cast< ValueType&& >(value))
+            {
+            }
+#endif
         public: // queries
 
-            virtual const std::type_info & type() const
+            virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
             {
-                return typeid(ValueType);
+                return boost::typeindex::type_id<ValueType>().type_info();
             }
 
             virtual placeholder * clone() const
@@ -136,10 +205,10 @@ namespace boost
     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
 
@@ -150,11 +219,21 @@ namespace boost
         placeholder * content;
 
     };
+    inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
+    {
+        lhs.swap(rhs);
+    }
 
-    class bad_any_cast : public std::bad_cast
+    class BOOST_SYMBOL_VISIBLE bad_any_cast :
+#ifndef BOOST_NO_RTTI
+        public std::bad_cast
+#else
+        public std::exception
+#endif
     {
     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";
@@ -162,15 +241,15 @@ namespace boost
     };
 
     template<typename ValueType>
-    ValueType * any_cast(any * operand)
+    ValueType * any_cast(any * operand) BOOST_NOEXCEPT
     {
-        return operand && operand->type() == typeid(ValueType)
-                    ? &static_cast<any::holder<ValueType> *>(operand->content)->held
-                    : 0;
+        return operand && operand->type() == boost::typeindex::type_id<ValueType>()
+            ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
+            : 0;
     }
 
     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));
     }
@@ -180,35 +259,44 @@ namespace boost
     {
         typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
 
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-        // If 'nonref' is still reference type, it means the user has not
-        // specialized 'remove_reference'.
-
-        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
-        // to generate specialization of remove_reference for your class
-        // See type traits library documentation for details
-        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
-#endif
 
         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>
     inline ValueType any_cast(const any & operand)
     {
         typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
+        return any_cast<const nonref &>(const_cast<any &>(operand));
+    }
 
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-        // The comment in the above version of 'any_cast' explains when this
-        // assert is fired and what to do.
-        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
+#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 /*true if ValueType is rvalue or just a 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
 
-        return any_cast<const nonref &>(const_cast<any &>(operand));
-    }
 
     // Note: The "unsafe" versions of any_cast are not part of the
     // public interface and may be removed at any time. They are
@@ -216,13 +304,13 @@ namespace boost
     // 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));
     }