1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5//
6// clr_std/utility
7//
8// Copy of some key Standard Template Library functionality
9// See http://msdn.microsoft.com/en-us/library/bb982077.aspx for documentation.
10//
11
12#ifdef _MSC_VER
13#pragma once
14#endif
15
16#ifdef USE_STL
17#include <utility>
18#else
19#ifndef __clr_std_utility_h__
20#define __clr_std_utility_h__
21
22#include "clr_std/type_traits"
23
24namespace std
25{
26 //-----------------------------------------------------------------------------------------
27 // TEMPLATE FUNCTION move
28 template<class T> inline
29 typename remove_reference<T>::type&&
30 move(T&& arg)
31 { // forward _Arg as movable
32 return ((typename remove_reference<T>::type&&)arg);
33 }
34
35 //-----------------------------------------------------------------------------------------
36 // TEMPLATE FUNCTION swap (from <algorithm>)
37 template<class T> inline
38 void swap(T& left, T& right)
39 { // exchange values stored at left and right
40 T tmp = std::move(left);
41 left = std::move(right);
42 right = std::move(tmp);
43 }
44
45 //-----------------------------------------------------------------------------------------
46 // TEMPLATE FUNCTION forward
47 template<class T> inline
48 T&&
49 forward(typename identity<T>::type& _Arg)
50 { // forward _Arg, given explicitly specified type parameter
51 return ((T&&)_Arg);
52 }
53}
54
55namespace std
56{
57 //-----------------------------------------------------------------------------------------
58 // TEMPLATE STRUCT pair
59 template<class _Ty1, class _Ty2>
60 struct pair
61 { // store a pair of values
62 typedef pair<_Ty1, _Ty2> _Myt;
63 typedef _Ty1 first_type;
64 typedef _Ty2 second_type;
65
66 pair()
67 : first(_Ty1()), second(_Ty2())
68 { // construct from defaults
69 }
70
71 pair(const _Ty1& _Val1, const _Ty2& _Val2)
72 : first(_Val1.first), second(_Val2.second)
73 { // construct from specified values
74 }
75
76 template<class _Other1, class _Other2>
77 pair(pair<_Other1, _Other2>& _Right)
78 : first(_Right.first), second(_Right.second)
79 { // construct from compatible pair
80 }
81
82 template<class _Other1, class _Other2>
83 pair(const pair<_Other1, _Other2>& _Right)
84 : first(_Right.first), second(_Right.second)
85 { // construct from compatible pair
86 }
87
88 void swap(_Myt& _Right)
89 { // exchange contents with _Right
90 if (this != &_Right)
91 { // different, worth swapping
92 swap(this->first, _Right.first);
93 swap(this->second, _Right.second);
94 }
95 }
96
97 _Myt& operator=(const _Myt& _Right)
98 { // assign from copied pair
99 this->first = _Right.first;
100 this->second = _Right.second;
101 return (*this);
102 }
103
104 typedef typename remove_reference<_Ty1>::type _Ty1x;
105 typedef typename remove_reference<_Ty2>::type _Ty2x;
106
107 pair(_Ty1x&& _Val1, _Ty2x&& _Val2)
108 : first(std::move(_Val1)),
109 second(std::move(_Val2))
110 { // construct from specified values
111 }
112
113 pair(const _Ty1x& _Val1, _Ty2x&& _Val2)
114 : first(_Val1),
115 second(std::move(_Val2))
116 { // construct from specified values
117 }
118
119 pair(_Ty1x&& _Val1, const _Ty2x& _Val2)
120 : first(std::move(_Val1)),
121 second(_Val2)
122 { // construct from specified values
123 }
124
125 template<class _Other1, class _Other2>
126 pair(_Other1&& _Val1, _Other2&& _Val2)
127 : first(std::move(_Val1)),
128 second(std::move(_Val2))
129 { // construct from moved values
130 }
131
132 template<class _Other1, class _Other2>
133 pair(pair<_Other1, _Other2>&& _Right)
134 : first(std::move(_Right.first)),
135 second(std::move(_Right.second))
136 { // construct from moved compatible pair
137 }
138
139 pair& operator=(pair<_Ty1, _Ty2>&& _Right)
140 { // assign from moved pair
141 this->first = std::move(_Right.first);
142 this->second = std::move(_Right.second);
143 return (*this);
144 }
145
146 void swap(_Myt&& _Right)
147 { // exchange contents with _Right
148 if (this != &_Right)
149 { // different, worth swapping
150 this->first = std::move(_Right.first);
151 this->second = std::move(_Right.second);
152 }
153 }
154
155 _Ty1 first; // the first stored value
156 _Ty2 second; // the second stored value
157 }; // struct pair
158
159 //-----------------------------------------------------------------------------------------
160 // pair TEMPLATE FUNCTIONS
161
162 template<class _Ty1, class _Ty2> inline
163 void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right)
164 { // swap _Left and _Right pairs
165 _Left.swap(_Right);
166 }
167
168 template<class _Ty1, class _Ty2> inline
169 void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>&& _Right)
170 { // swap _Left and _Right pairs
171 typedef pair<_Ty1, _Ty2> _Myt;
172 _Left.swap(std::forward<_Myt>(_Right));
173 }
174
175 template<class _Ty1, class _Ty2> inline
176 void swap(
177 pair<_Ty1, _Ty2>&& _Left,
178 pair<_Ty1, _Ty2>& _Right)
179 { // swap _Left and _Right pairs
180 typedef pair<_Ty1, _Ty2> _Myt;
181 _Right.swap(std::forward<_Myt>(_Left));
182 }
183
184 template<class _Ty1, class _Ty2> inline
185 bool operator==(
186 const pair<_Ty1, _Ty2>& _Left,
187 const pair<_Ty1, _Ty2>& _Right)
188 { // test for pair equality
189 return (_Left.first == _Right.first && _Left.second == _Right.second);
190 }
191
192 template<class _Ty1, class _Ty2> inline
193 bool operator!=(
194 const pair<_Ty1, _Ty2>& _Left,
195 const pair<_Ty1, _Ty2>& _Right)
196 { // test for pair inequality
197 return (!(_Left == _Right));
198 }
199
200 template<class _Ty1, class _Ty2> inline
201 bool operator<(
202 const pair<_Ty1, _Ty2>& _Left,
203 const pair<_Ty1, _Ty2>& _Right)
204 { // test if _Left < _Right for pairs
205 return (_Left.first < _Right.first ||
206 (!(_Right.first < _Left.first) && _Left.second < _Right.second));
207 }
208
209 template<class _Ty1, class _Ty2> inline
210 bool operator>(
211 const pair<_Ty1, _Ty2>& _Left,
212 const pair<_Ty1, _Ty2>& _Right)
213 { // test if _Left > _Right for pairs
214 return (_Right < _Left);
215 }
216
217 template<class _Ty1, class _Ty2> inline
218 bool operator<=(
219 const pair<_Ty1, _Ty2>& _Left,
220 const pair<_Ty1, _Ty2>& _Right)
221 { // test if _Left <= _Right for pairs
222 return (!(_Right < _Left));
223 }
224
225 template<class _Ty1, class _Ty2> inline
226 bool operator>=(
227 const pair<_Ty1, _Ty2>& _Left,
228 const pair<_Ty1, _Ty2>& _Right)
229 { // test if _Left >= _Right for pairs
230 return (!(_Left < _Right));
231 }
232
233 template<class _InIt> inline
234 _InIt begin(
235 const pair<_InIt, _InIt>& _Pair)
236 { // return first element of pair
237 return (_Pair.first);
238 }
239
240 template<class _InIt> inline
241 _InIt end(
242 const pair<_InIt, _InIt>& _Pair)
243 { // return second element of pair
244 return (_Pair.second);
245 }
246
247} // namespace std
248
249#endif /* __clr_std_utility_h__ */
250
251#endif // !USE_STL
252
253// Help the VIM editor figure out what kind of file this no-extension file is.
254// vim: filetype=cpp
255