1
/*
2
 *
3
 * Copyright (c) 1994
4
 * Hewlett-Packard Company
5
 *
6
 * Copyright (c) 1996,1997
7
 * Silicon Graphics Computer Systems, Inc.
8
 *
9
 * Copyright (c) 1999
10
 * Boris Fomitchev
11
 *
12
 * This material is provided "as is", with absolutely no warranty expressed
13
 * or implied. Any use is at your own risk.
14
 *
15
 * Permission to use or copy this software for any purpose is hereby granted
16
 * without fee, provided the above notices are retained on all copies.
17
 * Permission to modify the code and to distribute modified code is granted,
18
 * provided the above notices are retained, and a notice that the code was
19
 * modified is included with the above copyright notice.
20
 *
21
 */
22
23
#ifndef _STLP_UTILITY
24
#  define _STLP_UTILITY
25
26
#ifndef _STLP_TYPE_TRAITS
27
#  include <type_traits>
28
#endif
29
30
#ifndef _STLP_OUTERMOST_HEADER_ID
31
#  define _STLP_OUTERMOST_HEADER_ID 0x75
32
#  include <stl/_prolog.h>
33
#endif
34
35
_STLP_BEGIN_NAMESPACE
36
37
template <class _Tp> void swap( _Tp&, _Tp& );
38
39
template <class _Tp>
40
class __move_source
41
{
42
  public:
43
    explicit __move_source( _Tp& _src ) :
44
        _M_data(_src)
45
      { }
46
47
    _Tp& get() const
48
      { return _M_data; }
49
  private:
50
    _Tp& _M_data;
51
52
    //We explicitely forbid assignment to avoid warning:
53
    typedef __move_source<_Tp> _Self;
54
55
    _Self& operator = ( _Self const& );
56
};
57
58
//Class used to signal move constructor support, implementation and type.
59
60
template <class _Tp>
61
struct __has_trivial_move :
62
    public integral_constant<bool, is_trivial<_Tp>::value>
63
{ };
64
65
template <class _Tp>
66
struct __has_move_constructor :
67
    public false_type
68
{ };
69
70
namespace rel_ops {
71
} // namespace rel_ops
72
73
// template <class T>
74
// struct identity
75
// {
76
//     typedef T type;
77
//    const T& operator ()( const T& v ) const
78
//       { return v; }
79
// };
80
81
#ifdef _STLP_CPP_0X
82
83
template <class T>
84
inline T&& forward( typename _STLP_STD::remove_reference<T>::type& t ) throw() // noexcept
85
{ return static_cast<T&&>(t); }
86
87
template <class T>
88
inline T&& forward( typename _STLP_STD::remove_reference<T>::type&& t ) throw() // noexcept
89
{
90
  _STLP_STATIC_ASSERT( !_STLP_STD::is_lvalue_reference<T>::value )
91
  return static_cast<T&&>(t);
92
}
93
94
template <class T>
95
inline typename remove_reference<T>::type&& move( T&& t ) throw() // noexcept
96
{ return static_cast<typename remove_reference<T>::type&&>(t); }
97
98
//template <class T>
99
//inline typename _STLP_STD::conditional<!_STLP_STD::is_nothrow_move_constructible<T>::value && _STLP_STD::is_copy_constructible<T>::value, const T&, T&&>::type move_if_noexcept(T& x) throw() // noexcept
100
//{ return _STLP_STD::move(x); }
101
102
#else // !_STLP_CPP_0X
103
104
template <class T>
105
__move_source<typename remove_const<typename remove_reference<T>::type>::type> move( const T& t )
106
{ return __move_source<typename remove_const<typename remove_reference<T>::type>::type>( const_cast<T&>(t) ); }
107
108
template <class T>
109
__move_source<typename remove_reference<T>::type> move( T& t )
110
{ return __move_source<typename remove_reference<T>::type>( t ); }
111
112
#endif // !_STLP_CPP_0X
113
114
template <class _T1, class _T2>
115
struct pair {
116
  typedef _T1 first_type;
117
  typedef _T2 second_type;
118
119
  _T1 first;
120
  _T2 second;
121
#ifndef _STLP_CPP_0X
122
  pair() : first(_T1()), second(_T2()) {}
123
  pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {}
124
125
  template <class _U1, class _U2>
126
  pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
127
128
  pair(const pair<_T1,_T2>& __o) : first(__o.first), second(__o.second) {}
129
130
#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_NO_MOVE_SEMANTIC)
131
  pair(__move_source<pair<_T1, _T2> > src) :
132
      first(src.get().first),
133
      second(src.get().second)
134
    { }
135
#endif
136
137
  __TRIVIAL_DESTRUCTOR(pair)
138
#else // _STLP_CPP_0X
139
  pair( const pair& ) = default;
140
  pair( pair&& ) = default;
141
  constexpr pair() :
142
      first(_T1()),
143
      second(_T2())
144
    {
145
      static_assert( _STLP_STD::is_default_constructible<first_type>::value, "first_type not default constructible" );
146
      static_assert( _STLP_STD::is_default_constructible<second_type>::value, "second_type not default constructible" );
147
    }
148
149
  pair(const _T1& __a, const _T2& __b) :
150
      first(__a),
151
      second(__b)
152
    { }
153
154
  template <class U, class V>
155
  pair( U&& x, V&& y ) :
156
      first( _STLP_STD::forward<U>(x) ),
157
      second( _STLP_STD::forward<V>(y) )
158
    { }
159
160
  template <class U, class V>
161
  pair( const pair<U,V>& p ) :
162
      first( p.first ),
163
      second( p.second )
164
    { }
165
166
  template <class U, class V>
167
  pair( pair<U,V>&& p ) :
168
      first( _STLP_STD::forward<U>(p.first) ),
169
      second( _STLP_STD::forward<V>(p.second) )
170
    { }
171
172
  // template <class ... Args1, class ... Args2>
173
  // pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
174
175
  pair& operator =(const pair& p)
176
    {
177
      static_assert( _STLP_STD::is_copy_assignable<first_type>::value, "first_type not copy assignable" );
178
      static_assert( _STLP_STD::is_copy_assignable<second_type>::value, "second_type not copy assignable" );
179
      first = p.first; second = p.second; return *this;
180
    }
181
182
  template <class U, class V>
183
  pair& operator =(const pair<U,V>& p)
184
    {
185
      static_assert( is_assignable<first_type&,const U&>::value, "first_type is not assignable" );
186
      static_assert( is_assignable<second_type&,const V&>::value, "second_type is not assignable" );
187
      first = p.first; second = p.second; return *this;
188
    }
189
190
  pair& operator =(pair&& p) noexcept
191
    {
192
      static_assert( is_move_assignable<first_type>::value, "first_type is not move assignable" );
193
      static_assert( is_move_assignable<second_type>::value, "second_type is not move assignable" );
194
      first = _STLP_STD::forward<first_type>(p.first);
195
      second = _STLP_STD::forward<second_type>(p.second);
196
      return *this;
197
    }
198
199
  template <class U, class V>
200
  pair& operator =(pair<U,V>&& p)
201
    {
202
      static_assert( is_assignable<first_type&,U&&>::value, "first_type is not assignable" );
203
      static_assert( is_assignable<second_type&,V&&>::value, "second_type is not assignable" );
204
      first = _STLP_STD::forward<U>(p.first);
205
      second = _STLP_STD::forward<V>(p.second);
206
      return *this;
207
    }
208
209
  void swap(pair& p) noexcept
210
    { _STLP_STD::swap(first, p.first); _STLP_STD::swap(second, p.second); }
211
#endif // _STLP_CPP_0X
212
};
213
214
template <class _T1, class _T2>
215
inline bool _STLP_CALL operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
216
{ return __x.first == __y.first && __x.second == __y.second; }
217
218
template <class _T1, class _T2>
219
inline bool _STLP_CALL operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
220
  return __x.first < __y.first ||
221
         (!(__y.first < __x.first) && __x.second < __y.second);
222
}
223
224
#if defined (_STLP_USE_SEPARATE_RELOPS_NAMESPACE)
225
template <class _T1, class _T2>
226
inline bool _STLP_CALL operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
227
{ return !(__x == __y); }
228
229
template <class _T1, class _T2>
230
inline bool _STLP_CALL operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
231
{ return __y < __x; }
232
233
template <class _T1, class _T2>
234
inline bool _STLP_CALL operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
235
{ return !(__y < __x); }
236
237
template <class _T1, class _T2>
238
inline bool _STLP_CALL operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
239
{ return !(__x < __y); }
240
#endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
241
242
#if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) && !defined (_STLP_NO_EXTENSIONS)
243
template <class _T1, class _T2, int _Sz>
244
inline pair<_T1, _T2 const*> make_pair(_T1 const& __x,
245
                                       _T2 const (&__y)[_Sz])
246
{ return pair<_T1, _T2 const*>(__x, static_cast<_T2 const*>(__y)); }
247
248
template <class _T1, class _T2, int _Sz>
249
inline pair<_T1 const*, _T2> make_pair(_T1 const (&__x)[_Sz],
250
                                       _T2 const& __y)
251
{ return pair<_T1 const*, _T2>(static_cast<_T1 const*>(__x), __y); }
252
253
template <class _T1, class _T2, int _Sz1, int _Sz2>
254
inline pair<_T1 const*, _T2 const*> make_pair(_T1 const (&__x)[_Sz1],
255
                                              _T2 const (&__y)[_Sz2]) {
256
  return pair<_T1 const*, _T2 const*>(static_cast<_T1 const*>(__x),
257
                                      static_cast<_T2 const*>(__y));
258
}
259
#endif
260
261
template <class _T1, class _T2>
262
inline pair<_T1, _T2> _STLP_CALL make_pair(_T1 __x, _T2 __y)
263
{ return pair<_T1, _T2>(__x, __y); }
264
265
_STLP_END_NAMESPACE
266
267
#if defined (_STLP_USE_NAMESPACES) || !defined (_STLP_USE_SEPARATE_RELOPS_NAMESPACE)
268
_STLP_BEGIN_RELOPS_NAMESPACE
269
270
template <class _Tp>
271
inline bool _STLP_CALL operator!=(const _Tp& __x, const _Tp& __y)
272
{ return !(__x == __y); }
273
274
template <class _Tp>
275
inline bool _STLP_CALL operator>(const _Tp& __x, const _Tp& __y)
276
{ return __y < __x; }
277
278
template <class _Tp>
279
inline bool _STLP_CALL operator<=(const _Tp& __x, const _Tp& __y)
280
{ return !(__y < __x); }
281
282
template <class _Tp>
283
inline bool _STLP_CALL  operator>=(const _Tp& __x, const _Tp& __y)
284
{ return !(__x < __y); }
285
286
_STLP_END_RELOPS_NAMESPACE
287
#endif
288
289
#ifdef _STLP_CPP_0X
290
291
_STLP_BEGIN_NAMESPACE
292
293
namespace detail {
294
295
template <class _Tp>
296
struct __declval_aux
297
{
298
    static const bool __instance = false;
299
    static typename add_rvalue_reference<_Tp>::type __dummy();
300
};
301
302
} // namespace detail
303
304
template <class _Tp>
305
inline typename add_rvalue_reference<_Tp>::type declval() _STLP_NOEXCEPT
306
{
307
  // protect declval() from call:
308
  _STLP_STATIC_ASSERT(detail::__declval_aux<_Tp>::__instance);
309
  return detail::__declval_aux<_Tp>::__dummy();
310
}
311
312
_STLP_END_NAMESPACE
313
314
#endif // _STLP_CPP_0X
315
316
#if (_STLP_OUTERMOST_HEADER_ID == 0x75)
317
#  include <stl/_epilog.h>
318
#  undef _STLP_OUTERMOST_HEADER_ID
319
#endif
320
321
#endif /* _STLP_UTILITY */
322
323
// Local Variables:
324
// mode:C++
325
// End: