Elm  2
ELM is a library providing generic data structures, OS-independent interface, plugins and XML.
List.h
1 /*
2  * List class interface
3  *
4  * This file is part of OTAWA
5  * Copyright (c) 2016, IRIT UPS.
6  *
7  * OTAWA is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * OTAWA is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with OTAWA; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #ifndef ELM_DATA_LIST_H
22 #define ELM_DATA_LIST_H
23 
24 #include <elm/assert.h>
25 #include <elm/PreIterator.h>
26 #include <elm/inhstruct/SLList.h>
27 #include "custom.h"
28 #include <elm/equiv.h>
29 
30 namespace elm {
31 
32 // SLList class
33 template <class T, class E = Equiv<T>, class A = DefaultAlloc>
34 class List: public E, public A {
35 
36  // Node class
37  class Node: public inhstruct::SLNode {
38  public:
39  inline Node(const T value): val(value) { }
40  T val;
41  inline Node *next(void) const { return nextNode(); }
42  inline Node *nextNode(void) const { return static_cast<Node *>(SLNode::next()); }
43  inline static void *operator new(size_t s, List<T, E, A> *l) { return l->A::allocate(s); }
44  inline void free(List<T, E, A> *l) { this->~Node(); l->A::free(this); }
45  private:
46  inline ~Node(void) { }
47  };
48 
49 public:
50 
51  inline List() { }
52  inline List(const List<T, E, A>& list) { copy(list); }
53  inline ~List(void) { clear(); }
54  inline E& equivalence() { return *this; }
55  inline const E& equivalence() const { return *this; }
56  inline A& allocator() { return *this; }
57 
58  void copy(const List<T, E, A>& list) {
59  clear(); Iter item(list); if(!item) return; addFirst(*item); Node *cur = firstNode();
60  for(item++; item(); item++) { cur->insertAfter(new(this) Node(*item)); cur = cur->next(); }
61  }
62 
63  // Iter class
64  class Iter: public PreIterator<Iter, const T&> {
65  friend class List;
66  public:
67  inline Iter(void): node(0) { }
68  inline Iter(const List& _list): node(_list.firstNode()) { }
69 
70  inline bool ended(void) const { return !node; }
71  inline const T& item(void) const { ASSERT(node); return node->val; }
72  inline void next(void) { ASSERT(node); node = node->next(); }
73  inline bool equals(const Iter& i) const { return node == i.node; }
74 
75  private:
76  friend class prec_iter;
77  Node *node;
78  };
79  inline Iter items(void) const { return Iter(*this); }
80  inline Iter operator*(void) const { return items(); }
81  inline operator Iter(void) const { return items(); }
82  inline Iter begin(void) const { return items(); }
83  inline Iter end(void) const { return Iter(); }
84 
85  // PrecIter class
86  class PrecIter: public PreIterator<PrecIter, const T&> {
87  friend class List;
88  public:
89  inline PrecIter(void): node(0), prev(0) { }
90  inline PrecIter(const List& _list): node(_list.firstNode()), prev(0) { }
91  inline operator Iter(void) const { Iter i; i.node = node; return i; }
92  inline bool operator==(const PrecIter& i) { return node == i.node; }
93  inline bool operator!=(const PrecIter& i) { return node != i.node; }
94 
95  inline bool ended(void) const { return !node; }
96  inline const T& item(void) const { ASSERT(node); return node->val; }
97  inline void next(void) { ASSERT(node); prev = node; node = node->next(); }
98 
99  private:
100  Node *node, *prev;
101  };
102 
103  // SubIter class
104  class SubIter: public PreIterator<SubIter, T> {
105  public:
106  inline SubIter(void) { }
107  inline SubIter(Iter begin, Iter end): c(begin), e(end) { }
108  inline bool ended(void) const { return c.equals(e); }
109  inline const T& item(void) const { return *c; }
110  inline void next(void) { c++; }
111  inline Iter asIter(void) const { return c; }
112  inline operator Iter(void) const { return c; }
113  private:
114  Iter c, e;
115  };
116 
117  // Collection concept
118  static List<T, E, A> null;
119  inline int count(void) const { return _list.count(); }
120  inline bool contains (const T &item) const
121  { for(Iter iter(*this); iter(); iter++) if(E::isEqual(item, *iter)) return true; return false; }
122  inline bool isEmpty(void) const { return _list.isEmpty(); };
123  inline operator bool(void) const { return !isEmpty(); }
124  bool equals(const List<T>& l) const
125  { Iter i1(*this), i2(l); while(i1() && i2()) { if(!E::isEqual(*i1, *i2)) return false; i1++; i2++; } return !i1 && !i2; }
126  inline const T& at(const Iter& i) const { return i.node->val; }
127 
128  // MutableCollection concept
129  inline void clear(void)
130  { while(!_list.isEmpty()) { Node *node = firstNode(); _list.removeFirst(); node->free(this); } }
131  inline void add(const T& value) { addFirst(value); }
132  template <class C> inline void addAll(const C& items)
133  { for(typename C::Iter i(items); i(); i++) add(*i); }
134  template <class C> inline void removeAll(const C& items)
135  { for(const auto i: items) remove(i); }
136  void remove(const T& value) {
137  if(isEmpty()) return; else if(E::isEqual(first(), value)) removeFirst(); else
138  for(Node *prev = firstNode(), *cur = prev->nextNode(); cur; prev = cur, cur = cur->nextNode())
139  if(E::isEqual(cur->val, value)) { prev->removeNext(); cur->free(this); return; }
140  }
141  inline T& at(const Iter& i) { return i.node->val; }
142  inline void remove(PrecIter &iter) { remove(iter.prev, iter.node); }
143 
144  // List concept
145  inline T& first(void) { return firstNode()->val; }
146  inline const T& first(void) const { return firstNode()->val; }
147  inline T& last(void) { return lastNode()->val; }
148  inline const T& last(void) const { return lastNode()->val; }
149  inline T& nth(int n) { Iter i(*this); while(n) { ASSERT(i); i++; n--; } ASSERT(i); return i.node->val; };
150  inline const T& nth(int n) const { Iter i(*this); while(n) { ASSERT(i); i++; n--; } ASSERT(i); return *i; };
151  Iter find(const T& item) const
152  { Iter i; for(i = items(); i(); i++) if(E::isEqual(item, *i)) break; return i; }
153  Iter find(const T& item, const Iter& pos) const
154  { Iter i = pos; for(i++; i(); i++) if(E::isEqual(item, *i)) break; return i; }
155 
156  // MutableList concept
157  inline void addFirst(const T& value) { _list.addFirst(new(this) Node(value)); }
158  inline void addLast(const T& value) { _list.addLast(new(this) Node(value)); }
159  inline void addAfter(const Iter& pos, const T& value)
160  { ASSERT(pos.node); pos.node->insertAfter(new(this) Node(value)); }
161  inline void addBefore(PrecIter& pos, const T& value)
162  { if(!pos.prev) { addFirst(value); pos.prev = firstNode(); }
163  else { pos.prev->insertAfter(new(this) Node(value)); pos.prev = pos.prev->next(); } }
164  inline void removeFirst(void) { Node *node = firstNode(); _list.removeFirst(); node->free(this); }
165  inline void removeLast(void) { Node *node = lastNode(); _list.removeLast(); node->free(this); }
166  inline void set(const Iter &pos, const T &item) { ASSERT(pos.node); pos.node->val = item; }
167 
168  // Stack concept
169  inline const T& top(void) const { return first(); }
170  inline T pop(void) { T r = first(); removeFirst(); return r; }
171  inline void push(const T& i) { addFirst(i); }
172  inline void reset(void) { clear(); }
173 
174  // operators
175  inline List& operator=(const List& list) { copy(list); return *this; }
176  inline bool operator&(const T& e) const { return contains(e); }
177  inline T& operator[](int k) { return nth(k); }
178  inline const T& operator[](int k) const { return nth(k); }
179  inline bool operator==(const List<T>& l) const { return equals(l); }
180  inline bool operator!=(const List<T>& l) const { return !equals(l); }
181  inline List<T>& operator+=(const T& h) { add(h); return *this; }
182  inline List<T>& operator+=(const List<T>& l) { addAll(l); return *this; }
183  inline List<T>& operator-=(const T& h) { remove(h); return *this; }
184  inline List<T>& operator-=(const List<T>& l) { removeAll(l); return *this; }
185 
186 private:
187  inhstruct::SLList _list;
188 
189  inline Node *firstNode(void) const { return static_cast<Node *>(_list.first()); }
190  inline Node *lastNode(void) const { return static_cast<Node *>(_list.last()); }
191  void remove(Node* prev, Node*& cur)
192  { ASSERT(cur); if(!prev) { removeFirst(); cur = firstNode(); }
193  else { prev->removeNext(); cur->free(this); cur = prev->next(); } }
194 };
195 
196 template <class T, class E, class A> List<T, E, A> List<T, E, A>::null;
197 
198 } // elm
199 
200 #endif // ELM_DATA_LIST_H
elm::List::Iter::next
void next(void)
Definition: List.h:72
elm::inhstruct::SLList::removeLast
void removeLast(void)
Definition: inhstruct_SLList.cpp:102
elm::List::add
void add(const T &value)
Definition: List.h:131
elm::List::clear
void clear(void)
Definition: List.h:129
elm::inhstruct::SLNode
Definition: SLList.h:17
elm::inhstruct::SLList::count
int count(void) const
Definition: inhstruct_SLList.cpp:74
elm::iter
Definition: util_WAHVector.cpp:157
elm::iter
void iter(const C &c, const F &f)
Definition: util.h:95
elm::List::addLast
void addLast(const T &value)
Definition: List.h:158
elm::List::PrecIter::item
const T & item(void) const
Definition: List.h:96
elm::List::contains
bool contains(const T &item) const
Definition: List.h:120
elm::List::addAfter
void addAfter(const Iter &pos, const T &value)
Definition: List.h:159
elm::List::equals
bool equals(const List< T > &l) const
Definition: List.h:124
elm::List::Iter::equals
bool equals(const Iter &i) const
Definition: List.h:73
elm::List::operator&
bool operator&(const T &e) const
Definition: List.h:176
elm::List::PrecIter::PrecIter
PrecIter(const List &_list)
Definition: List.h:90
elm::inhstruct::SLList::first
SLNode * first(void) const
Definition: SLList.h:60
elm::inhstruct::SLList::addLast
void addLast(SLNode *node)
Definition: inhstruct_SLList.cpp:90
elm::inhstruct::SLList
Definition: SLList.h:28
elm::List::nth
const T & nth(int n) const
Definition: List.h:150
elm::inhstruct::SLList::addFirst
void addFirst(SLNode *node)
Definition: SLList.h:63
elm::inhstruct::SLList::removeFirst
void removeFirst(void)
Definition: SLList.h:67
prec_iter
elm::List::SubIter::item
const T & item(void) const
Definition: List.h:109
elm::List::Iter
Definition: List.h:64
elm::List::operator!=
bool operator!=(const List< T > &l) const
Definition: List.h:180
elm::List::last
const T & last(void) const
Definition: List.h:148
elm::List::operator=
List & operator=(const List &list)
Definition: List.h:175
elm::List::begin
Iter begin(void) const
Definition: List.h:82
elm::List::end
Iter end(void) const
Definition: List.h:83
elm::List::last
T & last(void)
Definition: List.h:147
elm::List::top
const T & top(void) const
Definition: List.h:169
elm::List::removeAll
void removeAll(const C &items)
Definition: List.h:134
elm::List::Iter::Iter
Iter(const List &_list)
Definition: List.h:68
elm::List::List
List(const List< T, E, A > &list)
Definition: List.h:52
value
bool
elm::List::pop
T pop(void)
Definition: List.h:170
elm::List::Iter::Iter
Iter(void)
Definition: List.h:67
elm::List::operator[]
T & operator[](int k)
Definition: List.h:177
elm::List::equivalence
E & equivalence()
Definition: List.h:54
elm::List::operator+=
List< T > & operator+=(const List< T > &l)
Definition: List.h:182
elm::List::PrecIter::ended
bool ended(void) const
Definition: List.h:95
elm::List::SubIter::asIter
Iter asIter(void) const
Definition: List.h:111
elm::List::at
T & at(const Iter &i)
Definition: List.h:141
elm::DefaultAllocatorDelegate::free
void free(t::ptr p) const
Definition: custom.h:32
elm::List::copy
void copy(const List< T, E, A > &list)
Definition: List.h:58
elm::io::list
ListPrinter< T > list(const T &l, cstring s="", typename ListPrinter< T >::fun_t f=ListPrinter< T >::asis)
Definition: Output.h:321
elm::List::allocator
A & allocator()
Definition: List.h:56
elm
Definition: adapter.h:26
elm::List::equivalence
const E & equivalence() const
Definition: List.h:55
elm::List::addFirst
void addFirst(const T &value)
Definition: List.h:157
elm::List::PrecIter
Definition: List.h:86
elm::List::operator==
bool operator==(const List< T > &l) const
Definition: List.h:179
elm::List::nth
T & nth(int n)
Definition: List.h:149
elm::List::operator-=
List< T > & operator-=(const List< T > &l)
Definition: List.h:184
elm::List::count
int count(void) const
Definition: List.h:119
elm::List::find
Iter find(const T &item, const Iter &pos) const
Definition: List.h:153
elm::List::SubIter::SubIter
SubIter(Iter begin, Iter end)
Definition: List.h:107
elm::List::items
Iter items(void) const
Definition: List.h:79
elm::List::removeFirst
void removeFirst(void)
Definition: List.h:164
elm::List::operator+=
List< T > & operator+=(const T &h)
Definition: List.h:181
elm::List::PrecIter::operator!=
bool operator!=(const PrecIter &i)
Definition: List.h:93
elm::inhstruct::SLList::last
SLNode * last(void) const
Definition: inhstruct_SLList.cpp:59
elm::List::isEmpty
bool isEmpty(void) const
Definition: List.h:122
elm::List::set
void set(const Iter &pos, const T &item)
Definition: List.h:166
elm::List::remove
void remove(PrecIter &iter)
Definition: List.h:142
elm::List::removeLast
void removeLast(void)
Definition: List.h:165
elm::List::PrecIter::PrecIter
PrecIter(void)
Definition: List.h:89
elm::inhstruct::SLList::isEmpty
bool isEmpty(void) const
Definition: SLList.h:70
elm::List::push
void push(const T &i)
Definition: List.h:171
elm::List::find
Iter find(const T &item) const
Definition: List.h:151
elm::List::remove
void remove(const T &value)
Definition: List.h:136
elm::List::addBefore
void addBefore(PrecIter &pos, const T &value)
Definition: List.h:161
elm::List::at
const T & at(const Iter &i) const
Definition: List.h:126
elm::List::first
T & first(void)
Definition: List.h:145
elm::List::operator[]
const T & operator[](int k) const
Definition: List.h:178
elm::List::SubIter::ended
bool ended(void) const
Definition: List.h:108
elm::List::operator-=
List< T > & operator-=(const T &h)
Definition: List.h:183
elm::List::Iter::item
const T & item(void) const
Definition: List.h:71
elm::List::null
static List< T, E, A > null
Definition: List.h:118
elm::List::reset
void reset(void)
Definition: List.h:172
elm::List::addAll
void addAll(const C &items)
Definition: List.h:132
elm::List::PrecIter::next
void next(void)
Definition: List.h:97
elm::List::first
const T & first(void) const
Definition: List.h:146
elm::List::PrecIter::operator==
bool operator==(const PrecIter &i)
Definition: List.h:92
elm::List::~List
~List(void)
Definition: List.h:53
elm::List::SubIter::SubIter
SubIter(void)
Definition: List.h:106
elm::List::operator*
Iter operator*(void) const
Definition: List.h:80
elm::PreIterator
Definition: iter.h:28
elm::List::List
List()
Definition: List.h:51
elm::List
Definition: List.h:34
elm::List::SubIter
Definition: List.h:104
elm::List::Iter::ended
bool ended(void) const
Definition: List.h:70
elm::List::SubIter::next
void next(void)
Definition: List.h:110