source: trunk/poppler/mypoppler/goo/GooVector.h @ 461

Last change on this file since 461 was 461, checked in by Silvan Scherrer, 11 years ago

poppler update to 0.14.2

File size: 4.0 KB
Line 
1//========================================================================
2//
3// GooVector.h
4//
5// This file is licensed under the GPLv2 or later
6//
7// Copyright 2010 David Benjamin <davidben@mit.edu>
8// Copyright 2010 Albert Astals Cid <aacid@kde.org>
9//
10//========================================================================
11
12
13
14#ifndef GOO_GOOVECTOR_H
15#define GOO_GOOVECTOR_H
16
17#ifdef USE_GCC_PRAGMAS
18#pragma interface
19#endif
20
21#include <new> // vector implementations need placement-new
22
23#include <assert.h>
24#include <stdlib.h>
25
26/* Mostly STL-compatible vector class. Should correctly call constructors and
27 * destructors, but does not carefully handle alignment requirements. */
28
29template<class T> class GooVector {
30public:
31  /* various STL-compatible typedefs */
32  typedef T value_type;
33  typedef T* pointer;
34  typedef T& reference;
35  typedef const T& const_reference;
36  typedef size_t size_type;
37  typedef int difference_type;
38  typedef T* iterator;
39  typedef const T* const_iterator;
40  // TODO: reverse_iterator, if we feel like it
41 
42  GooVector() : m_data(NULL), m_capacity(0), m_size(0) {}
43  explicit GooVector(size_type n) : m_data(NULL), m_capacity(0), m_size(0) {
44    resize(n);
45  }
46  explicit GooVector(size_type n, const T& t) : m_data(NULL), m_capacity(0), m_size(0) {
47    resize(n, t);
48  }
49  explicit GooVector(const GooVector& gv) : m_data(NULL), m_capacity(0), m_size(0) {
50    reserve(gv.size());
51    for (size_type i = 0; i < m_size; i++) {
52      push_back(gv[i]);
53    }
54  }
55
56  ~GooVector() {
57    clear();
58  }
59
60  iterator begin() { return m_data; }
61  const_iterator begin() const { return m_data; }
62  iterator end() { return m_data + m_size; }
63  const_iterator end() const { return m_data + m_size; }
64
65  size_type size() const { return m_size; }
66  size_type capacity() const { return m_capacity; }
67
68  bool empty() const { return m_size == 0; }
69
70  reference operator[] (size_type n) { return m_data[n]; }
71  const_reference operator[] (size_type n) const { return m_data[n]; }
72
73  reference at(size_type n) {
74    assert(n < m_size);
75    return m_data[n];
76  }
77  const_reference at(size_type n) const {
78    assert(n < m_size);
79    return m_data[n];
80  }
81
82  reference front() { assert(!empty()); return m_data[0]; }
83  const_reference front() const { assert(!empty()); return m_data[0]; }
84
85  reference back() { assert(!empty()); return m_data[m_size-1]; }
86  const_reference back() const { assert(!empty()); return m_data[m_size-1]; }
87
88  void push_back(const T& v) {
89    reserve(m_size + 1);
90    place_new(m_data + m_size, v);
91    m_size++;
92  }
93  void pop_back() {
94    assert(!empty());
95    m_size--;
96    destruct(m_data + m_size);
97  }
98
99  void clear() {
100    for (size_t i = 0; i < m_size; i++) {
101      destruct(m_data + i);
102    }
103    m_size = 0;
104    free(m_data);
105    m_data = NULL;
106    m_capacity = 0;
107  }
108
109  void reserve(size_type cap) {
110    if (m_capacity >= cap) return;
111    // make sure we always at least double
112    if (m_capacity*2 > cap)
113      cap = m_capacity*2;
114    resize_internal(cap);
115  }
116
117  void resize(size_type n) { resize(n, T()); }
118  void resize(size_type n, const T& t) {
119    reserve(n);
120    while (m_size < n)
121      push_back(t);
122    while (m_size > n)
123      pop_back();
124  }
125
126private:
127  T *m_data;
128  size_type m_capacity;
129  size_type m_size;
130
131  inline void destruct(T *obj) {
132    obj->~T();
133  }
134  inline void place_new(T *loc, const T& v) {
135    new (loc) T(v);
136  }
137
138  inline void resize_internal(size_type new_cap) {
139    assert(new_cap >= m_capacity);
140    // To be correct with ctors and dtors, we do not use realloc and friends.
141    // A more efficient implementation would specialize for POD types and just
142    // realloc() or something. Meh, if we care, we ought to use just STL's
143    T *new_data = (T*) malloc(sizeof(T) * new_cap);
144    assert(new_data);
145    // Move over old data
146    if (m_data) {
147      for (size_type i = 0; i < m_size; i++) {
148        place_new(new_data + i, m_data[i]);
149        destruct(m_data + i);
150      }
151      free(m_data);
152    }
153    // And set the new values
154    m_data = new_data;
155    m_capacity = new_cap;
156  }
157};
158
159#endif
Note: See TracBrowser for help on using the repository browser.