1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
20
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24// <http://www.gnu.org/licenses/>.
25
26/*
27 *
28 * Copyright (c) 1994
29 * Hewlett-Packard Company
30 *
31 * Permission to use, copy, modify, distribute and sell this software
32 * and its documentation for any purpose is hereby granted without fee,
33 * provided that the above copyright notice appear in all copies and
34 * that both that copyright notice and this permission notice appear
35 * in supporting documentation.  Hewlett-Packard Company makes no
36 * representations about the suitability of this software for any
37 * purpose.  It is provided "as is" without express or implied warranty.
38 *
39 *
40 * Copyright (c) 1996,1997
41 * Silicon Graphics Computer Systems, Inc.
42 *
43 * Permission to use, copy, modify, distribute and sell this software
44 * and its documentation for any purpose is hereby granted without fee,
45 * provided that the above copyright notice appear in all copies and
46 * that both that copyright notice and this permission notice appear
47 * in supporting documentation.  Silicon Graphics makes no
48 * representations about the suitability of this software for any
49 * purpose.  It is provided "as is" without express or implied warranty.
50 */
51
52/** @file bits/stl_pair.h
53 *  This is an internal header file, included by other library headers.
54 *  Do not attempt to use it directly. @headername{utility}
55 */
56
57#ifndef _STL_PAIR_H
58#define _STL_PAIR_H 1
59
60#include <bits/move.h> // for std::move / std::forward, and std::swap
61
62#ifdef __GXX_EXPERIMENTAL_CXX0X__
63#include <type_traits> // for std::__decay_and_strip too
64#endif
65
66namespace std _GLIBCXX_VISIBILITY(default)
67{
68_GLIBCXX_BEGIN_NAMESPACE_VERSION
69
70#ifdef __GXX_EXPERIMENTAL_CXX0X__
71  /// piecewise_construct_t
72  struct piecewise_construct_t { };
73
74  /// piecewise_construct
75  constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
76
77  // Forward declarations.
78  template<typename...>
79    class tuple;
80
81  template<int...>
82    struct _Index_tuple;
83#endif
84
85  /// Struct holding two objects of arbitrary type.
86  template<class _T1, class _T2>
87    struct pair
88    {
89      typedef _T1 first_type;    /// @c first_type is the first bound type
90      typedef _T2 second_type;   /// @c second_type is the second bound type
91
92      _T1 first;                 /// @c first is a copy of the first object
93      _T2 second;                /// @c second is a copy of the second object
94
95      // _GLIBCXX_RESOLVE_LIB_DEFECTS
96      // 265.  std::pair::pair() effects overly restrictive
97      /** The default constructor creates @c first and @c second using their
98       *  respective default constructors.  */
99      _GLIBCXX_CONSTEXPR pair()
100      : first(), second() { }
101
102      /** Two objects may be passed to a @c pair constructor to be copied.  */
103      _GLIBCXX_CONSTEXPR pair(const _T1& __a, const _T2& __b)
104      : first(__a), second(__b) { }
105
106      /** There is also a templated copy ctor for the @c pair class itself.  */
107      template<class _U1, class _U2>
108	_GLIBCXX_CONSTEXPR pair(const pair<_U1, _U2>& __p)
109	: first(__p.first), second(__p.second) { }
110
111#ifdef __GXX_EXPERIMENTAL_CXX0X__
112      constexpr pair(const pair&) = default;
113
114      // Implicit.
115      // pair(pair&&) = default;
116
117      // DR 811.
118      template<class _U1, class = typename
119	       std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
120	pair(_U1&& __x, const _T2& __y)
121	: first(std::forward<_U1>(__x)), second(__y) { }
122
123      template<class _U2, class = typename
124	       std::enable_if<std::is_convertible<_U2, _T2>::value>::type>
125	pair(const _T1& __x, _U2&& __y)
126	: first(__x), second(std::forward<_U2>(__y)) { }
127
128      template<class _U1, class _U2, class = typename
129	       std::enable_if<std::is_convertible<_U1, _T1>::value
130			      && std::is_convertible<_U2, _T2>::value>::type>
131	pair(_U1&& __x, _U2&& __y)
132	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
133
134      template<class _U1, class _U2>
135	pair(pair<_U1, _U2>&& __p)
136	: first(std::forward<_U1>(__p.first)),
137	  second(std::forward<_U2>(__p.second)) { }
138
139      template<class... _Args1, class... _Args2>
140	pair(piecewise_construct_t,
141	     tuple<_Args1...> __first, tuple<_Args2...> __second)
142	: first(__cons<first_type>(std::move(__first))),
143	  second(__cons<second_type>(std::move(__second))) { }
144
145      pair&
146      operator=(const pair& __p)
147      {
148	first = __p.first;
149	second = __p.second;
150	return *this;
151      }
152
153      pair&
154      operator=(pair&& __p)
155      {
156	first = std::move(__p.first);
157	second = std::move(__p.second);
158	return *this;
159      }
160
161      template<class _U1, class _U2>
162	pair&
163	operator=(const pair<_U1, _U2>& __p)
164	{
165	  first = __p.first;
166	  second = __p.second;
167	  return *this;
168	}
169
170      template<class _U1, class _U2>
171	pair&
172	operator=(pair<_U1, _U2>&& __p)
173	{
174	  first = std::move(__p.first);
175	  second = std::move(__p.second);
176	  return *this;
177	}
178
179      void
180      swap(pair& __p)
181      {
182	using std::swap;
183	swap(first, __p.first);
184	swap(second, __p.second);
185      }
186
187    private:
188      template<typename _Tp, typename... _Args>
189	static _Tp
190	__cons(tuple<_Args...>&&);
191
192      template<typename _Tp, typename... _Args, int... _Indexes>
193	static _Tp
194	__do_cons(tuple<_Args...>&&, const _Index_tuple<_Indexes...>&);
195#endif
196    };
197
198  /// Two pairs of the same type are equal iff their members are equal.
199  template<class _T1, class _T2>
200    inline _GLIBCXX_CONSTEXPR bool
201    operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
202    { return __x.first == __y.first && __x.second == __y.second; }
203
204  /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
205  template<class _T1, class _T2>
206    inline _GLIBCXX_CONSTEXPR bool
207    operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
208    { return __x.first < __y.first
209	     || (!(__y.first < __x.first) && __x.second < __y.second); }
210
211  /// Uses @c operator== to find the result.
212  template<class _T1, class _T2>
213    inline _GLIBCXX_CONSTEXPR bool
214    operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
215    { return !(__x == __y); }
216
217  /// Uses @c operator< to find the result.
218  template<class _T1, class _T2>
219    inline _GLIBCXX_CONSTEXPR bool
220    operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
221    { return __y < __x; }
222
223  /// Uses @c operator< to find the result.
224  template<class _T1, class _T2>
225    inline _GLIBCXX_CONSTEXPR bool
226    operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
227    { return !(__y < __x); }
228
229  /// Uses @c operator< to find the result.
230  template<class _T1, class _T2>
231    inline _GLIBCXX_CONSTEXPR bool
232    operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
233    { return !(__x < __y); }
234
235#ifdef __GXX_EXPERIMENTAL_CXX0X__
236  /// See std::pair::swap().
237  // Note:  no std::swap overloads in C++03 mode, this has performance
238  //        implications, see, eg, libstdc++/38466.
239  template<class _T1, class _T2>
240    inline void
241    swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
242    { __x.swap(__y); }
243#endif
244
245  /**
246   *  @brief A convenience wrapper for creating a pair from two objects.
247   *  @param  x  The first object.
248   *  @param  y  The second object.
249   *  @return   A newly-constructed pair<> object of the appropriate type.
250   *
251   *  The standard requires that the objects be passed by reference-to-const,
252   *  but LWG issue #181 says they should be passed by const value.  We follow
253   *  the LWG by default.
254   */
255  // _GLIBCXX_RESOLVE_LIB_DEFECTS
256  // 181.  make_pair() unintended behavior
257#ifdef __GXX_EXPERIMENTAL_CXX0X__
258  // NB: DR 706.
259  template<class _T1, class _T2>
260    inline pair<typename __decay_and_strip<_T1>::__type,
261		typename __decay_and_strip<_T2>::__type>
262    make_pair(_T1&& __x, _T2&& __y)
263    {
264      typedef typename __decay_and_strip<_T1>::__type __ds_type1;
265      typedef typename __decay_and_strip<_T2>::__type __ds_type2;
266      typedef pair<__ds_type1, __ds_type2> 	      __pair_type;
267      return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
268    }
269#else
270  template<class _T1, class _T2>
271    inline pair<_T1, _T2>
272    make_pair(_T1 __x, _T2 __y)
273    { return pair<_T1, _T2>(__x, __y); }
274#endif
275
276_GLIBCXX_END_NAMESPACE_VERSION
277} // namespace
278
279#endif /* _STL_PAIR_H */
280