mf
Media Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
elem_tuple.h
Go to the documentation of this file.
1 #ifndef MF_ELEM_TUPLE_H_
2 #define MF_ELEM_TUPLE_H_
3 
4 #include <cstddef>
5 #include <cstdint>
6 #include <utility>
7 #include <type_traits>
8 #include "elem.h"
9 
10 namespace mf {
11 
13 
15 template<typename First_elem, typename... Other_elems>
16 class elem_tuple {
17  static_assert(! elem_traits<First_elem>::is_tuple, "elem_tuple element must not be another tuple");
18 
19 public:
20  using others_tuple_type = elem_tuple<Other_elems...>;
22 
23  First_elem first_;
25 
26 public:
27  elem_tuple() = default;
28  elem_tuple(const elem_tuple&) = default;
29  elem_tuple(elem_tuple&&) = default;
30 
31  elem_tuple(const First_elem& first, const Other_elems&... others) :
32  first_(first), others_(others...) { }
33 
34  elem_tuple& operator=(const elem_tuple&) = default;
35  elem_tuple& operator=(elem_tuple&&) = default;
36 
37  friend bool operator==(const elem_tuple& a, const elem_tuple& b) {
38  return (a.first_ == b.first_) && (a.others_ == b.others_);
39  }
40  friend bool operator!=(const elem_tuple& a, const elem_tuple& b) {
41  return (a.first_ != b.first_) || (a.others_ != b.others_);
42  }
43 
44  constexpr static std::size_t size() { return 1 + sizeof...(Other_elems); }
45 
46  bool is_null() const noexcept { return is_null(first_) || is_null(others_); }
47 };
48 
49 
50 
51 template<typename First_elem>
52 class elem_tuple<First_elem> {
53  static_assert(! elem_traits<First_elem>::is_tuple, "elem_tuple element must not be another tuple");
54 
55 public:
56  First_elem first_;
58 
59 public:
60  elem_tuple() = default;
61  elem_tuple(const elem_tuple&) = default;
62  elem_tuple(elem_tuple&&) = default;
63 
64  explicit elem_tuple(const First_elem& first) :
65  first_(first) { }
66 
67  elem_tuple& operator=(const elem_tuple&) = default;
68  elem_tuple& operator=(elem_tuple&&) = default;
69 
70  friend bool operator==(const elem_tuple& a, const elem_tuple& b) {
71  return (a.first_ == b.first_);
72  }
73  friend bool operator!=(const elem_tuple& a, const elem_tuple& b) {
74  return (a.first_ != b.first_);
75  }
76 
77  constexpr static std::size_t size() { return 1; }
78 
79  bool is_null() const noexcept { return is_null(first_); }
80 };
81 
82 
83 
84 namespace detail {
85  template<std::ptrdiff_t Index, typename Tuple>
86  struct elem_tuple_accessor;
87 
88 
89  template<std::ptrdiff_t Index, typename First_elem, typename... Other_elems>
90  struct elem_tuple_accessor<Index, elem_tuple<First_elem, Other_elems...>> {
91  using tuple_type = elem_tuple<First_elem, Other_elems...>;
92  using others_tuple_type = typename tuple_type::others_tuple_type;
93 
94  static auto& get(tuple_type& tup) {
96  }
97 
98  static const auto& get(const tuple_type& tup) {
100  }
101 
102  constexpr static std::ptrdiff_t offset() {
103  return offsetof(tuple_type, others_) + elem_tuple_accessor<Index - 1, others_tuple_type>::offset();
104  }
105  };
106 
107 
108  template<typename First_elem, typename... Other_elems>
109  struct elem_tuple_accessor<0, elem_tuple<First_elem, Other_elems...>> {
110  using tuple_type = elem_tuple<First_elem, Other_elems...>;
111 
112  static auto& get(tuple_type& tup) {
113  return tup.first_;
114  }
115  static const auto& get(const tuple_type& tup) {
116  return tup.first_;
117  }
118  constexpr static std::ptrdiff_t offset() {
119  return 0;
120  }
121  };
122 }
123 
124 
126 template<typename T, typename Tuple>
127 constexpr std::ptrdiff_t elem_tuple_index = -1;
128 
129 template<typename T, typename First_elem, typename... Other_elems>
130 constexpr std::ptrdiff_t elem_tuple_index<T, elem_tuple<First_elem, Other_elems...>>
131  = 1 + elem_tuple_index<T, elem_tuple<Other_elems...>>;
132 
133 template<typename T, typename... Other_elems>
134 constexpr std::ptrdiff_t elem_tuple_index<T, elem_tuple<T, Other_elems...>>
135  = 0;
136 
137 
139 template<std::size_t Index, typename First_elem, typename... Other_elems>
140 const auto& get(const elem_tuple<First_elem, Other_elems...>& tup) {
141  using tuple_type = std::decay_t<decltype(tup)>;
143 }
144 
145 template<std::size_t Index, typename First_elem, typename... Other_elems>
146 auto& get(elem_tuple<First_elem, Other_elems...>& tup) {
147  using tuple_type = std::decay_t<decltype(tup)>;
149 }
150 
151 
153 template<typename T, typename First_elem, typename... Other_elems>
154 const auto& get(const elem_tuple<First_elem, Other_elems...>& tup) {
155  using tuple_type = std::decay_t<decltype(tup)>;
156  constexpr std::size_t index = elem_tuple_index<T, tuple_type>;
158 }
159 
160 template<typename T, typename First_elem, typename... Other_elems>
161 auto& get(elem_tuple<First_elem, Other_elems...>& tup) {
162  using tuple_type = std::decay_t<decltype(tup)>;
163  constexpr std::size_t index = elem_tuple_index<T, tuple_type>;
165 }
166 
167 
169 template<std::size_t Index, typename Tuple>
170 constexpr std::ptrdiff_t elem_tuple_offset = -1;
171 
172 template<std::size_t Index, typename First_elem, typename... Other_elems>
173 constexpr std::ptrdiff_t elem_tuple_offset<Index, elem_tuple<First_elem, Other_elems...>> =
174  detail::elem_tuple_accessor<Index, elem_tuple<First_elem, Other_elems...>>::offset();
175 
176 
178 template<typename... Elems>
179 elem_tuple<Elems...> make_elem_tuple(const Elems&... elems) {
180  return elem_tuple<Elems...>(elems...);
181 }
182 
183 
185 template<typename... Elems>
186 struct elem_traits<elem_tuple<Elems...>> : elem_traits_base<elem_tuple<Elems...>> {
187  constexpr static bool is_tuple = true;
188  constexpr static bool is_nullable = elem_tuple<Elems...>::is_nullable;
189 };
190 
191 
192 }
193 
194 #endif
First_elem first_
Definition: elem_tuple.h:53
elem_tuple< Elems...> make_elem_tuple(const Elems &...elems)
Make elem_tuple with elements elems.
Definition: elem_tuple.h:179
bool is_null() const noexcept
Definition: elem_tuple.h:46
elem_tuple(const First_elem &first, const Other_elems &...others)
Definition: elem_tuple.h:31
static constexpr std::size_t size()
Definition: elem_tuple.h:44
constexpr std::ptrdiff_t elem_tuple_offset
Offset in bytes of element at index Index in elem_tuple type Tuple.
Definition: elem_tuple.h:170
Heterogeneous tuple of items.
Definition: elem_tuple.h:16
others_tuple_type others_
Definition: elem_tuple.h:24
elem_tuple(const First_elem &first)
Definition: elem_tuple.h:64
First_elem first_
Definition: elem_tuple.h:23
elem_tuple & operator=(const elem_tuple &)=default
elem_tuple()=default
friend bool operator!=(const elem_tuple &a, const elem_tuple &b)
Definition: elem_tuple.h:73
Elem traits base class with the required members.
Definition: elem.h:14
friend bool operator==(const elem_tuple &a, const elem_tuple &b)
Definition: elem_tuple.h:37
Default elem traits, using Elem as standard layout scalar type.
Definition: elem.h:30
static constexpr bool is_nullable
Definition: elem.h:23
auto & get(elem_tuple< First_elem, Other_elems...> &tup)
Definition: elem_tuple.h:146
bool is_null() const noexcept
Definition: elem_tuple.h:79
constexpr std::ptrdiff_t elem_tuple_index
Index of first element of type T in elem_tuple type Tuple.
Definition: elem_tuple.h:127
static constexpr bool is_nullable
Definition: elem_tuple.h:21
static constexpr std::size_t size()
Definition: elem_tuple.h:77
static constexpr bool is_tuple
Definition: elem.h:19
friend bool operator==(const elem_tuple &a, const elem_tuple &b)
Definition: elem_tuple.h:70
friend bool operator!=(const elem_tuple &a, const elem_tuple &b)
Definition: elem_tuple.h:40