1 : /* GRAPHITE2 LICENSING
2 :
3 : Copyright 2010, SIL International
4 : All rights reserved.
5 :
6 : This library is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU Lesser General Public License as published
8 : by the Free Software Foundation; either version 2.1 of License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should also have received a copy of the GNU Lesser General Public
17 : License along with this library in the file named "LICENSE".
18 : If not, write to the Free Software Foundation, 51 Franklin Street,
19 : Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20 : internet at http://www.fsf.org/licenses/lgpl.html.
21 :
22 : Alternatively, the contents of this file may be used under the terms of the
23 : Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 : License, as published by the Free Software Foundation, either version 2
25 : of the License or (at your option) any later version.
26 : */
27 :
28 : // designed to have a limited subset of the std::vector api
29 : #pragma once
30 :
31 : #include <cassert>
32 : #include <cstring>
33 : #include <cstdlib>
34 : #include <new>
35 :
36 :
37 : namespace graphite2 {
38 :
39 : template <typename T>
40 : inline
41 0 : ptrdiff_t distance(T* first, T* last) { return last-first; }
42 :
43 :
44 : template <typename T>
45 : class Vector
46 : {
47 : T * m_first, *m_last, *m_end;
48 : public:
49 : typedef T & reference;
50 : typedef const T & const_reference;
51 : typedef T * iterator;
52 : typedef const T * const_iterator;
53 :
54 0 : Vector() : m_first(0), m_last(0), m_end(0) {}
55 0 : Vector(size_t n, const T& value = T()) : m_first(0), m_last(0), m_end(0) { insert(begin(), n, value); }
56 0 : Vector(const Vector<T> &rhs) : m_first(0), m_last(0), m_end(0) { insert(begin(), rhs.begin(), rhs.end()); }
57 : template <typename I>
58 : Vector(I first, const I last) : m_first(0), m_last(0), m_end(0) { insert(begin(), first, last); }
59 0 : ~Vector() { clear(); free(m_first); }
60 :
61 0 : iterator begin() { return m_first; }
62 0 : const_iterator begin() const { return m_first; }
63 :
64 0 : iterator end() { return m_last; }
65 0 : const_iterator end() const { return m_last; }
66 :
67 : bool empty() const { return m_first == m_last; }
68 0 : size_t size() const { return m_last - m_first; }
69 0 : size_t capacity() const{ return m_end - m_first; }
70 :
71 : void reserve(size_t n);
72 :
73 : reference front() { assert(size() > 0); return *begin(); }
74 : const_reference front() const { assert(size() > 0); return *begin(); }
75 : reference back() { assert(size() > 0); return *(end()-1); }
76 : const_reference back() const { assert(size() > 0); return *(end()-1); }
77 :
78 : Vector<T> & operator = (const Vector<T> & rhs) { assign(rhs.begin(), rhs.end()); return *this; }
79 0 : reference operator [] (size_t n) { assert(size() > n); return m_first[n]; }
80 0 : const_reference operator [] (size_t n) const { assert(size() > n); return m_first[n]; }
81 :
82 : void assign(size_t n, const T& u) { clear(); insert(begin(), n, u); }
83 : void assign(const_iterator first, const_iterator last) { clear(); insert(begin(), first, last); }
84 : iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); *p = x; return p; }
85 : void insert(iterator p, size_t n, const T & x);
86 : void insert(iterator p, const_iterator first, const_iterator last);
87 : void pop_back() { assert(size() > 0); --m_last; }
88 0 : void push_back(const T &v) { if (m_last == m_end) reserve(size()+1); new (m_last++) T(v); }
89 :
90 0 : void clear() { erase(begin(), end()); }
91 : iterator erase(iterator p) { return erase(p, p+1); }
92 : iterator erase(iterator first, iterator last);
93 :
94 : private:
95 : iterator _insert_default(iterator p, size_t n);
96 : };
97 :
98 : template <typename T>
99 : inline
100 0 : void Vector<T>::reserve(size_t n)
101 : {
102 0 : if (n > capacity())
103 : {
104 0 : const ptrdiff_t sz = size();
105 0 : m_first = static_cast<T*>(realloc(m_first, n*sizeof(T)));
106 0 : m_last = m_first + sz;
107 0 : m_end = m_first + n;
108 : }
109 0 : }
110 :
111 : template<typename T>
112 : inline
113 0 : typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)
114 : {
115 0 : assert(begin() <= p && p <= end());
116 0 : const ptrdiff_t i = p - begin();
117 0 : reserve((size() + n + 7) >> 3 << 3);
118 0 : p = begin() + i;
119 : // Move tail if there is one
120 0 : if (p != end()) memmove(p + n, p, distance(p,end())*sizeof(T));
121 0 : m_last += n;
122 0 : return p;
123 : }
124 :
125 : template<typename T>
126 : inline
127 0 : void Vector<T>::insert(iterator p, size_t n, const T & x)
128 : {
129 0 : p = _insert_default(p, n);
130 : // Copy in elements
131 0 : for (; n; --n, ++p) { new (p) T(x); }
132 0 : }
133 :
134 : template<typename T>
135 : inline
136 0 : void Vector<T>::insert(iterator p, const_iterator first, const_iterator last)
137 : {
138 0 : p = _insert_default(p, distance(first, last));
139 : // Copy in elements
140 0 : for (;first != last; ++first, ++p) { new (p) T(*first); }
141 0 : }
142 :
143 : template<typename T>
144 : inline
145 0 : typename Vector<T>::iterator Vector<T>::erase(iterator first, iterator last)
146 : {
147 0 : for (iterator e = first; e != last; ++e) e->~T();
148 0 : const size_t sz = distance(first, last);
149 0 : if (m_last != last) memmove(first, last, distance(last,end())*sizeof(T));
150 0 : m_last -= sz;
151 0 : return first;
152 : }
153 :
154 : } // namespace graphite2
|