JSON Voorhees
Killer JSON for C++
Loading...
Searching...
No Matches
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#pragma once
12
13#include <jsonv/config.hpp>
14
15#include <algorithm>
16#include <initializer_list>
17#include <utility>
18
19namespace jsonv
20{
21namespace detail
22{
23
24/** A generic container that exposes the traversal and modification operations externally. Basically, this is just a way
25 * to allow deriving from \c std::vector without actually doing so.
26**/
27template <typename TStorage>
28class generic_container
29{
30public:
31 using storage_type = TStorage;
32 using size_type = typename storage_type::size_type;
33 using value_type = typename storage_type::value_type;
34 using difference_type = typename storage_type::difference_type;
35 using iterator = typename storage_type::iterator;
36 using const_iterator = typename storage_type::const_iterator;
37 using reverse_iterator = typename storage_type::reverse_iterator;
38 using const_reverse_iterator = typename storage_type::const_reverse_iterator;
39 using reference = typename storage_type::reference;
40 using const_reference = typename storage_type::const_reference;
41 using pointer = typename storage_type::pointer;
42 using const_pointer = typename storage_type::const_pointer;
43 using allocator_type = typename storage_type::allocator_type;
44
45public:
46 generic_container()
47 { }
48
49 explicit generic_container(storage_type data) :
50 _data(std::move(data))
51 { }
52
53 template <typename TInputIterator>
54 generic_container(TInputIterator first, TInputIterator last) :
55 _data(first, last)
56 { }
57
58 generic_container(const generic_container&) = default;
59 generic_container& operator=(const generic_container&) = default;
60 generic_container(generic_container&&) noexcept = default;
61 generic_container& operator=(generic_container&&) = default;
62
63 /** Get the number of elements. **/
65 size_type size() const { return _data.size(); }
66
68 bool empty() const { return _data.empty(); }
69
71 iterator begin() { return _data.begin(); }
73 const_iterator begin() const { return _data.begin(); }
75 const_iterator cbegin() const { return _data.begin(); }
76
78 iterator end() { return _data.end(); }
80 const_iterator end() const { return _data.end(); }
82 const_iterator cend() const { return _data.end(); }
83
85 reverse_iterator rbegin() { return _data.rbegin(); }
87 const_reverse_iterator rbegin() const { return _data.rbegin(); }
89 const_reverse_iterator crbegin() const { return _data.rbegin(); }
90
92 reverse_iterator rend() { return _data.rend(); }
94 const_reverse_iterator rend() const { return _data.rend(); }
96 const_reverse_iterator crend() const { return _data.rend(); }
97
98 reference operator[](size_type idx) { return _data[idx]; }
100 const_reference operator[](size_type idx) const { return _data[idx]; }
101
102 reference at(size_type idx) { return _data.at(idx); }
104 const_reference at(size_type idx) const { return _data.at(idx); }
105
106 reference front() { return _data.front(); }
108 const_reference front() const { return _data.front(); }
109
110 reference back() { return _data.back(); }
112 const_reference back() const { return _data.back(); }
113
114 void clear() { return _data.clear(); }
115
116 iterator insert(const_iterator pos, const value_type& x) { return _data.insert(pos, x); }
117 iterator insert(const_iterator pos, value_type&& x) { return _data.insert(pos, std::move(x)); }
118
119 template <typename TInputIterator>
120 iterator insert(const_iterator pos, TInputIterator first, TInputIterator last)
121 {
122 return _data.insert(pos, first, last);
123 }
124
125 iterator insert(const_iterator pos, std::initializer_list<value_type> ilist)
126 {
127 return _data.insert(pos, ilist);
128 }
129
130 template <typename... TArgs>
131 iterator emplace(const_iterator pos, TArgs&&... args)
132 {
133 return _data.emplace(pos, std::forward<TArgs>(args)...);
134 }
135
136 template <typename... TArgs>
137 void emplace_back(TArgs&&... args)
138 {
139 return _data.emplace_back(std::forward<TArgs>(args)...);
140 }
141
142 void push_back(const value_type& x) { return _data.push_back(x); }
143 void push_back(value_type&& x) { return _data.push_back(std::move(x)); }
144
145 iterator erase(const_iterator pos) { return _data.erase(pos); }
146 iterator erase(const_iterator first, const_iterator last) { return _data.erase(first, last); }
147
148 void pop_back() { return _data.pop_back(); }
149
150protected:
151 storage_type _data;
152};
153
154template <typename TStorage>
156bool operator==(const generic_container<TStorage>& a, const generic_container<TStorage>& b)
157{
158 if (&a == &b)
159 return true;
160 else if (a.size() != b.size())
161 return false;
162 else
163 return std::equal(a.begin(), a.end(), b.begin());
164}
165
166template <typename TStorage>
168bool operator!=(const generic_container<TStorage>& a, const generic_container<TStorage>& b)
169{
170 return !(a == b);
171}
172
173}
174}
Copyright (c) 2014-2020 by Travis Gockel.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
Definition config.hpp:132
@ insert
Insert the correct key/value pair as part of serialization.
STL namespace.