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:
__move_source(_Tp & _src)37 explicit __move_source (_Tp &_src) : _M_data(_src)
38 {}
39
get()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
_AsMoveSource(_Tp & src)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