OGLplus  (0.59.0) a C++ wrapper for rendering APIs

key_val_list.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_KEY_VAL_LIST_HPP
10 #define EAGINE_KEY_VAL_LIST_HPP
11 
12 #include "span.hpp"
13 #include <array>
14 #include <type_traits>
15 #include <utility>
16 #include <vector>
17 
18 namespace eagine {
19 
20 template <typename Traits, std::size_t N = 0>
22 
26 template <typename Traits>
29  using key_type = typename Traits::key_type;
31  using value_type = typename Traits::value_type;
32 
33  key_type _key;
34  value_type _value;
35 
37  constexpr key_value_list_element(key_type key, value_type value) noexcept
38  : _key{key}
39  , _value{value} {}
40 };
41 
42 template <typename Traits, std::size_t N>
43 struct key_value_list_base;
44 
45 template <typename Traits>
46 struct key_value_list_base<Traits, 0> {
47  using value_type = typename Traits::value_type;
48 
49  key_value_list_base() = default;
50 
51  static auto data() noexcept -> const value_type* {
52  static const value_type term = Traits::terminator();
53  return &term;
54  }
55 };
56 
57 template <typename Traits>
58 struct key_value_list_base<Traits, 2> {
59  std::array<typename Traits::value_type, 3> _elements;
60 
61  using key_type = typename Traits::key_type;
62  using conv_type = typename Traits::conv_type;
63  using value_type = typename Traits::value_type;
64 
65  constexpr key_value_list_base(key_type key, value_type value) noexcept
66  : _elements{{value_type(conv_type(key)), value, Traits::terminator()}} {}
67 
68  constexpr key_value_list_base(
69  const key_value_list_base<Traits, 0>&,
70  key_type key,
71  value_type value,
72  std::index_sequence<>) noexcept
73  : _elements{{value_type(conv_type(key)), value, Traits::terminator()}} {}
74 
75  auto data() const noexcept -> const value_type* {
76  return _elements.data();
77  }
78 };
79 
80 template <typename Traits, std::size_t N>
81 struct key_value_list_base {
82  std::array<typename Traits::value_type, N + 1> _elements;
83 
84  using key_type = typename Traits::key_type;
85  using conv_type = typename Traits::conv_type;
86  using value_type = typename Traits::value_type;
87 
88  template <
89  std::size_t M,
90  std::size_t... I,
91  typename = std::enable_if_t<(M + 2 == N) && (sizeof...(I) == M)>>
92  constexpr key_value_list_base(
93  const key_value_list_base<Traits, M>& head,
94  key_type key,
95  value_type value,
96  std::index_sequence<I...>) noexcept
97  : _elements{
98  {head._elements[I]...,
99  value_type(conv_type(key)),
100  value,
101  Traits::terminator()}} {}
102 
103  auto data() const noexcept -> const value_type* {
104  return _elements.data();
105  }
106 };
107 
112 template <typename Traits, std::size_t N>
113 class key_value_list {
114 public:
116  using key_type = typename Traits::key_type;
117 
119  using value_type = typename Traits::value_type;
120 
122  key_value_list() = default;
123 
124  template <std::size_t M, typename = std::enable_if_t<M + 2 == N>>
125  constexpr key_value_list(
126  const key_value_list_base<Traits, M>& head,
127  key_type key,
128  value_type value) noexcept
129  : _base(head, key, value, std::make_index_sequence<M>()) {}
130 
132  : _base(head._key, head._value) {}
133 
136  static constexpr auto size() noexcept -> span_size_t {
137  return span_size(N + 1);
138  }
139 
142  auto data() const noexcept -> const value_type* {
143  return _base.data();
144  }
145 
148  auto copy() const noexcept -> std::vector<value_type> {
149  return {data(), data() + size()};
150  }
151 
154  auto get() const noexcept -> span<const value_type> {
155  return {data(), size()};
156  }
157 
159  constexpr auto
160  append(const key_value_list_element<Traits>& key_val) const noexcept
162  return {_base, key_val._key, key_val._value};
163  }
164 
165 private:
166  key_value_list_base<Traits, N> _base;
167 };
168 
173 template <typename Traits>
174 static constexpr auto operator+(
176  const key_value_list_element<Traits>& r) noexcept
178  return key_value_list<Traits, 2>(l).append(r);
179 }
180 
185 template <typename Traits, std::size_t N>
186 static constexpr auto operator+(
187  const key_value_list<Traits, N>& l,
188  const key_value_list_element<Traits>& r) noexcept
190  return l.append(r);
191 }
192 
193 } // namespace eagine
194 
195 #endif // EAGINE_KEY_VAL_LIST_HPP
value_type
Value tree value element data type enumeration.
Definition: interface.hpp:27
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
static constexpr auto span_size(T v) noexcept
Converts argument to span size type.
Definition: types.hpp:59
A single key/value pair for a key/value list.
Definition: key_val_list.hpp:27
Common code is placed in this namespace.
Definition: eagine.hpp:21
typename Traits::key_type key_type
Alias for the key type.
Definition: key_val_list.hpp:116
static constexpr auto head(basic_span< T, P, S > s, L l) noexcept -> basic_span< T, P, S >
Returns the first l elements from the front of a span.
Definition: span_algo.hpp:99
basic_span< T, T *, S > span
Default alias for basic memory spans with native pointer type.
Definition: span.hpp:415
typename Traits::key_type key_type
Alias for the key type.
Definition: key_val_list.hpp:29
Basic N-dimensional vector implementation template.
Definition: fwd.hpp:19
constexpr key_value_list_element(key_type key, value_type value) noexcept
Construction from the key and the value.
Definition: key_val_list.hpp:37
typename Traits::value_type value_type
Alias for the value type.
Definition: key_val_list.hpp:119
typename Traits::value_type value_type
Alias for the value type.
Definition: key_val_list.hpp:31
static constexpr auto operator+(const key_value_list< Traits, N > &l, const key_value_list_element< Traits > &r) noexcept -> key_value_list< Traits, N+2 >
Adds a key/value pair into a key/value list, returns a new list.
Definition: key_val_list.hpp:186
auto get() const noexcept -> span< const value_type >
A const view of the internal element array.
Definition: key_val_list.hpp:154
static constexpr auto size() noexcept -> span_size_t
Returns the size of the element array (including the terminating zero).
Definition: key_val_list.hpp:136
Template for classes wrapping static key/value typically attribute lists.
Definition: key_val_list.hpp:21
constexpr auto append(const key_value_list_element< Traits > &key_val) const noexcept -> key_value_list< Traits, N+2 >
Appends a key/value pair and returns a new extended list.
Definition: key_val_list.hpp:160
static constexpr auto operator+(const key_value_list_element< Traits > &l, const key_value_list_element< Traits > &r) noexcept -> key_value_list< Traits, 4 >
Concatenates two individual key/value elements into a key/value list.
Definition: key_val_list.hpp:174
auto copy() const noexcept -> std::vector< value_type >
Copies the internal element array into a vector.
Definition: key_val_list.hpp:148
auto data() const noexcept -> const value_type *
Returns a pointer to the internal element array.
Definition: key_val_list.hpp:142

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).