Path: blob/master/thirdparty/graphite/src/inc/List.h
10279 views
// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later1// Copyright 2010, SIL International, All rights reserved.234// designed to have a limited subset of the std::vector api5#pragma once67#include <cstddef>8#include <cassert>9#include <cstring>10#include <cstdlib>11#include <new>1213#include "Main.h"1415namespace graphite2 {1617template <typename T>18inline19ptrdiff_t distance(T* first, T* last) { return last-first; }202122template <typename T>23class Vector24{25T * m_first, *m_last, *m_end;26public:27typedef T & reference;28typedef const T & const_reference;29typedef T * iterator;30typedef const T * const_iterator;3132Vector() : m_first(0), m_last(0), m_end(0) {}33Vector(size_t n, const T& value = T()) : m_first(0), m_last(0), m_end(0) { insert(begin(), n, value); }34Vector(const Vector<T> &rhs) : m_first(0), m_last(0), m_end(0) { insert(begin(), rhs.begin(), rhs.end()); }35template <typename I>36Vector(I first, const I last) : m_first(0), m_last(0), m_end(0) { insert(begin(), first, last); }37~Vector() { clear(); free(m_first); }3839iterator begin() { return m_first; }40const_iterator begin() const { return m_first; }4142iterator end() { return m_last; }43const_iterator end() const { return m_last; }4445bool empty() const { return m_first == m_last; }46size_t size() const { return m_last - m_first; }47size_t capacity() const{ return m_end - m_first; }4849void reserve(size_t n);50void resize(size_t n, const T & v = T());5152reference front() { assert(size() > 0); return *begin(); }53const_reference front() const { assert(size() > 0); return *begin(); }54reference back() { assert(size() > 0); return *(end()-1); }55const_reference back() const { assert(size() > 0); return *(end()-1); }5657Vector<T> & operator = (const Vector<T> & rhs) { assign(rhs.begin(), rhs.end()); return *this; }58reference operator [] (size_t n) { assert(size() > n); return m_first[n]; }59const_reference operator [] (size_t n) const { assert(size() > n); return m_first[n]; }6061void assign(size_t n, const T& u) { clear(); insert(begin(), n, u); }62void assign(const_iterator first, const_iterator last) { clear(); insert(begin(), first, last); }63iterator insert(iterator p, const T & x) { p = _insert_default(p, 1); new (p) T(x); return p; }64void insert(iterator p, size_t n, const T & x);65void insert(iterator p, const_iterator first, const_iterator last);66void pop_back() { assert(size() > 0); --m_last; }67void push_back(const T &v) { if (m_last == m_end) reserve(size()+1); new (m_last++) T(v); }6869void clear() { erase(begin(), end()); }70iterator erase(iterator p) { return erase(p, p+1); }71iterator erase(iterator first, iterator last);7273private:74iterator _insert_default(iterator p, size_t n);75};7677template <typename T>78inline79void Vector<T>::reserve(size_t n)80{81if (n > capacity())82{83const ptrdiff_t sz = size();84size_t requested;85if (checked_mul(n,sizeof(T), requested)) std::abort();86m_first = static_cast<T*>(realloc(m_first, requested));87if (!m_first) std::abort();88m_last = m_first + sz;89m_end = m_first + n;90}91}9293template <typename T>94inline95void Vector<T>::resize(size_t n, const T & v) {96const ptrdiff_t d = n-size();97if (d < 0) erase(end()+d, end());98else if (d > 0) insert(end(), d, v);99}100101template<typename T>102inline103typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)104{105assert(begin() <= p && p <= end());106const ptrdiff_t i = p - begin();107reserve(((size() + n + 7) >> 3) << 3);108p = begin() + i;109// Move tail if there is one110if (p != end()) memmove(p + n, p, distance(p,end())*sizeof(T));111m_last += n;112return p;113}114115template<typename T>116inline117void Vector<T>::insert(iterator p, size_t n, const T & x)118{119p = _insert_default(p, n);120// Copy in elements121for (; n; --n, ++p) { new (p) T(x); }122}123124template<typename T>125inline126void Vector<T>::insert(iterator p, const_iterator first, const_iterator last)127{128p = _insert_default(p, distance(first, last));129// Copy in elements130for (;first != last; ++first, ++p) { new (p) T(*first); }131}132133template<typename T>134inline135typename Vector<T>::iterator Vector<T>::erase(iterator first, iterator last)136{137for (iterator e = first; e != last; ++e) e->~T();138const size_t sz = distance(first, last);139if (m_last != last) memmove(first, last, distance(last,end())*sizeof(T));140m_last -= sz;141return first;142}143144} // namespace graphite2145146147