CACAO
ordered_list.hpp
Go to the documentation of this file.
1 /* src/toolbox/ordered_list.hpp - ordered list
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #ifndef ORDEREDLIST_HPP_
27 #define ORDEREDLIST_HPP_ 1
28 
29 #include <list>
30 #include <algorithm>
31 
32 namespace cacao {
33 
34 // forward declaration
35 template<class T, class Allocator, class intern_list>
37 template<class T, class Allocator, class intern_list>
39 
40 /**
41  * An ordered_list is an indexed sequence container. It shares most
42  * characteristics with a std::list with the difference that its iterators are
43  * more powerful. In addition the features of bidirectional iterators the total
44  * ordering relation is supported (hence the name ordered_list).
45  *
46  * Like std::list it supports constant time insertion and removal of elements
47  * anywhere. Additionally those operations do not invalidate iterators.
48  *
49  * ordered_list meets the requirement of Container, AllocatorAwareContainer,
50  * SequenceContainer, ReversibleContainer.
51  *
52  * @todo not all methods are implemented yet!
53  */
54 template <class T,class Allocator = std::allocator<T> >
55 class ordered_list {
56 private:
57  struct Entry;
58  typedef std::list<Entry,typename Allocator::template rebind<Entry>::other> intern_list;
59  typedef typename intern_list::iterator intern_iterator;
60 
61  /// tagged list entry
62  struct Entry {
63  Entry(T value, std::size_t index) : value(value), index(index) {}
64  T value;
65  std::size_t index;
66  bool operator==(const Entry& other) const {
67  return index == other.index && value == other.value;
68  }
69  };
70  /// Inserter
71  struct Inserter {
74  std::size_t index;
76  : list(list), pos(pos), index(pos->index) {}
77  void operator()(T& value) {
78  list.insert(pos, Entry(value,index++));
79  }
80  };
81  /// Increment function struct
82  struct IncrementEntry {
83  void operator()(Entry& E) {
84  ++E.index;
85  }
86  };
87  /// Increasing function struct
88  struct IncreasingEntry {
89  std::size_t index;
90  IncreasingEntry(std::size_t index) : index(index) {}
91  void operator()(Entry& E) {
92  E.index = index++;
93  }
94  };
95  /// Decrement function struct
96  struct DecrementEntry {
97  void operator()(Entry& E) {
98  --E.index;
99  }
100  };
101  /// internal storage
103 
104 public:
105  typedef T value_type;
106  typedef Allocator allocator_type;
107  typedef typename allocator_type::reference reference;
108  typedef typename allocator_type::const_reference const_reference;
109  typedef typename allocator_type::pointer pointer;
110  typedef typename allocator_type::const_pointer const_pointer;
113  typedef std::reverse_iterator<iterator> reverse_iterator;
114  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
115 
116  /// construct an empty MachineBasicBlock
118  /// copy constructor
120  /// copy assignment operator
122  /// checks if the container has no elements.
123  bool empty() const;
124 
125  /// returns the number of elements
126  std::size_t size() const;
127  /// returns the maximum possible number of elements
128  std::size_t max_size() const;
129  /// Appends the given element value to the end of the container.
130  void push_back(const T& value);
131  /// inserts value to the beginning
132  void push_front(const T& value);
133  /// inserts value before the element pointed to by pos
134  iterator insert(iterator pos, const T& value);
135  /// inserts elements from range [first, last) before the element pointed to by pos
136  template<class InputIt>
137  void insert(iterator pos, InputIt first, InputIt last);
138  /// erases element
140  /// erases elements
141  iterator erase(iterator first, iterator last);
142  /// returns an iterator to the beginning
143  iterator begin();
144  /// returns an iterator to the end
145  iterator end();
146  /// returns a const_iterator to the beginning
147  const_iterator begin() const;
148  /// returns a const_iterator to the end
149  const_iterator end() const;
150  /// returns a reverse iterator to the beginning
152  /// returns a reverse iterator to the end
154  /// returns a const reverse iterator to the beginning
156  /// returns a const reverse iterator to the end
158  /// access the first element
159  const_reference front() const;
160  /// access the last element
161  const_reference back() const;
162  /// access the first element
163  reference front();
164  /// access the last element
165  reference back();
166  /// removes all elements from the container
167  void clear();
168  /// exchanges the contents of the container with those of other
169  void swap(ordered_list<T,Allocator> &other);
170 
171  // friends
172  template<class _T,class _Allocator>
173  friend bool operator==(const ordered_list<_T,_Allocator>& lhs,
174  const ordered_list<_T,_Allocator>& rhs);
175  template<class _T,class _Allocator>
176  friend bool operator==(const typename ordered_list<_T,_Allocator>::Entry& lhs,
177  const typename ordered_list<_T,_Allocator>::Entry& rhs);
178 
179 };
180 
181 /// equality
182 template< class T, class Allocator>
183 inline bool operator==(const ordered_list<T,Allocator>& lhs,
184  const ordered_list<T,Allocator>& rhs) {
185  return lhs.list == rhs.list;
186 }
187 
188 /// inequality
189 template< class T, class Allocator>
190 inline bool operator!=(const ordered_list<T,Allocator>& lhs,
191  const ordered_list<T,Allocator>& rhs) {
192  return !(lhs == rhs);
193 }
194 
195 
196 /**
197  * ordered iterator
198  */
199 template<class T, class Allocator, class intern_list>
200 class _ordered_iterator : public std::iterator<std::bidirectional_iterator_tag,T> {
201 public:
202  typedef typename std::iterator<std::bidirectional_iterator_tag,T>
204  typedef typename std::iterator<std::bidirectional_iterator_tag,T>
207  _ordered_iterator(typename intern_list::iterator it) : it(it) {}
208  _ordered_iterator(const _ordered_iterator& other) : it(other.it) {}
210  ++it;
211  return *this;
212  }
214  _ordered_iterator tmp(*this);
215  operator++();
216  return tmp;
217  }
219  --it;
220  return *this;
221  }
223  _ordered_iterator tmp(*this);
224  operator--();
225  return tmp;
226  }
227  bool operator==(const _ordered_iterator& rhs) const { return it == rhs.it; }
228  bool operator!=(const _ordered_iterator& rhs) const { return it != rhs.it; }
229  bool operator<( const _ordered_iterator& rhs) const { return it->index < rhs.it->index; }
230  bool operator>( const _ordered_iterator& rhs) const { return rhs < *this; }
231  reference operator*() { return it->value; }
232  const reference operator*() const { return it->value; }
233  pointer operator->() { return it->value; }
234  const pointer operator->() const { return it->value; }
235 private:
236  typename intern_list::iterator it;
237  friend class ordered_list<T,Allocator>;
238  friend class _ordered_const_iterator<T,Allocator,intern_list>;
239 };
240 
241 /**
242  * ordered const_iterator
243  */
244 template<class T, class Allocator, class intern_list>
245 class _ordered_const_iterator : public std::iterator<std::bidirectional_iterator_tag,const T> {
246 public:
247  typedef typename std::iterator<std::bidirectional_iterator_tag,const T>
249  typedef typename std::iterator<std::bidirectional_iterator_tag,const T>
252  _ordered_const_iterator(typename intern_list::const_iterator it) : it(it) {}
254  // convert from non const version
256  intern_list>& other) : it(other.it) {}
258  ++it;
259  return *this;
260  }
263  operator++();
264  return tmp;
265  }
267  --it;
268  return *this;
269  }
272  operator--();
273  return tmp;
274  }
275  bool operator==(const _ordered_const_iterator& rhs) const { return it == rhs.it; }
276  bool operator!=(const _ordered_const_iterator& rhs) const { return it != rhs.it; }
277  bool operator<( const _ordered_const_iterator& rhs) const { return it->index < rhs.it->index; }
278  bool operator>( const _ordered_const_iterator& rhs) const { return rhs < *this; }
279  reference operator*() { return it->value; }
280  const reference operator*() const { return it->value; }
281  pointer operator->() { return it->value; }
282  const pointer operator->() const { return it->value; }
283 private:
284  typename intern_list::const_iterator it;
285  friend class ordered_list<T,Allocator>;
286 };
287 
288 // implementation
289 template <class T, class Allocator>
292  list = other.list;
293  return *this;
294 }
295 
296 template <class T, class Allocator>
298  return list.empty();
299 }
300 
301 template <class T, class Allocator>
302 inline std::size_t ordered_list<T, Allocator>::size() const {
303  return list.size();
304 }
305 
306 template <class T, class Allocator>
307 inline std::size_t ordered_list<T, Allocator>::max_size() const {
308  return list.max_size();
309 }
310 
311 template <class T, class Allocator>
312 inline void ordered_list<T, Allocator>::push_back(const T& value) {
313  list.push_back(Entry(value,size()));
314 }
315 
316 template <class T, class Allocator>
317 inline void ordered_list<T, Allocator>::push_front(const T& value) {
318  std::for_each(list.begin(),list.end(),IncrementEntry());
319  list.push_front(Entry(value,0));
320 }
321 
322 template <class T, class Allocator>
325  const T& value) {
326  typename intern_list::iterator it = list.insert(pos.it,Entry(value,pos.it->index));
327  std::for_each(pos.it,list.end(),IncrementEntry());
328  return iterator(it);
329 }
330 
331 template <class T, class Allocator>
332 template <class InputIt>
335  InputIt first, InputIt last) {
336  typename intern_list::iterator it = pos.it;
337  std::for_each(first,last,Inserter(list,pos.it));
338  std::for_each(it,list.end(),IncreasingEntry((--it)->index+1));
339 }
340 
341 template <class T, class Allocator>
345  typename intern_list::iterator it = list.erase(pos.it);
346  std::for_each(it,list.end(),DecrementEntry());
347  return it;
348 }
349 
350 template <class T, class Allocator>
351 inline typename ordered_list<T, Allocator>::iterator
353  typename ordered_list<T, Allocator>::iterator first,
354  typename ordered_list<T, Allocator>::iterator last) {
355  std::size_t index = first.it->index;
356  typename intern_list::iterator it = list.erase(first.it,last.it);
357  std::for_each(it,list.end(),IncreasingEntry(index));
358  return it;
359 }
360 
361 template <class T, class Allocator>
363  return list.begin();
364 }
365 
366 template <class T, class Allocator>
369  return list.begin();
370 }
371 
372 template <class T, class Allocator>
374  return list.end();
375 }
376 
377 template <class T, class Allocator>
380  return list.end();
381 }
382 
383 template <class T, class Allocator>
386  return list.rbegin();
387 }
388 
389 template <class T, class Allocator>
392  return list.rend();
393 }
394 
395 template <class T, class Allocator>
398  return list.rbegin();
399 }
400 
401 template <class T, class Allocator>
404  return list.rend();
405 }
406 
407 template <class T, class Allocator>
410  return list.front().value;
411 }
412 template <class T, class Allocator>
415  return list.back().value;
416 }
417 template <class T, class Allocator>
420  return list.front().value;
421 }
422 template <class T, class Allocator>
425  return list.back().value;
426 }
427 template <class T, class Allocator>
429  return list.clear();
430 }
431 
432 template <class T, class Allocator>
434  list.swap(other.list);
435 }
436 
437 } // end namespace cacao
438 
439 #endif // ORDEREDLIST_HPP
440 
441 
442 /*
443  * These are local overrides for various environment variables in Emacs.
444  * Please do not remove this and leave it at the end of the file, where
445  * Emacs will automagically detect them.
446  * ---------------------------------------------------------------------
447  * Local variables:
448  * mode: c++
449  * indent-tabs-mode: t
450  * c-basic-offset: 4
451  * tab-width: 4
452  * End:
453  * vim:noexpandtab:sw=4:ts=4:
454  */
bool operator==(const Entry &other) const
std::reverse_iterator< const_iterator > const_reverse_iterator
std::size_t index
const reference operator*() const
allocator_type::const_reference const_reference
bool empty() const
checks if the container has no elements.
ordered const_iterator
_ordered_const_iterator & operator--()
_ordered_iterator(const _ordered_iterator &other)
friend bool operator==(const ordered_list< _T, _Allocator > &lhs, const ordered_list< _T, _Allocator > &rhs)
const pointer operator->() const
_ordered_const_iterator(const _ordered_iterator< T, Allocator, intern_list > &other)
std::size_t max_size() const
returns the maximum possible number of elements
void clear()
removes all elements from the container
#define E(why, which)
Definition: escape.cpp:52
bool operator!=(const _ordered_const_iterator &rhs) const
const_reference back() const
access the last element
std::iterator< std::bidirectional_iterator_tag, const T >::reference reference
intern_list::iterator it
allocator_type::const_pointer const_pointer
ordered iterator
iterator insert(iterator pos, const T &value)
inserts value before the element pointed to by pos
intern_list::iterator intern_iterator
const pointer operator->() const
Increment function struct.
allocator_type::reference reference
_ordered_const_iterator operator++(int)
iterator begin()
returns an iterator to the beginning
_ordered_const_iterator & operator++()
std::iterator< std::bidirectional_iterator_tag, T >::pointer pointer
intern_list list
internal storage
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
iterator erase(iterator pos)
erases element
_ordered_const_iterator(const _ordered_const_iterator &other)
iterator end()
returns an iterator to the end
_ordered_iterator operator++(int)
intern_list::const_iterator it
_ordered_iterator< T, Allocator, intern_list > iterator
std::iterator< std::bidirectional_iterator_tag, const T >::pointer pointer
Instruction::InstID tmp[]
Definition: Matcher.cpp:55
std::size_t size() const
returns the number of elements
bool operator!=(const ordered_list< T, Allocator > &lhs, const ordered_list< T, Allocator > &rhs)
inequality
_ordered_iterator & operator++()
_ordered_const_iterator< T, Allocator, intern_list > const_iterator
bool operator==(const _ordered_const_iterator &rhs) const
const_reference front() const
access the first element
void push_back(const T &value)
Appends the given element value to the end of the container.
reverse_iterator rbegin()
returns a reverse iterator to the beginning
Decrement function struct.
MIIterator pos
ordered_list & operator=(const ordered_list< T, Allocator > &other)
copy assignment operator
tagged list entry
allocator_type::pointer pointer
const reference operator*() const
bool operator==(const ordered_list< T, Allocator > &lhs, const ordered_list< T, Allocator > &rhs)
equality
_ordered_const_iterator(typename intern_list::const_iterator it)
bool operator==(const _ordered_iterator &rhs) const
ordered_list(const ordered_list< T, Allocator > &other)
copy constructor
ordered_list()
construct an empty MachineBasicBlock
std::reverse_iterator< iterator > reverse_iterator
_ordered_const_iterator operator--(int)
void push_front(const T &value)
inserts value to the beginning
bool operator!=(const _ordered_iterator &rhs) const
Entry(T value, std::size_t index)
std::list< Entry, typename Allocator::template rebind< Entry >::other > intern_list
reverse_iterator rend()
returns a reverse iterator to the end
bool operator>(const _ordered_const_iterator &rhs) const
bool operator>(const _ordered_iterator &rhs) const
void swap(ordered_list< T, Allocator > &other)
exchanges the contents of the container with those of other
_ordered_iterator(typename intern_list::iterator it)
Increasing function struct.
bool operator<(const _ordered_const_iterator &rhs) const
std::iterator< std::bidirectional_iterator_tag, T >::reference reference
Inserter(intern_list &list, intern_iterator pos)
bool operator<(const _ordered_iterator &rhs) const
_ordered_iterator operator--(int)
_ordered_iterator & operator--()
An ordered_list is an indexed sequence container.