gfx/graphite2/src/inc/List.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial