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 | |
20 | namespace olm { |
21 | |
22 | template<typename T, std::size_t max_size> |
23 | class List { |
24 | public: |
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 | |
112 | private: |
113 | T * _end; |
114 | T _data[max_size]; |
115 | }; |
116 | |
117 | } // namespace olm |
118 | |
119 | #endif /* OLM_LIST_HH_ */ |
120 | |