DASH  0.3.0
Pair.h
1 #ifndef DASH_DASH_INCLUDE_DASH_PAIR_H_
2 #define DASH_DASH_INCLUDE_DASH_PAIR_H_
3 
4 #include <dash/Meta.h>
5 
6 #include <type_traits>
7 #include <iostream>
8 #include <sstream>
9 
10 
11 namespace dash {
12 
21  template<class T1, class T2>
22  struct Pair
23  {
24  typedef T1 first_type;
25  typedef T2 second_type;
26 
27  T1 first;
28  T2 second;
29 
33  constexpr Pair()
34  : first(), second()
35  { }
36 
40  constexpr Pair(const T1& __a, const T2& __b)
41  : first(__a), second(__b)
42  { }
43 
48  template<class U1, class U2, class = typename
49  std::enable_if<
50  std::is_convertible<const U1&, T1>::value &&
51  std::is_convertible<const U2&, T2>::value>::value>
52  constexpr Pair(const Pair<U1, U2>& p)
53  : first(p.first), second(p.second)
54  { }
55 
56  constexpr Pair(const Pair&) = default;
57  constexpr Pair(Pair&&) = default;
58 
59  template<class U1, class = typename
60  std::enable_if<std::is_convertible<U1, T1>::value>::type>
61  constexpr Pair(U1&& x, const T2& y)
62  : first(std::forward<U1>(x)), second(y)
63  { }
64 
65  template<class U2, class = typename
66  std::enable_if<std::is_convertible<U2, T2>::value>::type>
67  constexpr Pair(const T1& x, U2&& y)
68  : first(x), second(std::forward<U2>(y))
69  { }
70 
71  template<class U1, class U2, class = typename
72  std::enable_if<std::is_convertible<U1, T1>::value &&
73  std::is_convertible<U2, T2>::value>::type>
74  constexpr Pair(U1&& x, U2&& y)
75  : first(std::forward<U1>(x)), second(std::forward<U2>(y))
76  { }
77 
78  template<class U1, class U2, class = typename
79  std::enable_if<std::is_convertible<U1, T1>::value &&
80  std::is_convertible<U2, T2>::value>::type>
81  constexpr Pair(Pair<U1, U2>&& p)
82  : first(std::forward<U1>(p.first)),
83  second(std::forward<U2>(p.second))
84  { }
85 
86  Pair&
87  operator=(const Pair& p) = default;
88 
89  Pair&
90  operator=(Pair&& p)
91  noexcept(
92  std::is_nothrow_move_assignable<T1>::value &&
93  std::is_nothrow_move_assignable<T2>::value) = default;
94 
95  template<class U1, class U2>
96  Pair&
97  operator=(const Pair<U1, U2>& p)
98  {
99  first = p.first;
100  second = p.second;
101  return *this;
102  }
103 
104  template<class U1, class U2>
105  Pair&
106  operator=(Pair<U1, U2>&& p)
107  {
108  first = std::forward<U1>(p.first);
109  second = std::forward<U2>(p.second);
110  return *this;
111  }
112 
113  void
114  swap(Pair& p)
115  noexcept(noexcept(swap(first, p.first))
116  && noexcept(swap(second, p.second)))
117  {
118  std::swap(first, p.first);
119  std::swap(second, p.second);
120  }
121  };
122 
126  template<class T1, class T2>
127  inline constexpr bool
128  operator==(const Pair<T1, T2>& x, const Pair<T1, T2>& y)
129  {
130  return x.first == y.first && x.second == y.second;
131  }
132 
138  template<class T1, class T2>
139  inline constexpr bool
140  operator<(const Pair<T1, T2>& x, const Pair<T1, T2>& y)
141  {
142  return x.first < y.first
143  || (!(y.first < x.first) && !(x.second >= y.second));
144  }
145 
150  template<class T1, class T2>
151  inline constexpr bool
152  operator!=(const Pair<T1, T2>& x, const Pair<T1, T2>& y)
153  {
154  return !(x == y);
155  }
156 
160  template<class T1, class T2>
161  inline constexpr bool
162  operator>(const Pair<T1, T2>& x, const Pair<T1, T2>& y)
163  {
164  return y < x;
165  }
166 
170  template<class T1, class T2>
171  inline constexpr bool
172  operator<=(const Pair<T1, T2>& x, const Pair<T1, T2>& y)
173  {
174  return !(y < x);
175  }
176 
180  template<class T1, class T2>
181  inline constexpr bool
183  {
184  return !(x < y);
185  }
186 
190  template<class T1, class T2>
191  inline void
193  noexcept(noexcept(x.swap(y)))
194  {
195  x.swap(y);
196  }
197 
198  namespace internal {
202  template <class T>
203  struct strip
204  {
205  typedef T type;
206  };
207  template <class T>
208  struct strip<std::reference_wrapper<T>>
209  {
210  typedef T& type;
211  };
212  template <class T>
213  struct decay_and_strip
214  {
215  typedef typename strip<typename std::decay<T>::type>::type type;
216  };
217  } // namespace internal
218 
222  template<class T1, class T2>
224  typename internal::decay_and_strip<T2>::type>
225  make_pair(T1&& x, T2&& y)
226  {
227  typedef typename internal::decay_and_strip<T1>::type ds_type1;
228  typedef typename internal::decay_and_strip<T2>::type ds_type2;
229  typedef Pair<ds_type1, ds_type2> pair_type;
230  return pair_type(std::forward<T1>(x), std::forward<T2>(y));
231  }
232 
233  template<class T1, class T2>
234  std::ostream & operator<<(
235  std::ostream & os,
236  const Pair<T1, T2> & pair)
237  {
238  std::ostringstream ss;
239  ss << dash::typestr(pair)
240  << " { " << pair.first
241  << " , " << pair.second
242  << " } ";
243  return operator<<(os, ss.str());
244  }
245 
246 } // namespace dash
247 
248 
249 #endif /* DASH_DASH_INCLUDE_DASH_PAIR_H_ */
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
constexpr Pair< typename internal::decay_and_strip< T1 >::type, typename internal::decay_and_strip< T2 >::type > make_pair(T1 &&x, T2 &&y)
Convennience wrapper to create a Pair object.
Definition: Pair.h:225
T1 first
second_type is the second bound type
Definition: Pair.h:27
constexpr bool operator>=(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Greater-than-or-equal operator implemented in terms of less-than operator.
Definition: Pair.h:182
constexpr bool operator>(const Pair< T1, T2 > &x, const Pair< T1, T2 > &y)
Greater-than operator implemented in terms of less-than operator.
Definition: Pair.h:162
T2 second_type
first_type is the first bound type
Definition: Pair.h:25
T2 second
first is a copy of the first object
Definition: Pair.h:28
std::string typestr(const T &obj)
Returns string containing the type name of the given object.
Definition: TypeInfo.h:20
constexpr Pair(const T1 &__a, const T2 &__b)
Two objects may be passed to a Pair constructor to be copied.
Definition: Pair.h:40
constexpr Pair()
second is a copy of the second object
Definition: Pair.h:33
A trivially-copyable implementation of std::pair to be used as element type of DASH containers...
Definition: Pair.h:22
constexpr Pair(const Pair< U1, U2 > &p)
A Pair might be constructed from another pair iff first and second are convertible.
Definition: Pair.h:52