All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
triple.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_UTILITY_TRIPLE_HPP
23 #define GEARS_UTILITY_TRIPLE_HPP
24 
25 #include "../meta/alias.hpp"
26 #include <cstddef>
27 
28 namespace gears {
29 namespace utility {
54 template<typename T, typename U, typename V>
55 struct triple {
56  using first_type = T;
57  using second_type = U;
58  using third_type = V;
59 
60  T first;
61  U second;
62  V third;
63 
70  void swap(triple& t) noexcept(noexcept(std::swap(first, t.first)) &&
71  noexcept(std::swap(second, t.second)) &&
72  noexcept(std::swap(third, t.third))) {
73  using std::swap;
74  swap(first, t.first);
75  swap(second, t.second);
76  swap(third, t.third);
77  }
78 };
79 
91 template<typename T, typename U, typename V>
92 constexpr bool operator==(const triple<T, U, V>& lhs, const triple<T, U, V>& rhs) {
93  return lhs.first == rhs.first && lhs.second == rhs.second && lhs.third == rhs.third;
94 }
95 
105 template<typename T, typename U, typename V>
106 constexpr bool operator<(const triple<T, U, V>& lhs, const triple<T, U, V>& rhs) {
107  return lhs.first < rhs.first ? true :
108  rhs.first < lhs.first ? false :
109  lhs.second < rhs.second ? true :
110  rhs.second < lhs.second ? false :
111  lhs.third < rhs.third;
112 }
113 
124 template<typename T, typename U, typename V>
125 constexpr bool operator!=(const triple<T, U, V>& lhs, const triple<T, U, V>& rhs) {
126  return !(lhs == rhs);
127 }
128 
138 template<typename T, typename U, typename V>
139 constexpr bool operator>(const triple<T, U, V>& lhs, const triple<T, U, V>& rhs) {
140  return (rhs < lhs);
141 }
142 
153 template<typename T, typename U, typename V>
154 constexpr bool operator>=(const triple<T, U, V>& lhs, const triple<T, U, V>& rhs) {
155  return !(lhs < rhs);
156 }
157 
168 template<typename T, typename U, typename V>
169 constexpr bool operator<=(const triple<T, U, V>& lhs, const triple<T, U, V>& rhs) {
170  return !(rhs < lhs);
171 }
172 
181 template<typename T, typename U, typename V>
182 inline void swap(triple<T, U, V>& lhs, triple<T, U, V>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
183  lhs.swap(rhs);
184 }
185 
203 template<typename T, typename U, typename V>
205  return { std::forward<T>(t), std::forward<U>(u), std::forward<V>(v) };
206 }
207 } // utility
208 } // gears
209 
210 namespace triple_detail {
211 template<size_t N> struct triple_get;
212 
213 template<>
214 struct triple_get<0> {
215  template<typename T, typename U, typename V>
216  static constexpr T& get(gears::utility::triple<T, U, V>& t) noexcept {
217  return t.first;
218  }
219 
220  template<typename T, typename U, typename V>
221  static constexpr const T& const_get(const gears::utility::triple<T, U, V>& t) noexcept {
222  return t.first;
223  }
224 
225  template<typename T, typename U, typename V>
226  static constexpr T&& move_get(gears::utility::triple<T, U, V>&& t) noexcept {
227  return std::forward<T>(t.first);
228  }
229 };
230 
231 template<>
232 struct triple_get<1> {
233  template<typename T, typename U, typename V>
234  static constexpr U& get(gears::utility::triple<T, U, V>& t) noexcept {
235  return t.second;
236  }
237 
238  template<typename T, typename U, typename V>
239  static constexpr const U& const_get(const gears::utility::triple<T, U, V>& t) noexcept {
240  return t.second;
241  }
242 
243  template<typename T, typename U, typename V>
244  static constexpr U&& move_get(gears::utility::triple<T, U, V>&& t) noexcept {
245  return std::forward<U>(t.second);
246  }
247 };
248 
249 template<>
250 struct triple_get<2> {
251  template<typename T, typename U, typename V>
252  static constexpr V& get(gears::utility::triple<T, U, V>& t) noexcept {
253  return t.third;
254  }
255 
256  template<typename T, typename U, typename V>
257  static constexpr const V& const_get(const gears::utility::triple<T, U, V>& t) noexcept {
258  return t.third;
259  }
260 
261  template<typename T, typename U, typename V>
262  static constexpr V&& move_get(gears::utility::triple<T, U, V>&& t) noexcept {
263  return std::forward<V>(t.third);
264  }
265 };
266 } // triple_detail
267 
268 namespace std {
269 template<typename T> struct tuple_size;
270 template<size_t N, typename T> struct tuple_element;
271 
272 template<typename T, typename U, typename V>
273 struct tuple_size<gears::utility::triple<T, U, V>> : gears::meta::Const<size_t, 3> {};
274 
275 template<typename T, typename U, typename V>
276 struct tuple_element<0, gears::utility::triple<T, U, V>> {
277  using type = T;
278 };
279 
280 template<typename T, typename U, typename V>
281 struct tuple_element<1, gears::utility::triple<T, U, V>> {
282  using type = U;
283 };
284 
285 template<typename T, typename U, typename V>
286 struct tuple_element<2, gears::utility::triple<T, U, V>> {
287  using type = V;
288 };
289 } // std
290 
291 namespace gears {
292 namespace utility {
293 template<size_t N, typename T, typename U, typename V>
294 constexpr gears::meta::Type<std::tuple_element<N, triple<T, U, V>>>& get(triple<T, U, V>& t) noexcept {
296 }
297 
298 template<size_t N, typename T, typename U, typename V>
299 constexpr const gears::meta::Type<std::tuple_element<N, triple<T, U, V>>>& get(const triple<T, U, V>& t) noexcept {
300  return triple_detail::triple_get<N>::const_get(t);
301 }
302 
303 template<size_t N, typename T, typename U, typename V>
304 constexpr gears::meta::Type<std::tuple_element<N, triple<T, U, V>>>&& get(triple<T, U, V>&& t) noexcept {
305  return triple_detail::triple_get<N>::move_get(std::move(t));
306 }
307 } // utility
308 } // gears
309 
310 #endif // GEARS_UTILITY_TRIPLE_HPP