1/* 2 * 3 * Copyright (c) 2003 4 * Francois Dumont 5 * 6 * This material is provided "as is", with absolutely no warranty expressed 7 * or implied. Any use is at your own risk. 8 * 9 * Permission to use or copy this software for any purpose is hereby granted 10 * without fee, provided the above notices are retained on all copies. 11 * Permission to modify the code and to distribute modified code is granted, 12 * provided the above notices are retained, and a notice that the code was 13 * modified is included with the above copyright notice. 14 * 15 */ 16 17#ifndef _STLP_MOVE_CONSTRUCT_FWK_H 18#define _STLP_MOVE_CONSTRUCT_FWK_H 19 20#ifndef _STLP_TYPE_TRAITS_H 21# include <stl/type_traits.h> 22#endif 23 24_STLP_BEGIN_NAMESPACE 25 26/************************************************************* 27 * Move constructor framework 28 *************************************************************/ 29 30/************************************************************* 31 *Partial move: 32 *The source HAS to be a valid instance after the move! 33 *************************************************************/ 34template <class _Tp> 35class __move_source { 36public: 37 explicit __move_source (_Tp &_src) : _M_data(_src) 38 {} 39 40 _Tp& get() const 41 { return _M_data; } 42private: 43 _Tp &_M_data; 44 45 //We explicitely forbid assignment to avoid warning: 46 typedef __move_source<_Tp> _Self; 47 _Self& operator = (_Self const&); 48}; 49 50//Class used to signal move constructor support, implementation and type. 51template <class _Tp> 52struct __move_traits { 53 /* 54 * implemented tells if a the special move constructor has to be called or the classic 55 * copy constructor is just fine. Most of the time the copy constructor is fine only 56 * if the following info is true. 57 */ 58#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && \ 59 !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && \ 60 !defined (_STLP_NO_MOVE_SEMANTIC) 61 typedef typename _IsSTLportClass<_Tp>::_Ret implemented; 62#else 63 typedef __false_type implemented; 64#endif 65 /* 66 * complete tells if the move is complete or partial, that is to say, does the source 67 * needs to be destroyed once it has been moved. 68 */ 69# if defined (__BORLANDC__) && (__BORLANDC__ >= 0x564) 70 typedef __type_traits<_Tp>::has_trivial_destructor _TpMoveComplete; 71 typedef typename __bool2type<__type2bool<_TpMoveComplete>::_Ret>::_Ret complete; 72# else 73 typedef typename __type_traits<_Tp>::has_trivial_destructor complete; 74# endif 75}; 76 77_STLP_MOVE_TO_PRIV_NAMESPACE 78 79/* 80 * This struct should never be used if the user has not explicitely stipulated 81 * that its class support the full move concept. To check that the return type 82 * in such a case will be __invalid_source<_Tp> to generate a compile error 83 * revealing the configuration problem. 84 */ 85template <class _Tp> 86struct _MoveSourceTraits { 87 typedef typename __move_traits<_Tp>::implemented _MvImpRet; 88#if defined (__BORLANDC__) 89 typedef typename __selectT<_MvImpRet, 90#else 91 enum {_MvImp = __type2bool<_MvImpRet>::_Ret}; 92 typedef typename __select<_MvImp, 93#endif 94 __move_source<_Tp>, 95 _Tp const&>::_Ret _Type; 96}; 97 98//The helper function 99template <class _Tp> 100inline _STLP_TYPENAME_ON_RETURN_TYPE _MoveSourceTraits<_Tp>::_Type 101_AsMoveSource (_Tp &src) { 102 typedef typename _MoveSourceTraits<_Tp>::_Type _SrcType; 103 return _SrcType(src); 104} 105 106//Helper structs used for many class. 107template <class _Tp> 108struct __move_traits_aux { 109 typedef typename __move_traits<_Tp>::implemented implemented; 110 typedef typename __move_traits<_Tp>::complete complete; 111}; 112 113template <class _Tp1, class _Tp2> 114struct __move_traits_aux2 { 115 typedef __move_traits<_Tp1> _MoveTraits1; 116 typedef __move_traits<_Tp2> _MoveTraits2; 117 118 typedef typename _Lor2<typename _MoveTraits1::implemented, 119 typename _MoveTraits2::implemented>::_Ret implemented; 120 typedef typename _Land2<typename _MoveTraits1::complete, 121 typename _MoveTraits2::complete>::_Ret complete; 122}; 123 124/* 125 * Most of the time a class implement a move constructor but its use depends 126 * on a third party, this is what the following struct are for. 127 */ 128template <class _Tp> 129struct __move_traits_help { 130 typedef __true_type implemented; 131 typedef typename __move_traits<_Tp>::complete complete; 132}; 133 134template <class _Tp1, class _Tp2> 135struct __move_traits_help1 { 136 typedef __move_traits<_Tp1> _MoveTraits1; 137 typedef __move_traits<_Tp2> _MoveTraits2; 138 139 typedef typename _Lor2<typename _MoveTraits1::implemented, 140 typename _MoveTraits2::implemented>::_Ret implemented; 141 typedef typename _Land2<typename _MoveTraits1::complete, 142 typename _MoveTraits2::complete>::_Ret complete; 143}; 144 145template <class _Tp1, class _Tp2> 146struct __move_traits_help2 { 147 typedef __move_traits<_Tp1> _MoveTraits1; 148 typedef __move_traits<_Tp2> _MoveTraits2; 149 150 typedef __true_type implemented; 151 typedef typename _Land2<typename _MoveTraits1::complete, 152 typename _MoveTraits2::complete>::_Ret complete; 153}; 154 155_STLP_MOVE_TO_STD_NAMESPACE 156 157_STLP_END_NAMESPACE 158 159#endif /* _STLP_MOVE_CONSTRUCT_FWK_H */ 160