siplasplas
meta.hpp
1 #ifndef SIPLASPLAS_CONSTEXPR_META_HPP
2 #define SIPLASPLAS_CONSTEXPR_META_HPP
3 
4 #include "arrayview.hpp"
5 #include "string.hpp"
6 #include <siplasplas/utility/meta.hpp>
7 #include <ostream>
8 
9 namespace cpp
10 {
11 
12 namespace constexp
13 {
14 
15 struct DummyValueToType {};
16 
17 template<typename Seq, typename TypeToValue>
19 
20 template<template<typename...> class Seq, typename Head, typename... Tail, typename TypeToValue>
21 class SequenceToArray<Seq<Head, Tail...>, TypeToValue>
22 {
23 public:
24  using value_type = typename TypeToValue::value_type;
25 
26  constexpr SequenceToArray() = default;
27 
28  static constexpr const value_type& get(std::size_t i)
29  {
30  return array[i];
31  }
32 
33  static constexpr ConstArrayView<value_type> get()
34  {
35  return {Bounds::begin(), Bounds::size()};
36  }
37 
38  struct Bounds
39  {
40  static constexpr std::size_t size()
41  {
42  return sizeof...(Tail) + 1;
43  }
44 
45  static constexpr const value_type* begin()
46  {
47  return array;
48  }
49 
50  static constexpr const value_type* end()
51  {
52  return array + size();
53  }
54 
55  static constexpr const value_type* const cbegin()
56  {
57  return array;
58  }
59 
60  static constexpr const value_type* const cend()
61  {
62  return array + size();
63  }
64  };
65 
66  constexpr std::size_t size() const
67  {
68  return Bounds::size();
69  }
70 
71  constexpr const value_type& operator[](std::size_t i) const
72  {
73  return get(i);
74  }
75 
76  constexpr const value_type* begin() const
77  {
78  return Bounds::begin();
79  }
80 
81  constexpr const value_type* end() const
82  {
83  return Bounds::end();
84  }
85 
86  constexpr const value_type* const cbegin() const
87  {
88  return Bounds::cbegin();
89  }
90 
91  constexpr const value_type* const cend() const
92  {
93  return Bounds::cend();
94  }
95 
96 private:
97  static constexpr value_type array[] = {
98  TypeToValue::template get<Head>(),
99  TypeToValue::template get<Tail>()...
100  };
101 };
102 
103 template<template<typename...> class Seq, typename Head, typename... Tail, typename TypeToValue>
104 constexpr typename TypeToValue::value_type SequenceToArray<Seq<Head, Tail...>, TypeToValue>::array[sizeof...(Tail) + 1];
105 
106 template<template<typename...> class Seq, typename TypeToValue>
107 class SequenceToArray<Seq<>, TypeToValue>
108 {
109 public:
110  using value_type = typename TypeToValue::value_type;
111 
112  constexpr SequenceToArray() = default;
113 
114  static constexpr const value_type& get(std::size_t i)
115  {
116  return *static_cast<value_type*>(nullptr);
117  }
118 
119  struct Bounds
120  {
121  static constexpr std::size_t size()
122  {
123  return 0;
124  }
125 
126  static constexpr const value_type* begin()
127  {
128  return nullptr;
129  }
130 
131  static constexpr const value_type* end()
132  {
133  return nullptr;
134  }
135 
136  static constexpr const value_type* const cbegin()
137  {
138  return nullptr;
139  }
140 
141  static constexpr const value_type* const cend()
142  {
143  return nullptr;
144  }
145  };
146 
147  static constexpr ConstArrayView<value_type> get()
148  {
149  return {static_cast<value_type*>(nullptr), static_cast<std::size_t>(0)};
150  }
151 
152  constexpr std::size_t size() const
153  {
154  return Bounds::size();
155  }
156 
157  constexpr const value_type& operator[](std::size_t i) const
158  {
159  return get(i);
160  }
161 
162  constexpr const value_type* begin() const
163  {
164  return Bounds::begin();
165  }
166 
167  constexpr const value_type* end() const
168  {
169  return Bounds::end();
170  }
171 
172  constexpr const value_type* const cbegin() const
173  {
174  return Bounds::cbegin();
175  }
176 
177  constexpr const value_type* const cend() const
178  {
179  return Bounds::cend();
180  }
181 };
182 
183 template<typename T>
185 {
186  using value_type = T;
187 
188  template<typename IntegralConstant>
189  static constexpr value_type get()
190  {
191  return IntegralConstant::value;
192  }
193 };
194 
195 template<typename T, T... Values>
199 >;
200 
201 template<typename String>
203 
204 template<template<typename...> class Seq, char... Chars>
205 class SequenceToString<Seq<std::integral_constant<char, Chars>...>>
206 {
207 public:
208  static constexpr const String<sizeof...(Chars) + 1>& str()
209  {
210  return _str;
211  }
212 
213  static constexpr const char* c_str()
214  {
215  return _str.c_str();
216  }
217 
218 private:
219  static constexpr String<sizeof...(Chars) + 1> _str{
220  Chars..., '\0'
221  };
222 };
223 
224 template<template<typename...> class Seq, char... Chars>
225 constexpr String<sizeof...(Chars) + 1> SequenceToString<Seq<std::integral_constant<char, Chars>...>>::_str;
226 
227 template<typename Lhs, typename LhsToValue, typename Rhs, typename RhsToValue>
228 constexpr bool operator==(const SequenceToArray<Lhs, LhsToValue>& lhs, const SequenceToArray<Rhs, RhsToValue>& rhs)
229 {
230  return cpp::constexp::equal(lhs, rhs);
231 }
232 
233 template<typename Lhs, typename LhsToValue, typename Rhs, typename RhsToValue>
234 constexpr bool operator!=(const SequenceToArray<Lhs, LhsToValue>& lhs, const SequenceToArray<Rhs, RhsToValue>& rhs)
235 {
236  return !(lhs == rhs);
237 }
238 
239 template<typename Sequence, typename ToValue>
240 std::ostream& operator<<(std::ostream& os, const SequenceToArray<Sequence, ToValue>& sequence)
241 {
242  os << "{";
243 
244  for(std::size_t i = 0; i < sequence.size(); ++i)
245  {
246  if(i < sequence.size() - 1)
247  {
248  os << sequence[i] << ", ";
249  }
250  else
251  {
252  os << sequence[i];
253  }
254  }
255 
256  return os << "}";
257 }
258 
259 template<char... Chars>
262 >;
263 
264 }
265 
266 }
267 
268 #endif // SIPLASPLAS_CONSTEXPR_META_HPP
Definition: arrayview.hpp:87
Definition: messaging.hpp:8
constexpr bool equal(Begin1 begin1, End1 end1, Begin2 begin2, End2 end2, Compare compare)
Compares if two sequences are equal.
Definition: algorithm.hpp:137
Definition: variant.hpp:500
Definition: meta.hpp:225
Definition: string.hpp:17
constexpr auto end(const Sequence &sequence)
Returns an iterator pointing to the end of a sequence.
Definition: algorithm.hpp:86
constexpr auto begin(const Sequence &sequence)
Returns an iterator pointing to the beginning of a sequence.
Definition: algorithm.hpp:62
Definition: meta.hpp:15
Definition: meta.hpp:18
Definition: meta.hpp:202