1// Pair implementation -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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 stl_pair.h
53 *  This is an internal header file, included by other library headers.
54 *  You should not attempt to use it directly.
55 */
56
57#ifndef _STL_PAIR_H
58#define _STL_PAIR_H 1
59
60#include <bits/move.h> // for std::move / std::forward, std::decay, and
61                       // std::swap
62
63_GLIBCXX_BEGIN_NAMESPACE(std)
64
65  /// pair holds two objects of arbitrary type.
66  template<class _T1, class _T2>
67    struct pair
68    {
69      typedef _T1 first_type;    ///<  @c first_type is the first bound type
70      typedef _T2 second_type;   ///<  @c second_type is the second bound type
71
72      _T1 first;                 ///< @c first is a copy of the first object
73      _T2 second;                ///< @c second is a copy of the second object
74
75      // _GLIBCXX_RESOLVE_LIB_DEFECTS
76      // 265.  std::pair::pair() effects overly restrictive
77      /** The default constructor creates @c first and @c second using their
78       *  respective default constructors.  */
79      pair()
80      : first(), second() { }
81
82      /** Two objects may be passed to a @c pair constructor to be copied.  */
83      pair(const _T1& __a, const _T2& __b)
84      : first(__a), second(__b) { }
85
86#ifdef __GXX_EXPERIMENTAL_CXX0X__
87      template<class _U1, class = typename
88	       std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
89	pair(_U1&& __x, const _T2& __y)
90	: first(std::forward<_U1>(__x)), second(__y) { }
91
92      template<class _U2, class = typename
93	       std::enable_if<std::is_convertible<_U2, _T2>::value>::type>
94	pair(const _T1& __x, _U2&& __y)
95	: first(__x), second(std::forward<_U2>(__y)) { }
96
97      template<class _U1, class _U2, class = typename
98	       std::enable_if<std::is_convertible<_U1, _T1>::value
99			      && std::is_convertible<_U2, _T2>::value>::type>
100        pair(_U1&& __x, _U2&& __y)
101	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
102
103      pair(pair&& __p)
104      : first(std::move(__p.first)),
105	second(std::move(__p.second)) { }
106#endif
107
108      /** There is also a templated copy ctor for the @c pair class itself.  */
109      template<class _U1, class _U2>
110        pair(const pair<_U1, _U2>& __p)
111	: first(__p.first),
112	  second(__p.second) { }
113
114#ifdef __GXX_EXPERIMENTAL_CXX0X__
115      template<class _U1, class _U2>
116        pair(pair<_U1, _U2>&& __p)
117	: first(std::move(__p.first)),
118	  second(std::move(__p.second)) { }
119
120      // http://gcc.gnu.org/ml/libstdc++/2007-08/msg00052.html
121
122#if 0
123      // This constructor is incompatible with libstdc++-4.6, and it
124      // interferes with passing NULL pointers to the 2-argument
125      // constructors, so we disable it.  map::emplace isn't
126      // implemented in libstdc++-4.4 anyway, and that's what this
127      // constructor was here for.
128      template<class _U1, class _Arg0, class... _Args>
129        pair(_U1&& __x, _Arg0&& __arg0, _Args&&... __args)
130	: first(std::forward<_U1>(__x)),
131	  second(std::forward<_Arg0>(__arg0),
132		 std::forward<_Args>(__args)...) { }
133#endif
134
135      pair&
136      operator=(pair&& __p)
137      {
138	first = std::move(__p.first);
139	second = std::move(__p.second);
140	return *this;
141      }
142
143      template<class _U1, class _U2>
144        pair&
145        operator=(pair<_U1, _U2>&& __p)
146	{
147	  first = std::move(__p.first);
148	  second = std::move(__p.second);
149	  return *this;
150	}
151
152      void
153      swap(pair& __p)
154      {
155	using std::swap;
156	swap(first, __p.first);
157	swap(second, __p.second);
158      }
159#endif
160    };
161
162  /// Two pairs of the same type are equal iff their members are equal.
163  template<class _T1, class _T2>
164    inline bool
165    operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
166    { return __x.first == __y.first && __x.second == __y.second; }
167
168  /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
169  template<class _T1, class _T2>
170    inline bool
171    operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
172    { return __x.first < __y.first
173	     || (!(__y.first < __x.first) && __x.second < __y.second); }
174
175  /// Uses @c operator== to find the result.
176  template<class _T1, class _T2>
177    inline bool
178    operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
179    { return !(__x == __y); }
180
181  /// Uses @c operator< to find the result.
182  template<class _T1, class _T2>
183    inline bool
184    operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
185    { return __y < __x; }
186
187  /// Uses @c operator< to find the result.
188  template<class _T1, class _T2>
189    inline bool
190    operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
191    { return !(__y < __x); }
192
193  /// Uses @c operator< to find the result.
194  template<class _T1, class _T2>
195    inline bool
196    operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
197    { return !(__x < __y); }
198
199#ifdef __GXX_EXPERIMENTAL_CXX0X__
200  /// See std::pair::swap().
201  // Note:  no std::swap overloads in C++03 mode, this has performance
202  //        implications, see, eg, libstdc++/38466.
203  template<class _T1, class _T2>
204    inline void
205    swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
206    { __x.swap(__y); }
207
208  template<class _T1, class _T2>
209    inline void
210    swap(pair<_T1, _T2>&& __x, pair<_T1, _T2>& __y)
211    { __x.swap(__y); }
212
213  template<class _T1, class _T2>
214    inline void
215    swap(pair<_T1, _T2>& __x, pair<_T1, _T2>&& __y)
216    { __x.swap(__y); }
217#endif
218
219  /**
220   *  @brief A convenience wrapper for creating a pair from two objects.
221   *  @param  x  The first object.
222   *  @param  y  The second object.
223   *  @return   A newly-constructed pair<> object of the appropriate type.
224   *
225   *  The standard requires that the objects be passed by reference-to-const,
226   *  but LWG issue #181 says they should be passed by const value.  We follow
227   *  the LWG by default.
228   */
229  // _GLIBCXX_RESOLVE_LIB_DEFECTS
230  // 181.  make_pair() unintended behavior
231#ifndef __GXX_EXPERIMENTAL_CXX0X__
232  template<class _T1, class _T2>
233    inline pair<_T1, _T2>
234    make_pair(_T1 __x, _T2 __y)
235    { return pair<_T1, _T2>(__x, __y); }
236#else
237  template<typename _Tp>
238    class reference_wrapper;
239
240  // Helper which adds a reference to a type when given a reference_wrapper
241  template<typename _Tp>
242    struct __strip_reference_wrapper
243    {
244      typedef _Tp __type;
245    };
246
247  template<typename _Tp>
248    struct __strip_reference_wrapper<reference_wrapper<_Tp> >
249    {
250      typedef _Tp& __type;
251    };
252
253  template<typename _Tp>
254    struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
255    {
256      typedef _Tp& __type;
257    };
258
259  template<typename _Tp>
260    struct __decay_and_strip
261    {
262      typedef typename __strip_reference_wrapper<
263	typename decay<_Tp>::type>::__type __type;
264    };
265
266  // NB: DR 706.
267  template<class _T1, class _T2>
268    inline pair<typename __decay_and_strip<_T1>::__type,
269		typename __decay_and_strip<_T2>::__type>
270    make_pair(_T1&& __x, _T2&& __y)
271    {
272      return pair<typename __decay_and_strip<_T1>::__type,
273	          typename __decay_and_strip<_T2>::__type>
274	(std::forward<_T1>(__x), std::forward<_T2>(__y));
275    }
276#endif
277
278_GLIBCXX_END_NAMESPACE
279
280#endif /* _STL_PAIR_H */
281