indigoX
triple.hpp
Go to the documentation of this file.
1 #include <type_traits>
2 #include <utility>
3 
4 #ifndef INDIGOX_UTILS_TRIPLE_HPP
5 #define INDIGOX_UTILS_TRIPLE_HPP
6 
7 #include "serialise.hpp"
8 
9 namespace stdx { // extended std namespace
10 
11  template <class _T1, class _T2 = _T1, class _T3 = _T2> struct triple {
12  typedef _T1 first_type;
13  typedef _T2 second_type;
14  typedef _T3 third_type;
15 
16  union {
19  };
20  union {
23  };
24  union {
27  };
28 
29  triple(triple const &t) : A(t.A), B(t.B), C(t.C){};
31  : A(std::move(t.A)), B(std::move(t.B)), C(std::move(t.C)){};
32  ~triple() {}
33 
34  inline constexpr triple() : first(), second(), third() {}
35 
36  inline constexpr triple(_T1 const &__t1, _T2 const &__t2, _T3 const &__t3)
37  : first(__t1), second(__t2), third(__t3) {}
38 
39  template <class _U1, class _U2, class _U3>
40  inline constexpr triple(_U1 &&__u1, _U2 &&__u2, _U3 &&__u3)
41  : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)),
42  third(std::forward<_U3>(__u3)) {}
43 
44  template <class _U1, class _U2, class _U3>
45  inline constexpr triple(triple<_U1, _U2, _U3> const &__p)
46  : first(__p.first), second(__p.second), third(__p.third) {}
47 
48  template <class _U1, class _U2, class _U3>
49  inline constexpr triple(triple<_U1, _U2, _U3> &&__p)
50  : first(std::forward<_U1>(__p.first)),
51  second(std::forward<_U2>(__p.second)),
52  third(std::forward<_U3>(__p.third)) {}
53 
54  inline triple &operator=(
55  typename std::conditional<
56  std::is_copy_assignable<first_type>::value &&
57  std::is_copy_assignable<second_type>::value &&
58  std::is_copy_assignable<third_type>::value,
59  triple, stdx::typeless>::type const
60  &__p) noexcept(std::is_nothrow_copy_assignable<first_type>::value
61  &&std::is_nothrow_copy_assignable<second_type>::
62  value &&std::is_nothrow_copy_assignable<
63  third_type>::value) {
64  first = __p.first;
65  second = __p.second;
66  third = __p.third;
67  return *this;
68  }
69 
70  inline triple &operator=(
71  typename std::conditional<
72  std::is_move_assignable<first_type>::value &&
73  std::is_move_assignable<second_type>::value &&
74  std::is_move_assignable<third_type>::value,
75  triple, stdx::typeless>::type
76  &&__p) noexcept(std::is_nothrow_move_assignable<first_type>::value
77  &&std::is_nothrow_move_assignable<second_type>::
78  value &&std::is_nothrow_move_assignable<
79  third_type>::value) {
80  first = std::forward<first_type>(__p.first);
81  second = std::forward<second_type>(__p.second);
82  third = std::forward<third_type>(__p.third);
83  return *this;
84  }
85 
86  inline void swap(triple &__p) noexcept(
87  std::is_nothrow_swappable<first_type>::value
88  &&std::is_nothrow_swappable<second_type>::value
89  &&std::is_nothrow_swappable<third_type>::value) {
90  using std::swap;
91  swap(first, __p.first);
92  swap(second, __p.second);
93  swap(third, __p.third);
94  }
95 
96  template <typename Archive>
97  void serialise(Archive &archive, const uint32_t) {
98  archive(INDIGOX_SERIAL_NVP("first", first),
99  INDIGOX_SERIAL_NVP("second", second),
100  INDIGOX_SERIAL_NVP("third", third));
101  }
102  };
103 
104  template <class _T1, class _T2, class _T3>
105  inline constexpr bool operator==(const triple<_T1, _T2, _T3> &__x,
106  const triple<_T1, _T2, _T3> &__y) {
107  return __x.first == __y.first && __x.second == __y.second &&
108  __x.third == __y.third;
109  }
110 
111  template <class _T1, class _T2, class _T3>
112  inline constexpr bool operator!=(const triple<_T1, _T2, _T3> &__x,
113  const triple<_T1, _T2, _T3> &__y) {
114  return !(__x == __y);
115  }
116 
117  template <class _T1, class _T2, class _T3>
118  inline constexpr bool operator<(const triple<_T1, _T2, _T3> &__x,
119  const triple<_T1, _T2, _T3> &__y) {
120  return __x.first < __y.first ||
121  (!(__y.first < __x.first) && __x.second < __y.second) ||
122  (!(__y.first < __x.first) && !(__y.second < __x.second) &&
123  __x.third < __y.third);
124  }
125 
126  template <class _T1, class _T2, class _T3>
127  inline constexpr bool operator>(const triple<_T1, _T2, _T3> &__x,
128  const triple<_T1, _T2, _T3> &__y) {
129  return __y < __x;
130  }
131 
132  template <class _T1, class _T2, class _T3>
133  inline constexpr bool operator>=(const triple<_T1, _T2, _T3> &__x,
134  const triple<_T1, _T2, _T3> &__y) {
135  return !(__x < __y);
136  }
137 
138  template <class _T1, class _T2, class _T3>
139  inline constexpr bool operator<=(const triple<_T1, _T2, _T3> &__x,
140  const triple<_T1, _T2, _T3> &__y) {
141  return !(__y < __x);
142  }
143 
144  template <class _T1, class _T2, class _T3>
145  inline typename std::enable_if<std::is_swappable<_T1>::value &&
146  std::is_swappable<_T2>::value &&
147  std::is_swappable<_T3>::value,
148  void>::type
150  (std::is_nothrow_swappable<_T1>::value &&
151  std::is_nothrow_swappable<_T2>::value &&
152  std::is_nothrow_swappable<_T3>::value)) {
153  __x.swap(__y);
154  }
155 
156  template <class _Tp> struct __make_triple_return_impl { typedef _Tp type; };
157 
158  template <class _Tp>
159  struct __make_triple_return_impl<std::reference_wrapper<_Tp>> {
160  typedef _Tp &type;
161  };
162 
163  template <class _Tp> struct __make_triple_return {
164  typedef
167  };
168 
169  template <class _T1, class _T2, class _T3>
173  make_triple(_T1 &&__t1, _T2 &&__t2, _T3 &&__t3) {
177  std::forward<_T1>(__t1), std::forward<_T2>(__t2),
178  std::forward<_T3>(__t3));
179  }
180 } // namespace stdx
181 
182 #endif /* INDIGOX_UTILS_TRIPLE_HPP */
Definition: triple.hpp:163
std::enable_if< std::is_swappable< _T1 >::value &&std::is_swappable< _T2 >::value &&std::is_swappable< _T3 >::value &&std::is_swappable< _T4 >::value, void >::type swap(quad< _T1, _T2, _T3, _T4 > &__x, quad< _T1, _T2, _T3, _T4 > &__y) noexcept((std::is_nothrow_swappable< _T1 >::value &&std::is_nothrow_swappable< _T2 >::value &&std::is_nothrow_swappable< _T3 >::value &&std::is_nothrow_swappable< _T4 >::value))
Definition: quad.hpp:157
constexpr bool operator>(const quad< _T1, _T2, _T3, _T4 > &__x, const quad< _T1, _T2, _T3, _T4 > &__y)
Definition: quad.hpp:135
Definition: triple.hpp:156
first_type A
Definition: triple.hpp:18
third_type C
Definition: triple.hpp:26
__make_triple_return_impl< typename std::decay< _Tp >::type >::type type
Definition: triple.hpp:166
first_type first
Definition: triple.hpp:17
#define INDIGOX_SERIAL_NVP(name, value)
Definition: serialise.hpp:66
_Tp type
Definition: triple.hpp:156
constexpr triple(_T1 const &__t1, _T2 const &__t2, _T3 const &__t3)
Definition: triple.hpp:36
second_type second
Definition: triple.hpp:21
constexpr triple< typename __make_triple_return< _T1 >::type, typename __make_triple_return< _T2 >::type, typename __make_triple_return< _T3 >::type > make_triple(_T1 &&__t1, _T2 &&__t2, _T3 &&__t3)
Definition: triple.hpp:173
constexpr triple(_U1 &&__u1, _U2 &&__u2, _U3 &&__u3)
Definition: triple.hpp:40
constexpr bool operator<(const quad< _T1, _T2, _T3, _T4 > &__x, const quad< _T1, _T2, _T3, _T4 > &__y)
Definition: quad.hpp:124
_T3 third_type
Definition: triple.hpp:14
third_type third
Definition: triple.hpp:25
_T2 second_type
Definition: triple.hpp:13
constexpr bool operator!=(const quad< _T1, _T2, _T3, _T4 > &__x, const quad< _T1, _T2, _T3, _T4 > &__y)
Definition: quad.hpp:118
constexpr triple()
Definition: triple.hpp:34
Definition: serialise.hpp:24
Definition: triple.hpp:11
triple & operator=(typename std::conditional< std::is_copy_assignable< first_type >::value &&std::is_copy_assignable< second_type >::value &&std::is_copy_assignable< third_type >::value, triple, stdx::typeless >::type const &__p) noexcept(std::is_nothrow_copy_assignable< first_type >::value &&std::is_nothrow_copy_assignable< second_type >::value &&std::is_nothrow_copy_assignable< third_type >::value)
Definition: triple.hpp:54
constexpr triple(triple< _U1, _U2, _U3 > const &__p)
Definition: triple.hpp:45
~triple()
Definition: triple.hpp:32
void serialise(Archive &archive, const uint32_t)
Definition: triple.hpp:97
std::enable_if< std::is_swappable< _T1 >::value &&std::is_swappable< _T2 >::value &&std::is_swappable< _T3 >::value, void >::type swap(triple< _T1, _T2, _T3 > &__x, triple< _T1, _T2, _T3 > &__y) noexcept((std::is_nothrow_swappable< _T1 >::value &&std::is_nothrow_swappable< _T2 >::value &&std::is_nothrow_swappable< _T3 >::value))
Definition: triple.hpp:149
Definition: quad.hpp:9
constexpr triple(triple< _U1, _U2, _U3 > &&__p)
Definition: triple.hpp:49
triple(triple &&t)
Definition: triple.hpp:30
void swap(triple &__p) noexcept(std::is_nothrow_swappable< first_type >::value &&std::is_nothrow_swappable< second_type >::value &&std::is_nothrow_swappable< third_type >::value)
Definition: triple.hpp:86
triple(triple const &t)
Definition: triple.hpp:29
second_type B
Definition: triple.hpp:22
constexpr bool operator>=(const quad< _T1, _T2, _T3, _T4 > &__x, const quad< _T1, _T2, _T3, _T4 > &__y)
Definition: quad.hpp:141
_T1 first_type
Definition: triple.hpp:12
constexpr bool operator<=(const quad< _T1, _T2, _T3, _T4 > &__x, const quad< _T1, _T2, _T3, _T4 > &__y)
Definition: quad.hpp:147
triple & operator=(typename std::conditional< std::is_move_assignable< first_type >::value &&std::is_move_assignable< second_type >::value &&std::is_move_assignable< third_type >::value, triple, stdx::typeless >::type &&__p) noexcept(std::is_nothrow_move_assignable< first_type >::value &&std::is_nothrow_move_assignable< second_type >::value &&std::is_nothrow_move_assignable< third_type >::value)
Definition: triple.hpp:70
constexpr bool operator==(const quad< _T1, _T2, _T3, _T4 > &__x, const quad< _T1, _T2, _T3, _T4 > &__y)
Definition: quad.hpp:111