blob: 4a85fe32de5f9ea1915d2f4aad64e80c7e576ef7 [file] [log] [blame]
Dan Albert287553d2017-02-16 10:47:51 -08001/*
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 */