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 *************************************************************/ 34 template <class _Tp> 35 class __move_source { 36 public: 37 explicit __move_source (_Tp &_src) : _M_data(_src) 38 {} 39 40 _Tp& get() const 41 { return _M_data; } 42 private: 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. 51 template <class _Tp> 52 struct __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 */ 85 template <class _Tp> 86 struct _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 99 template <class _Tp> 100 inline _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. 107 template <class _Tp> 108 struct __move_traits_aux { 109 typedef typename __move_traits<_Tp>::implemented implemented; 110 typedef typename __move_traits<_Tp>::complete complete; 111 }; 112 113 template <class _Tp1, class _Tp2> 114 struct __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 */ 128 template <class _Tp> 129 struct __move_traits_help { 130 typedef __true_type implemented; 131 typedef typename __move_traits<_Tp>::complete complete; 132 }; 133 134 template <class _Tp1, class _Tp2> 135 struct __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 145 template <class _Tp1, class _Tp2> 146 struct __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