JSON Voorhees
Killer JSON for C++
generic_container.hpp
Go to the documentation of this file.
1 /** \file jsonv/detail/generic_container.hpp
2  *
3  * Copyright (c) 2014 by Travis Gockel. All rights reserved.
4  *
5  * This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
6  * as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * \author Travis Gockel (travis@gockelhut.com)
10 **/
11 #ifndef __JSONV_DETAIL_GENERIC_CONTAINER_HPP_INCLUDED__
12 #define __JSONV_DETAIL_GENERIC_CONTAINER_HPP_INCLUDED__
13 
14 #include <jsonv/config.hpp>
15 
16 #include <algorithm>
17 #include <initializer_list>
18 #include <utility>
19 
20 namespace jsonv
21 {
22 namespace detail
23 {
24 
25 /** A generic container that exposes the traversal and modification operations externally. Basically, this is just a way
26  * to allow deriving from \c std::vector without actually doing so.
27 **/
28 template <typename TStorage>
30 {
31 public:
32  using storage_type = TStorage;
33  using size_type = typename storage_type::size_type;
34  using value_type = typename storage_type::value_type;
35  using difference_type = typename storage_type::difference_type;
36  using iterator = typename storage_type::iterator;
37  using const_iterator = typename storage_type::const_iterator;
38  using reverse_iterator = typename storage_type::reverse_iterator;
39  using const_reverse_iterator = typename storage_type::const_reverse_iterator;
40  using reference = typename storage_type::reference;
41  using const_reference = typename storage_type::const_reference;
42  using pointer = typename storage_type::pointer;
43  using const_pointer = typename storage_type::const_pointer;
44  using allocator_type = typename storage_type::allocator_type;
45 
46 public:
48  { }
49 
50  explicit generic_container(storage_type data) :
51  _data(std::move(data))
52  { }
53 
54  template <typename TInputIterator>
55  generic_container(TInputIterator first, TInputIterator last) :
56  _data(first, last)
57  { }
58 
59  generic_container(const generic_container&) = default;
60  generic_container& operator=(const generic_container&) = default;
61  generic_container(generic_container&&) noexcept = default;
62  generic_container& operator=(generic_container&&) = default;
63 
64  /** Get the number of elements. **/
65  size_type size() const { return _data.size(); }
66 
67  bool empty() const { return _data.empty(); }
68 
69  iterator begin() { return _data.begin(); }
70  const_iterator begin() const { return _data.begin(); }
71  const_iterator cbegin() const { return _data.begin(); }
72 
73  iterator end() { return _data.end(); }
74  const_iterator end() const { return _data.end(); }
75  const_iterator cend() const { return _data.end(); }
76 
77  reverse_iterator rbegin() { return _data.rbegin(); }
78  const_reverse_iterator rbegin() const { return _data.rbegin(); }
79  const_reverse_iterator crbegin() const { return _data.rbegin(); }
80 
81  reverse_iterator rend() { return _data.rend(); }
82  const_reverse_iterator rend() const { return _data.rend(); }
83  const_reverse_iterator crend() const { return _data.rend(); }
84 
85  reference operator[](size_type idx) { return _data[idx]; }
86  const_reference operator[](size_type idx) const { return _data[idx]; }
87 
88  reference at(size_type idx) { return _data.at(idx); }
89  const_reference at(size_type idx) const { return _data.at(idx); }
90 
91  reference front() { return _data.front(); }
92  const_reference front() const { return _data.front(); }
93 
94  reference back() { return _data.back(); }
95  const_reference back() const { return _data.back(); }
96 
97  void clear() { return _data.clear(); }
98 
99  iterator insert(const_iterator pos, const value_type& x) { return _data.insert(pos, x); }
100  iterator insert(const_iterator pos, value_type&& x) { return _data.insert(pos, std::move(x)); }
101 
102  template <typename TInputIterator>
103  iterator insert(const_iterator pos, TInputIterator first, TInputIterator last)
104  {
105  return _data.insert(pos, first, last);
106  }
107 
108  iterator insert(const_iterator pos, std::initializer_list<value_type> ilist)
109  {
110  return _data.insert(pos, ilist);
111  }
112 
113  template <typename... TArgs>
114  iterator emplace(const_iterator pos, TArgs&&... args)
115  {
116  return _data.emplace(pos, std::forward<TArgs>(args)...);
117  }
118 
119  template <typename... TArgs>
120  void emplace_back(TArgs&&... args)
121  {
122  return _data.emplace_back(std::forward<TArgs>(args)...);
123  }
124 
125  void push_back(const value_type& x) { return _data.push_back(x); }
126  void push_back(value_type&& x) { return _data.push_back(std::move(x)); }
127 
128  iterator erase(const_iterator pos) { return _data.erase(pos); }
129  iterator erase(const_iterator first, const_iterator last) { return _data.erase(first, last); }
130 
131  void pop_back() { return _data.pop_back(); }
132 
133 protected:
134  storage_type _data;
135 };
136 
137 template <typename TStorage>
138 bool operator==(const generic_container<TStorage>& a, const generic_container<TStorage>& b)
139 {
140  if (&a == &b)
141  return true;
142  else if (a.size() != b.size())
143  return false;
144  else
145  return std::equal(a.begin(), a.end(), b.begin());
146 }
147 
148 template <typename TStorage>
149 bool operator!=(const generic_container<TStorage>& a, const generic_container<TStorage>& b)
150 {
151  return !(a == b);
152 }
153 
154 }
155 }
156 
157 #endif/*__JSONV_DETAIL_GENERIC_CONTAINER_HPP_INCLUDED__*/
Copyright (c) 2014-2019 by Travis Gockel.
size_type size() const
Get the number of elements.
A generic container that exposes the traversal and modification operations externally.