]> git.lyx.org Git - lyx.git/blobdiff - boost/boost/any.hpp
Cmake export tests: Handle attic files with now missing references to png graphics
[lyx.git] / boost / boost / any.hpp
index 013a83fec9e5a2cea62b35834d5d25bb6d8bf86f..437de2c02316010d8e7be56597ca97da75091432 100644 (file)
@@ -3,18 +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/throw_exception.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
 {
@@ -22,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))
         {
         }
 
@@ -38,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)
         {
@@ -58,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
         {
-            return content ? content->type() : typeid(void);
+            any().swap(*this);
+        }
+
+        const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
+        {
+            return content ? content->type() : boost::typeindex::type_id<void>().type_info();
         }
 
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -85,17 +151,17 @@ namespace boost
         class placeholder
         {
         public: // structors
-    
+
             virtual ~placeholder()
             {
             }
 
         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;
-    
+
         };
 
         template<typename ValueType>
@@ -108,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
@@ -124,6 +196,8 @@ namespace boost
 
             ValueType held;
 
+        private: // intentionally left unimplemented
+            holder & operator=(const holder &);
         };
 
 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
@@ -131,7 +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 *) BOOST_NOEXCEPT;
 
 #else
 
@@ -142,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";
@@ -154,36 +241,85 @@ 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>
-    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));
     }
 
     template<typename ValueType>
-    ValueType any_cast(const any & operand)
+    ValueType any_cast(any & operand)
     {
-        const ValueType * result = any_cast<ValueType>(&operand);
+        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
+
+
+        nonref * result = any_cast<nonref>(&operand);
         if(!result)
-            throw_exception(bad_any_cast());
-        return *result;
+            boost::throw_exception(bad_any_cast());
+
+        // 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));
     }
 
+#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
+
+
+    // 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
+    // use typeid() comparison, e.g., when our types may travel across
+    // different shared libraries.
+    template<typename ValueType>
+    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) BOOST_NOEXCEPT
+    {
+        return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
+    }
 }
 
 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
 //
-// Permission to use, copy, modify, and distribute this software for any
-// purpose is hereby granted without fee, provided that this copyright and
-// permissions notice appear in all copies and derivatives.
-//
-// This software is provided "as is" without express or implied warranty.
+// 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)
 
 #endif