All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
fixedCapacityVector.h
Go to the documentation of this file.
1 /* fixedCapacityVector.h
2  */
3 #ifndef OSL_FIXED_CAPACITY_VECTOR_H
4 #define OSL_FIXED_CAPACITY_VECTOR_H
5 
6 #include "osl/misc/carray.h"
7 #include "osl/misc/cstdint.h"
8 #include "osl/misc/construct.h"
9 #include <algorithm>
10 #include <cstddef>
11 #include <cassert>
12 
13 #if (__GNUC__ >= 4 && __GNUC_MINOR__ >=4)
14 # pragma GCC diagnostic ignored "-Wstrict-aliasing"
15 #endif
16 
17 namespace osl
18 {
19  namespace misc
20  {
21  template <typename T>
23  {
24  T *ptr;
25  T **vPtr;
26 #if ! (defined NDEBUG && defined MINIMAL)
27  T *limit;
28 #endif
29  public:
30  FixedCapacityVectorPushBack(T** vPtr_, T* limit_)
31  : ptr(*vPtr_), vPtr(vPtr_)
32 #if ! (defined NDEBUG && defined MINIMAL)
33  ,limit(limit_)
34 #endif
35  {
36  }
38  {
39  assert( *vPtr == ptr );
40  *vPtr = ptr;
41  }
42  void push_back(const T& e)
43  {
44  assert(ptr < limit);
45  assert( *vPtr == ptr );
47  *ptr++ = e;
48  else
49  construct(ptr++,e);
50 #ifndef NDEBUG
51  (*vPtr)++;
52 #endif
53  }
54  };
55  template <typename T, size_t Capacity>
57  {
58  protected:
59  struct Array : public CArray<T, Capacity> {}
60 #ifdef __GNUC__
61  __attribute__((__may_alias__))
62 #endif
63  ;
64  typedef Array array_t;
65  T* ptr;
66  CArray<int64_t, (sizeof(T[Capacity])+sizeof(int64_t)-1)/sizeof(int64_t)> relements;
67  private:
68  const array_t &elements() const{
69  return *reinterpret_cast<const array_t*>(&relements);
70  }
72  return *reinterpret_cast<array_t*>(&relements);
73  }
74  public:
75  typedef typename array_t::value_type value_type;
76  typedef typename array_t::iterator iterator;
78 
80  explicit FixedCapacityVector(size_t size) : ptr(&(elements()[0]))
81  {
82  resize(size);
83  }
85  ptr= &*begin()+rhs.size();
86  std::uninitialized_copy(rhs.begin(),rhs.end(),begin());
87  }
88  template <class RangeIterator>
89  FixedCapacityVector(const RangeIterator& first, const RangeIterator& last)
90  : ptr(&(elements()[0]))
91  {
92  push_back(first, last);
93  }
95  {
96  destroy(begin(),end());
97  }
99  if (this == &rhs)
100  return *this;
101 
102  if(size()>rhs.size()){
103  iterator it=std::copy(rhs.begin(),rhs.end(),begin());
104  destroy(it,end());
105  }
106  else{
107  iterator it=std::copy(&(rhs.elements()[0]),
108  &(rhs.elements()[0])+size(),begin());
109  std::uninitialized_copy(&(rhs.elements()[0])+size(),
110  &(rhs.elements()[0])+rhs.size(),it);
111  }
112  ptr= &*begin()+rhs.size();
113  return *this;
114  }
115 
116  T& operator[] (size_t i)
117  {
118  assert(i <= size());
119  return elements()[i];
120  }
121 
122  iterator begin() { return &elements()[0]; }
123  iterator end() { return static_cast<iterator>(ptr); }
124 
125  T& front() { return *begin(); }
126  T& back() { return *(end() - 1); }
127 
128  void push_back(const T& e)
129  {
130  assert(size() < Capacity);
131  construct(ptr,e);
132  ++ptr;
133  }
134  template <class RangeIterator>
135  void push_back(const RangeIterator& first, const RangeIterator& last);
136  void pop_back() {
137  --ptr;
138  destroy(ptr+1);
139  }
140  void clear() {
141  size_t s=size();
142  ptr= &(elements()[0]);
143  // 該当する部分のdestructorを呼ぶ
144  destroy(begin(),begin()+(int)s);
145  }
146  void resize(size_t new_length)
147  {
148  while (size() < new_length)
149  push_back(T());
150  if (new_length < size()) {
151  destroy(begin()+(int)new_length,end());
152  ptr= &(elements()[new_length]);
153  }
154  }
155 
156  void erase(const T& e)
157  {
158  const iterator new_end = std::remove(begin(), end(), e);
159  ptr= &*new_end;
160  destroy(new_end,end());
161  }
162 
164  void unique()
165  {
166  std::sort(begin(),end());
167  iterator last = std::unique(begin(), end());
168  ptr = &*last;
169  destroy(last,end());
170  }
171 
172  size_t size() const { return ptr-&*begin(); }
173  bool empty() const { return ptr==&*begin(); }
174  size_t capacity() const { return Capacity; }
175 
176  T const& operator[] (size_t i) const
177  {
178  assert(i < size());
179  return elements()[i];
180  }
181  const_iterator begin() const { return &elements()[0]; }
182  const_iterator end() const { return ptr; }
183 
184  const T& front() const { return *begin(); }
185  const T& back() const { return *(end() - 1); }
186 
187  bool isMember(const T& e, const_iterator first, const_iterator last) const
188  {
189  return std::find(first, last, e) != last;
190  }
191  bool isMember(const T& e) const
192  {
193  return isMember(e, begin(), end());
194  }
196  {
198  (&ptr, &*begin()+Capacity);
199  }
200  };
201  template <typename T, size_t C> inline
203  {
204  return l.size() == r.size() && std::equal(l.begin(), l.end(), r.begin());
205  }
206  template <typename T, size_t C> inline
207  bool operator<(const FixedCapacityVector<T,C>& l, const FixedCapacityVector<T,C>& r)
208  {
209  return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
210  }
211  } // namespace misc
212  using misc::FixedCapacityVector;
213  using misc::FixedCapacityVectorPushBack;
214 } // namespace osl
215 
216 template <typename T, size_t Capacity>
217 template <class RangeIterator>
218 void osl::misc::FixedCapacityVector<T,Capacity>::push_back(const RangeIterator& first, const RangeIterator& last)
219 {
220  iterator insert_point = end();
221  std::uninitialized_copy(first, last, insert_point);
222  ptr += last-first;
223  assert(size() <= Capacity);
224 }
225 
226 
227 #endif /* OSL_FIXED_CAPACITY_VECTOR_H */
228 // ;;; Local Variables:
229 // ;;; mode:c++
230 // ;;; c-basic-offset:2
231 // ;;; End: