Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:53

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2012-2012.
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // See http://www.boost.org/libs/move for documentation.
0009 //
0010 //////////////////////////////////////////////////////////////////////////////
0011 
0012 //! \file
0013 //! This header implements macros to define movable classes and
0014 //! move-aware functions
0015 
0016 #ifndef BOOST_MOVE_CORE_HPP
0017 #define BOOST_MOVE_CORE_HPP
0018 
0019 #ifndef BOOST_CONFIG_HPP
0020 #  include <boost/config.hpp>
0021 #endif
0022 #
0023 #if defined(BOOST_HAS_PRAGMA_ONCE)
0024 #  pragma once
0025 #endif
0026 
0027 #include <boost/move/detail/config_begin.hpp>
0028 #include <boost/move/detail/workaround.hpp>
0029 
0030 // @cond
0031 
0032 //boost_move_no_copy_constructor_or_assign typedef
0033 //used to detect noncopyable types for other Boost libraries.
0034 #if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0035    #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
0036       private:\
0037       TYPE(TYPE &);\
0038       TYPE& operator=(TYPE &);\
0039       public:\
0040       typedef int boost_move_no_copy_constructor_or_assign; \
0041       private:\
0042    //
0043 #else
0044    #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
0045       public:\
0046       TYPE(TYPE const &) = delete;\
0047       TYPE& operator=(TYPE const &) = delete;\
0048       public:\
0049       typedef int boost_move_no_copy_constructor_or_assign; \
0050       private:\
0051    //
0052 #endif   //BOOST_NO_CXX11_DELETED_FUNCTIONS
0053 
0054 // @endcond
0055 
0056 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
0057 
0058    #include <boost/move/detail/type_traits.hpp>
0059 
0060    #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG)
0061    #define BOOST_MOVE_TO_LV_CAST(LV_TYPE, ARG) static_cast<LV_TYPE>(ARG)
0062 
0063    //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
0064    #if defined(BOOST_GCC) && (BOOST_GCC >= 40400) && (BOOST_GCC < 40500)
0065    #define BOOST_RV_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
0066    #else
0067    #define BOOST_RV_ATTRIBUTE_MAY_ALIAS 
0068    #endif
0069 
0070    namespace boost {
0071 
0072    //////////////////////////////////////////////////////////////////////////////
0073    //
0074    //                            struct rv
0075    //
0076    //////////////////////////////////////////////////////////////////////////////
0077    template <class T>
0078    class BOOST_RV_ATTRIBUTE_MAY_ALIAS rv
0079       : public ::boost::move_detail::if_c
0080          < ::boost::move_detail::is_class<T>::value
0081          , T
0082          , ::boost::move_detail::nat
0083          >::type
0084    {
0085       rv();
0086       ~rv() throw();
0087       rv(rv const&);
0088       void operator=(rv const&);
0089    };
0090 
0091 
0092    //////////////////////////////////////////////////////////////////////////////
0093    //
0094    //                            is_rv
0095    //
0096    //////////////////////////////////////////////////////////////////////////////
0097 
0098    namespace move_detail {
0099 
0100    template <class T>
0101    struct is_rv
0102         //Derive from integral constant because some Boost code assummes it has
0103         //a "type" internal typedef
0104       : integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
0105    {};
0106 
0107    template <class T>
0108    struct is_not_rv
0109    {
0110       static const bool value = !is_rv<T>::value;
0111    };
0112 
0113    }  //namespace move_detail {
0114 
0115    //////////////////////////////////////////////////////////////////////////////
0116    //
0117    //                               has_move_emulation_enabled
0118    //
0119    //////////////////////////////////////////////////////////////////////////////
0120    template<class T>
0121    struct has_move_emulation_enabled
0122       : ::boost::move_detail::has_move_emulation_enabled_impl<T>
0123    {};
0124 
0125    template<class T>
0126    struct has_move_emulation_disabled
0127    {
0128       static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl<T>::value;
0129    };
0130 
0131    }  //namespace boost {
0132 
0133    #define BOOST_RV_REF(TYPE)\
0134       ::boost::rv< TYPE >& \
0135    //
0136 
0137    #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
0138       ::boost::rv< TYPE<ARG1, ARG2> >& \
0139    //
0140 
0141    #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
0142       ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
0143    //
0144 
0145    #define BOOST_RV_REF_BEG\
0146       ::boost::rv<   \
0147    //
0148 
0149    #define BOOST_RV_REF_END\
0150       >& \
0151    //
0152 
0153    #define BOOST_RV_REF_BEG_IF_CXX11 \
0154       \
0155    //
0156 
0157    #define BOOST_RV_REF_END_IF_CXX11 \
0158       \
0159    //
0160 
0161    #define BOOST_FWD_REF(TYPE)\
0162       const TYPE & \
0163    //
0164 
0165    #define BOOST_COPY_ASSIGN_REF(TYPE)\
0166       const ::boost::rv< TYPE >& \
0167    //
0168 
0169    #define BOOST_COPY_ASSIGN_REF_BEG \
0170       const ::boost::rv<  \
0171    //
0172 
0173    #define BOOST_COPY_ASSIGN_REF_END \
0174       >& \
0175    //
0176 
0177    #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
0178       const ::boost::rv< TYPE<ARG1, ARG2> >& \
0179    //
0180 
0181    #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
0182       const ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
0183    //
0184 
0185    #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
0186       const ::boost::rv< TYPE >& \
0187    //
0188 
0189    namespace boost {
0190    namespace move_detail {
0191 
0192    template <class Ret, class T>
0193    BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
0194       <  ::boost::move_detail::is_lvalue_reference<Ret>::value ||
0195         !::boost::has_move_emulation_enabled<T>::value
0196       , T&>::type
0197          move_return(T& x) BOOST_NOEXCEPT
0198    {
0199       return x;
0200    }
0201 
0202    template <class Ret, class T>
0203    BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
0204       < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
0205          ::boost::has_move_emulation_enabled<T>::value
0206       , ::boost::rv<T>&>::type
0207          move_return(T& x) BOOST_NOEXCEPT
0208    {
0209       return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x));
0210    }
0211 
0212    template <class Ret, class T>
0213    BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
0214       < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
0215          ::boost::has_move_emulation_enabled<T>::value
0216       , ::boost::rv<T>&>::type
0217          move_return(::boost::rv<T>& x) BOOST_NOEXCEPT
0218    {
0219       return x;
0220    }
0221 
0222    template <class T>
0223    BOOST_MOVE_FORCEINLINE T& unrv(::boost::rv<T> &rv) BOOST_NOEXCEPT
0224    {  return BOOST_MOVE_TO_LV_CAST(T&, rv);   }
0225 
0226    }  //namespace move_detail {
0227    }  //namespace boost {
0228 
0229    #define BOOST_MOVE_RET(RET_TYPE, REF)\
0230       boost::move_detail::move_return< RET_TYPE >(REF)
0231    //
0232 
0233    #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
0234       ::boost::move((BASE_TYPE&)(ARG))
0235    //
0236 
0237    #define BOOST_MOVE_TO_LV(ARG) \
0238       ::boost::move_detail::unrv(ARG)
0239    //
0240 
0241 
0242    //////////////////////////////////////////////////////////////////////////////
0243    //
0244    //                         BOOST_MOVABLE_BUT_NOT_COPYABLE
0245    //
0246    //////////////////////////////////////////////////////////////////////////////
0247    #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
0248       BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
0249       public:\
0250       BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
0251       {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
0252       BOOST_MOVE_FORCEINLINE operator const ::boost::rv<TYPE>&() const \
0253       {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
0254       private:\
0255    //
0256 
0257    //////////////////////////////////////////////////////////////////////////////
0258    //
0259    //                         BOOST_COPYABLE_AND_MOVABLE
0260    //
0261    //////////////////////////////////////////////////////////////////////////////
0262 
0263    #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
0264       public:\
0265       BOOST_MOVE_FORCEINLINE TYPE& operator=(TYPE &t)\
0266       {  this->operator=(const_cast<const TYPE&>(t)); return *this;}\
0267       public:\
0268       BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
0269       {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
0270       BOOST_MOVE_FORCEINLINE operator const ::boost::rv<TYPE>&() const \
0271       {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
0272       private:\
0273    //
0274 
0275    #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
0276       public:\
0277       BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
0278       {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
0279       BOOST_MOVE_FORCEINLINE operator const ::boost::rv<TYPE>&() const \
0280       {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
0281       private:\
0282    //
0283 
0284    namespace boost{
0285    namespace move_detail{
0286 
0287    template< class T>
0288    struct forward_type
0289    { typedef const T &type; };
0290 
0291    template< class T>
0292    struct forward_type< boost::rv<T> >
0293    { typedef T type; };
0294 
0295    }}
0296 
0297 #else    //BOOST_NO_CXX11_RVALUE_REFERENCES
0298 
0299    //! This macro marks a type as movable but not copyable, disabling copy construction
0300    //! and assignment. The user will need to write a move constructor/assignment as explained
0301    //! in the documentation to fully write a movable but not copyable class.
0302    #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
0303       BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
0304       public:\
0305       typedef int boost_move_emulation_t;\
0306       private:\
0307    //
0308 
0309    //! This macro marks a type as copyable and movable.
0310    //! The user will need to write a move constructor/assignment and a copy assignment
0311    //! as explained in the documentation to fully write a copyable and movable class.
0312    #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
0313    //
0314 
0315    #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
0316    #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
0317    //
0318    #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
0319 
0320    namespace boost {
0321 
0322    //!This trait yields to a compile-time true boolean if T was marked as
0323    //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
0324    //!rvalue references are not available on the platform. False otherwise.
0325    template<class T>
0326    struct has_move_emulation_enabled
0327    {
0328       static const bool value = false;
0329    };
0330 
0331    template<class T>
0332    struct has_move_emulation_disabled
0333    {
0334       static const bool value = true;
0335    };
0336 
0337    }  //namespace boost{
0338 
0339    //!This macro is used to achieve portable syntax in move
0340    //!constructors and assignments for classes marked as
0341    //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
0342    #define BOOST_RV_REF(TYPE)\
0343       TYPE && \
0344    //
0345 
0346    //!This macro is used to achieve portable syntax in move
0347    //!constructors and assignments for template classes marked as
0348    //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
0349    //!As macros have problems with comma-separated template arguments,
0350    //!the template argument must be preceded with BOOST_RV_REF_BEG
0351    //!and ended with BOOST_RV_REF_END
0352    #define BOOST_RV_REF_BEG\
0353          \
0354    //
0355 
0356    //!This macro is used to achieve portable syntax in move
0357    //!constructors and assignments for template classes marked as
0358    //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
0359    //!As macros have problems with comma-separated template arguments,
0360    //!the template argument must be preceded with BOOST_RV_REF_BEG
0361    //!and ended with BOOST_RV_REF_END
0362    #define BOOST_RV_REF_END\
0363       && \
0364    //
0365 
0366    //!This macro expands to BOOST_RV_REF_BEG if BOOST_NO_CXX11_RVALUE_REFERENCES
0367    //!is not defined, empty otherwise
0368    #define BOOST_RV_REF_BEG_IF_CXX11 \
0369       BOOST_RV_REF_BEG \
0370    //
0371 
0372    //!This macro expands to BOOST_RV_REF_END if BOOST_NO_CXX11_RVALUE_REFERENCES
0373    //!is not defined, empty otherwise
0374    #define BOOST_RV_REF_END_IF_CXX11 \
0375       BOOST_RV_REF_END \
0376    //
0377 
0378    //!This macro is used to achieve portable syntax in copy
0379    //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
0380    #define BOOST_COPY_ASSIGN_REF(TYPE)\
0381       const TYPE & \
0382    //
0383 
0384    //! This macro is used to implement portable perfect forwarding
0385    //! as explained in the documentation.
0386    #define BOOST_FWD_REF(TYPE)\
0387       TYPE && \
0388    //
0389 
0390    #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
0391 
0392    #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
0393       TYPE<ARG1, ARG2> && \
0394    //
0395 
0396    #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
0397       TYPE<ARG1, ARG2, ARG3> && \
0398    //
0399 
0400    #define BOOST_COPY_ASSIGN_REF_BEG \
0401       const \
0402    //
0403 
0404    #define BOOST_COPY_ASSIGN_REF_END \
0405       & \
0406    //
0407 
0408    #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
0409       const TYPE<ARG1, ARG2> & \
0410    //
0411 
0412    #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
0413       const TYPE<ARG1, ARG2, ARG3>& \
0414    //
0415 
0416    #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
0417       const TYPE & \
0418    //
0419 
0420    #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
0421 
0422    #if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
0423 
0424       //!This macro is used to achieve portable move return semantics.
0425       //!The C++11 Standard allows implicit move returns when the object to be returned
0426       //!is designated by a lvalue and:
0427       //!   - The criteria for elision of a copy operation are met OR
0428       //!   - The criteria would be met save for the fact that the source object is a function parameter
0429       //!
0430       //!For C++11 conforming compilers this macros only yields to REF:
0431       //! <code>return BOOST_MOVE_RET(RET_TYPE, REF);</code> -> <code>return REF;</code>
0432       //!
0433       //!For compilers without rvalue references
0434       //!this macro does an explicit move if the move emulation is activated
0435       //!and the return type (RET_TYPE) is not a reference.
0436       //!
0437       //!For non-conforming compilers with rvalue references like Visual 2010 & 2012,
0438       //!an explicit move is performed if RET_TYPE is not a reference.
0439       //!
0440       //! <b>Caution</b>: When using this macro in non-conforming or C++03
0441       //!compilers, a move will be performed even if the C++11 standard does not allow it
0442       //!(e.g. returning a static variable). The user is responsible for using this macro
0443       //!only to return local objects that met C++11 criteria.
0444       #define BOOST_MOVE_RET(RET_TYPE, REF)\
0445          REF
0446       //
0447 
0448    #else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
0449 
0450       #include <boost/move/detail/meta_utils.hpp>
0451 
0452       namespace boost {
0453       namespace move_detail {
0454 
0455       template <class Ret, class T>
0456       BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
0457          <  ::boost::move_detail::is_lvalue_reference<Ret>::value
0458          , T&>::type
0459             move_return(T& x) BOOST_NOEXCEPT
0460       {
0461          return x;
0462       }
0463 
0464       template <class Ret, class T>
0465       BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
0466          < !::boost::move_detail::is_lvalue_reference<Ret>::value
0467          , Ret && >::type
0468             move_return(T&& t) BOOST_NOEXCEPT
0469       {
0470          return static_cast< Ret&& >(t);
0471       }
0472 
0473       }  //namespace move_detail {
0474       }  //namespace boost {
0475 
0476       #define BOOST_MOVE_RET(RET_TYPE, REF)\
0477          boost::move_detail::move_return< RET_TYPE >(REF)
0478       //
0479 
0480    #endif   //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
0481 
0482    //!This macro is used to achieve portable optimal move constructors.
0483    //!
0484    //!When implementing the move constructor, in C++03 compilers the moved-from argument must be
0485    //!cast to the base type before calling `::boost::move()` due to rvalue reference limitations.
0486    //!
0487    //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of
0488    //!a base type is implicit.
0489    #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
0490       ::boost::move((BASE_TYPE&)(ARG))
0491    //
0492 
0493    //!This macro is used to achieve portable optimal move constructors.
0494    //!
0495    //!In C++03 mode, when accessing a member of type through a rvalue (implemented as a `rv<T> &` type, where rv<T> derives
0496    //!from T) triggers a potential UB as the program never creates objects of type rv<T>. This macro casts back `rv<T>` to
0497    //!`T&` so that access to member types are done through the original type.
0498    //! 
0499    //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of
0500    //!a base type is implicit, so it's a no-op.
0501    #define BOOST_MOVE_TO_LV(ARG) ARG
0502    //
0503 
0504    namespace boost {
0505    namespace move_detail {
0506 
0507    template< class T> struct forward_type { typedef T type; };
0508 
0509    }}
0510 
0511 #endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
0512 
0513 #include <boost/move/detail/config_end.hpp>
0514 
0515 #endif //#ifndef BOOST_MOVE_CORE_HPP