layer.h
Go to the documentation of this file.
1 #ifndef GARLIC_LAYER_H
2 #define GARLIC_LAYER_H
3 
9 #include "garlic.h"
10 #include "containers.h"
11 
12 #ifdef GARLIC_USE_CONCEPTS
13 #define GARLIC_VIEW garlic::ViewLayer
14 #define GARLIC_REF garlic::RefLayer
15 #define GARLIC_ITERATOR_WRAPPER garlic::IteratorWrapper
16 #else
17 #define GARLIC_VIEW typename
18 #define GARLIC_REF typename
19 #define GARLIC_ITERATOR_WRAPPER typename
20 #endif
21 
22 namespace garlic {
23 
24  enum TypeFlag : uint8_t {
25  Null = 0x1 << 1,
26  Boolean = 0x1 << 2,
27  String = 0x1 << 3,
28  Integer = 0x1 << 4,
29  Double = 0x1 << 5,
30  Object = 0x1 << 6,
31  List = 0x1 << 7,
32  };
33 
34  template<typename T> using ConstValueIteratorOf = typename std::decay_t<T>::ConstValueIterator;
35  template<typename T> using ValueIteratorOf = typename std::decay_t<T>::ValueIterator;
36  template<typename T> using ConstMemberIteratorOf = typename std::decay_t<T>::ConstMemberIterator;
37  template<typename T> using MemberIteratorOf = typename std::decay_t<T>::MemberIterator;
38 
170 #ifdef GARLIC_USE_CONCEPTS
171 
172  template<typename T>
173  concept member_pair = requires(T pair) {
174  { pair.key };
175  { pair.value };
176  };
177 
178  template<typename T>
179  concept forward_pair_iterator = std::forward_iterator<T> && requires(T it) {
180  { *it } -> member_pair;
181  };
182 
183  template<typename T> concept ViewLayer = requires(const T& t) {
184  typename ConstValueIteratorOf<T>;
185  typename ConstMemberIteratorOf<T>;
186 
187  { t.is_null() } -> std::convertible_to<bool>;
188  { t.is_int() } -> std::convertible_to<bool>;
189  { t.is_string() } -> std::convertible_to<bool>;
190  { t.is_double() } -> std::convertible_to<bool>;
191  { t.is_object() } -> std::convertible_to<bool>;
192  { t.is_list() } -> std::convertible_to<bool>;
193  { t.is_bool() } -> std::convertible_to<bool>;
194 
195  { t.get_int() } -> std::convertible_to<int>;
196  { t.get_cstr() } -> std::convertible_to<const char*>;
197  { t.get_string() } -> std::convertible_to<std::string>;
198  { t.get_string_view() } -> std::convertible_to<std::string_view>;
199  { t.get_double() } -> std::convertible_to<double>;
200  { t.get_bool() } -> std::convertible_to<bool>;
201 
202  { t.begin_list() } -> std::forward_iterator;
203  { t.end_list() } -> std::forward_iterator;
204  { t.get_list() } -> std::ranges::range;
205 
206  { t.begin_member() } -> forward_pair_iterator;
207  { t.end_member() } -> forward_pair_iterator;
208  { t.find_member(std::declval<text>()) } -> forward_pair_iterator;
209  { t.get_object() } -> std::ranges::range;
210 
211  { t.get_view() };
212  };
213 
214  template<typename T> concept RefLayer = ViewLayer<T> && requires(T t) {
215  typename ValueIteratorOf<T>;
216  typename MemberIteratorOf<T>;
217 
218  { t.set_string(std::declval<text>()) };
219  { t.set_bool(std::declval<bool>()) };
220  { t.set_int(std::declval<int>()) };
221  { t.set_double(std::declval<double>()) };
222  { t.set_null() };
223  { t.set_list() };
224  { t.set_object() };
225 
226  { t.begin_list() } -> std::forward_iterator;
227  { t.end_list() } -> std::forward_iterator;
228  { t.get_list() } -> std::ranges::range;
229 
230  { t.begin_member() } -> forward_pair_iterator;
231  { t.end_member() } -> forward_pair_iterator;
232  { t.find_member(std::declval<text>()) } -> forward_pair_iterator;
233  { t.get_object() } -> std::ranges::range;
234 
235  /* TODO: <29-01-21, Peyman> Add a constraint to support pushing T. */
236  { t.clear() };
237  { t.push_back() };
238  { t.push_back(std::declval<const char*>()) };
239  { t.push_back(std::declval<text>()) };
240  { t.push_back(std::declval<bool>()) };
241  { t.push_back(std::declval<int>()) };
242  { t.push_back(std::declval<double>()) };
243  { t.push_back_builder(std::declval<void(*)(T)>()) };
244  { t.pop_back() };
245  { t.erase(std::declval<ValueIteratorOf<T>>()) };
246  { t.erase(std::declval<ValueIteratorOf<T>>(), std::declval<ValueIteratorOf<T>>()) };
247 
248  { t.add_member(std::declval<text>()) };
249  { t.add_member(std::declval<text>(), std::declval<const char*>()) };
250  { t.add_member(std::declval<text>(), std::declval<text>()) };
251  { t.add_member(std::declval<text>(), std::declval<bool>()) };
252  { t.add_member(std::declval<text>(), std::declval<int>()) };
253  { t.add_member(std::declval<text>(), std::declval<double>()) };
254  { t.add_member_builder(std::declval<text>(), std::declval<void(*)(T)>()) };
255  { t.remove_member(std::declval<text>()) };
256  { t.erase_member(std::declval<MemberIteratorOf<T>>()) };
257 
258  { t.get_reference() };
259  };
260 
261  template<typename T>
262  concept TypeAbstraction = requires {
263  { T::Null };
264  { T::Boolean };
265  { T::String };
266  { T::Number };
267  { T::Object };
268  { T::List };
269  };
270 
271  template<typename T>
272  concept TypeProvider = requires (const T& value) {
273  { T::type_flag } -> TypeAbstraction;
274  { value.get_type() } -> std::same_as<typename T::type_flag>;
275  };
276 
277  template<typename T>
278  concept IteratorWrapper = requires(T container) {
279  typename T::output_type;
280  typename T::iterator_type;
281 
282  { container.iterator };
283  /* TODO: <28-01-21, Peyman> Figure out why the next line doesn't compile. */
284  // { container.wrap() } -> std::same_as<typename T::output_type>;
285  };
286 #endif
287 
295  template<typename ValueType, typename Iterator>
297  using output_type = ValueType;
298  using iterator_type = Iterator;
299 
300  iterator_type iterator;
301 
302  inline ValueType wrap() const {
303  return ValueType { *iterator };
304  }
305  };
306 
308  template<GARLIC_ITERATOR_WRAPPER Container, typename DifferenceType = std::ptrdiff_t>
310  public:
311  using difference_type = DifferenceType;
312  using value_type = typename Container::output_type;
313  using reference = typename Container::output_type&;
314  using pointer = typename Container::output_type*;
315  using iterator_category = std::forward_iterator_tag;
316  using iterator_type = typename Container::iterator_type;
317  using self = ForwardIterator;
318 
319  ForwardIterator() = default;
320  ForwardIterator(Container container)
321  : container_(std::move(container)) {}
322 
323  self& operator ++ () {
324  ++container_.iterator;
325  return *this;
326  }
327 
328  self operator ++ (int) {
329  auto it = *this;
330  ++container_.iterator;
331  return it;
332  }
333 
334  bool operator == (const self& other) const {
335  return other.container_.iterator == container_.iterator;
336  }
337 
338  bool operator != (const self& other) const { return !(other == *this); }
339 
341  iterator_type& get_inner_iterator() { return container_.iterator; }
342 
344  const iterator_type& get_inner_iterator() const { return container_.iterator; }
345 
347  inline value_type operator * () const { return container_.wrap(); }
348 
349  private:
350  Container container_;
351  };
352 
354  template<GARLIC_ITERATOR_WRAPPER Container, typename DifferenceType = std::ptrdiff_t>
356  public:
357  using difference_type = DifferenceType;
358  using value_type = typename Container::output_type;
359  using reference_type = value_type;
360  using pointer_type = value_type*;
361  using iterator_category = std::random_access_iterator_tag;
362  using iterator_type = typename Container::iterator_type;
363  using self = RandomAccessIterator;
364 
365  RandomAccessIterator() = default;
366  RandomAccessIterator(Container container)
367  : container_(container) {}
368 
369  self& operator ++ () {
370  ++container_.iterator;
371  return *this;
372  }
373 
374  self operator ++ (int) {
375  auto it = *this;
376  ++container_.iterator;
377  return it;
378  }
379 
380  self& operator -- () {
381  --container_.iterator;
382  return *this;
383  }
384 
385  self operator -- (int) {
386  auto it = *this;
387  --container_.iterator;
388  return it;
389  }
390 
391  bool operator == (const self& other) const {
392  return container_.iterator == other.container_.iterator;
393  }
394 
395  bool operator != (const self& other) const {
396  return container_.iterator != other.container_.iterator;
397  }
398 
399  bool operator < (const self& other) const {
400  return container_.iterator < other.container_.iterator;
401  }
402 
403  bool operator > (const self& other) const {
404  return container_.iterator > other.container_.iterator;
405  }
406 
407  bool operator <= (const self& other) const {
408  return container_.iterator <= other.container_.iterator;
409  }
410 
411  bool operator >= (const self& other) const {
412  return container_.iterator >= other.container_.iterator;
413  }
414 
415  self operator + (int value) const {
416  auto it = *this;
417  it.container_.iterator += value;
418  return it;
419  }
420 
421  self& operator += (int value) {
422  container_.iterator += value;
423  return *this;
424  }
425 
426  self operator - (int value) const {
427  auto it = *this;
428  it.container_.iterator -= value;
429  return it;
430  }
431 
432  self& operator -= (int value) {
433  container_.iterator -= value;
434  return *this;
435  }
436 
437  reference_type operator [] (int index) const {
438  return *(*this + index);
439  }
440 
442  iterator_type& get_inner_iterator() { return container_.iterator; }
443 
445  const iterator_type& get_inner_iterator() const {
446  return container_.iterator;
447  }
448 
450  inline value_type operator * () const {
451  return container_.wrap();
452  }
453 
455  operator + (
456  int left,
458  return right += left;
459  }
460 
461  friend inline RandomAccessIterator<Container, DifferenceType>
462  operator - (
463  int left,
464  RandomAccessIterator<Container, DifferenceType> right) {
465  return right -= left;
466  }
467 
468  friend inline DifferenceType
469  operator - (
470  const RandomAccessIterator<Container, DifferenceType>& left,
471  const RandomAccessIterator<Container, DifferenceType>& right) {
472  return left.get_inner_iterator() - right.get_inner_iterator();
473  }
474 
475  private:
476  Container container_;
477  };
478 
493  template<GARLIC_REF LayerType>
495  public:
496  using difference_type = ptrdiff_t;
497  using value_type = void;
498  using reference_type = void;
499  using pointer_type = void;
500  using iterator_category = std::output_iterator_tag;
501  using container_type = LayerType;
502 
503  back_inserter_iterator(LayerType&& layer) : layer_(std::forward<LayerType>(layer)) {}
504 
505  template<typename T>
506  inline void operator = (T&& value) noexcept {
507  layer_.push_back(std::forward<T>(value));
508  }
509 
510  back_inserter_iterator& operator * () { return *this; }
511  back_inserter_iterator& operator ++() { return *this; }
512  back_inserter_iterator& operator ++(int) { return *this; }
513 
514  protected:
515  LayerType layer_;
516  };
517 
519  template<GARLIC_REF LayerType>
521  back_inserter(LayerType&& layer) {
522  return back_inserter_iterator<LayerType>(std::forward<LayerType>(layer));
523  }
524 
530  template<typename ValueType, typename Iterator>
531  using BasicForwardIterator = ForwardIterator<
532  BasicIteratorWrapper<ValueType, Iterator>
533  >;
534 
540  template<typename ValueType, typename Iterator>
543  >;
544 
546  template<typename ValueType, typename KeyType = ValueType>
547  struct MemberPair {
548  KeyType key;
549  ValueType value;
550  };
551 
560  template <typename LayerType>
561  struct ConstListRange {
562  const LayerType& layer;
563 
564  ConstValueIteratorOf<LayerType> begin() const { return layer.begin_list(); }
565  ConstValueIteratorOf<LayerType> end() const { return layer.end_list(); }
566  };
567 
576  template <typename LayerType>
577  struct ListRange {
578  LayerType& layer;
579 
580  ValueIteratorOf<LayerType> begin() { return layer.begin_list(); }
581  ValueIteratorOf<LayerType> end() { return layer.end_list(); }
582  };
583 
592  template <typename LayerType>
594  const LayerType& layer;
595 
596  ConstMemberIteratorOf<LayerType> begin() const { return layer.begin_member(); }
597  ConstMemberIteratorOf<LayerType> end() const { return layer.end_member(); }
598  };
599 
608  template <typename LayerType>
609  struct MemberRange {
610  LayerType& layer;
611 
612  MemberIteratorOf<LayerType> begin() { return layer.begin_member(); }
613  MemberIteratorOf<LayerType> end() { return layer.end_member(); }
614  };
615 
616 }
617 
618 #endif /* end of include guard: GARLIC_LAYER_H */
garlic::RandomAccessIterator::operator*
value_type operator*() const
Definition: layer.h:450
garlic::ForwardIterator::get_inner_iterator
iterator_type & get_inner_iterator()
Definition: layer.h:341
garlic::ConstMemberRange
Wrapper struct that can be used in a for-loop range iterating over an object's members.
Definition: layer.h:593
garlic::RandomAccessIterator::get_inner_iterator
iterator_type & get_inner_iterator()
Definition: layer.h:442
garlic::back_inserter
static back_inserter_iterator< LayerType > back_inserter(LayerType &&layer)
Helper method to produce garlic back inserter iterators.
Definition: layer.h:521
garlic::ConstListRange
Wrapper struct that can be used in a for-loop range iterating over lists.
Definition: layer.h:561
IteratorWrapper
Concept for iterator wrapping guidelines.
garlic::ForwardIterator::get_inner_iterator
const iterator_type & get_inner_iterator() const
Definition: layer.h:344
garlic::RandomAccessIterator::get_inner_iterator
const iterator_type & get_inner_iterator() const
Definition: layer.h:445
RefLayer
Concept for reading from and writing to containers.
garlic::ListRange
Wrapper struct that can be used in a for-loop range iterating over lists.
Definition: layer.h:577
garlic::MemberPair
Generic struct to hold a pair to be used to store key-value associations in an object.
Definition: layer.h:547
garlic::MemberRange
Wrapper struct that can be used in a for-loop range iterating over an object's members.
Definition: layer.h:609
ViewLayer
Concept for reading values from containers.
containers.h
Supporting containers for the garlic model.
garlic::ForwardIterator::operator*
value_type operator*() const
Definition: layer.h:347
garlic::ForwardIterator
A forward iterator that takes an IteratorWrapper as a guide to produce a complete iterator.
Definition: layer.h:309
garlic::BasicIteratorWrapper
A trivial and basic iterator wrapper that conforms to the IteratorWrapper concept.
Definition: layer.h:296
garlic::back_inserter_iterator
A generic bask inserter iterator for all garlic Layer types.
Definition: layer.h:494
garlic::RandomAccessIterator
A random access iterator that takes an IteratorWrapper as a guide to produce a complete iterator.
Definition: layer.h:355