1/* Copyright 2015 OpenMarket Ltd
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef OLM_LIST_HH_
16#define OLM_LIST_HH_
17
18#include <cstddef>
19
20namespace olm {
21
22template<typename T, std::size_t max_size>
23class List {
24public:
25 List() : _end(_data) {}
26
27 typedef T * iterator;
28 typedef T const * const_iterator;
29
30 T * begin() { return _data; }
31 T * end() { return _end; }
32 T const * begin() const { return _data; }
33 T const * end() const { return _end; }
34
35 /**
36 * Is the list empty?
37 */
38 bool empty() const { return _end == _data; }
39
40 /**
41 * The number of items in the list.
42 */
43 std::size_t size() const { return _end - _data; }
44
45 T & operator[](std::size_t index) { return _data[index]; }
46
47 T const & operator[](std::size_t index) const { return _data[index]; }
48
49 /**
50 * Erase the item from the list at the given position.
51 */
52 void erase(T * pos) {
53 --_end;
54 while (pos != _end) {
55 *pos = *(pos + 1);
56 ++pos;
57 }
58 }
59
60 /**
61 * Make space for an item in the list at a given position.
62 * If inserting the item makes the list longer than max_size then
63 * the end of the list is discarded.
64 * Returns the where the item is inserted.
65 */
66 T * insert(T * pos) {
67 if (_end != _data + max_size) {
68 ++_end;
69 } else if (pos == _end) {
70 --pos;
71 }
72 T * tmp = _end - 1;
73 while (tmp != pos) {
74 *tmp = *(tmp - 1);
75 --tmp;
76 }
77 return pos;
78 }
79
80 /**
81 * Make space for an item in the list at the start of the list
82 */
83 T * insert() { return insert(begin()); }
84
85 /**
86 * Insert an item into the list at a given position.
87 * If inserting the item makes the list longer than max_size then
88 * the end of the list is discarded.
89 * Returns the where the item is inserted.
90 */
91 T * insert(T * pos, T const & value) {
92 pos = insert(pos);
93 *pos = value;
94 return pos;
95 }
96
97 List<T, max_size> & operator=(List<T, max_size> const & other) {
98 if (this == &other) {
99 return *this;
100 }
101 T * this_pos = _data;
102 T * const other_pos = other._data;
103 while (other_pos != other._end) {
104 *this_pos = *other;
105 ++this_pos;
106 ++other_pos;
107 }
108 _end = this_pos;
109 return *this;
110 }
111
112private:
113 T * _end;
114 T _data[max_size];
115};
116
117} // namespace olm
118
119#endif /* OLM_LIST_HH_ */
120