move.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 229 行

HPP
229
字号
/*    Copyright 2005-2007 Adobe Systems Incorporated       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).*//*************************************************************************************************/#ifndef BOOST_UNORDERED_DETAIL_MOVE_HEADER#define BOOST_UNORDERED_DETAIL_MOVE_HEADER#include <boost/mpl/bool.hpp>#include <boost/mpl/and.hpp>#include <boost/mpl/or.hpp>#include <boost/mpl/not.hpp>#include <boost/type_traits/is_convertible.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/type_traits/is_class.hpp>#include <boost/utility/enable_if.hpp>#include <boost/unordered/detail/config.hpp>/*************************************************************************************************/namespace boost {namespace unordered_detail {/*************************************************************************************************/namespace move_detail {/*************************************************************************************************/#if !defined(BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN)/*************************************************************************************************/template <typename T>  struct class_has_move_assign {      class type {        typedef T& (T::*E)(T t);          typedef char (&no_type)[1];          typedef char (&yes_type)[2];          template <E e> struct sfinae { typedef yes_type type; };          template <class U>          static typename sfinae<&U::operator=>::type test(int);          template <class U>          static no_type test(...);      public:          enum {value = sizeof(test<T>(1)) == sizeof(yes_type)};      }; };  /*************************************************************************************************/template<typename T>struct has_move_assign : boost::mpl::and_<boost::is_class<T>, class_has_move_assign<T> > {};/*************************************************************************************************/class test_can_convert_anything { };/*************************************************************************************************/#endif // BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN/*************************************************************************************************//*    REVISIT (sparent@adobe.com): This is a work around for Boost 1.34.1 and VC++ 2008 where    boost::is_convertible<T, T> fails to compile.*/template <typename T, typename U>struct is_convertible : boost::mpl::or_<    boost::is_same<T, U>,    boost::is_convertible<T, U>> { };/*************************************************************************************************/} //namespace move_detail/*************************************************************************************************//*!\ingroup move_related\brief move_from is used for move_ctors.*/template <typename T>struct move_from{    explicit move_from(T& x) : source(x) { }    T& source;};/*************************************************************************************************/#if !defined(BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN)/*************************************************************************************************//*!\ingroup move_related\brief The is_movable trait can be used to identify movable types.*/template <typename T>struct is_movable : boost::mpl::and_<                        boost::is_convertible<move_from<T>, T>,                        move_detail::has_move_assign<T>,                        boost::mpl::not_<boost::is_convertible<move_detail::test_can_convert_anything, T> >                    > { };/*************************************************************************************************/#else // BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN// On compilers which don't have adequate SFINAE support, treat most types as unmovable,// unless the trait is specialized.template <typename T>struct is_movable : boost::mpl::false_ { };#endif/*************************************************************************************************/#if !defined(BOOST_NO_SFINAE)/*************************************************************************************************//*!\ingroup move_related\brief copy_sink and move_sink are used to select between overloaded operations according to whether type T is movable and convertible to type U.\sa move*/template <typename T,          typename U = T,          typename R = void*>struct copy_sink : boost::enable_if<                        boost::mpl::and_<                            boost::unordered_detail::move_detail::is_convertible<T, U>,                                                       boost::mpl::not_<is_movable<T> >                        >,                        R                    >{ };/*************************************************************************************************//*!\ingroup move_related\brief move_sink and copy_sink are used to select between overloaded operations according to whether type T is movable and convertible to type U. \sa move*/template <typename T,          typename U = T,          typename R = void*>struct move_sink : boost::enable_if<                        boost::mpl::and_<                            boost::unordered_detail::move_detail::is_convertible<T, U>,                                                        is_movable<T>                        >,                        R                    >{ };/*************************************************************************************************//*!\ingroup move_related\brief This version of move is selected when T is_movable . It in turn calls the moveconstructor. This call, with the help of the return value optimization, will cause x to be movedinstead of copied to its destination. See adobe/test/move/main.cpp for examples.*/template <typename T>T move(T& x, typename move_sink<T>::type = 0) { return T(move_from<T>(x)); }/*************************************************************************************************//*!\ingroup move_related\brief This version of move is selected when T is not movable . The net result will be thatx gets copied.*/template <typename T>T& move(T& x, typename copy_sink<T>::type = 0) { return x; }/*************************************************************************************************/#else // BOOST_NO_SFINAE// On compilers without SFINAE, define copy_sink to always use the copy function.template <typename T,          typename U = T,          typename R = void*>struct copy_sink{    typedef R type;};// Always copy the element unless this is overloaded.template <typename T>T& move(T& x) {    return x;}#endif // BOOST_NO_SFINAE} // namespace unordered_detail} // namespace boost/*************************************************************************************************/#endif/*************************************************************************************************/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?