1 /********************* */
4 ** Original author: mdeters
5 ** Major contributors: none
6 ** Minor contributors (to current version): barrett, taking
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
14 ** \brief Context-dependent list class.
16 ** Context-dependent list class.
19 #include "cvc4_private.h"
21 #ifndef __CVC4__CONTEXT__CDLIST_H
22 #define __CVC4__CONTEXT__CDLIST_H
24 #include "context/context.h"
25 #include "util/Assert.h"
31 * Generic context-dependent dynamic array. Note that for efficiency, this
32 * implementation makes the following assumptions:
33 * 1. Over time, objects are only added to the list. Objects are only
34 * removed when a pop restores the list to a previous state.
35 * 2. T objects can safely be copied using their copy constructor,
36 * operator=, and memcpy.
39 class CDList
: public ContextObj
{
41 * d_list is a dynamic array of objects of type T.
46 * Whether to call the destructor when items are popped from the
47 * list. True by default, but can be set to false by setting the
48 * second argument in the constructor to false.
50 bool d_callDestructor
;
53 * Number of objects in d_list
58 * Allocated size of d_list.
65 * Implementation of mandatory ContextObj method save: simply copies the
66 * current size to a copy using the copy constructor (the pointer and the
67 * allocated size are *not* copied as they are not restored on a pop).
68 * The saved information is allocated using the ContextMemoryManager.
70 ContextObj
* save(ContextMemoryManager
* pCMM
) {
71 return new(pCMM
) CDList
<T
>(*this);
75 * Implementation of mandatory ContextObj method restore: simply restores the
76 * previous size. Note that the list pointer and the allocated size are not
79 void restore(ContextObj
* data
) {
80 if(d_callDestructor
) {
81 unsigned size
= ((CDList
<T
>*)data
)->d_size
;
82 while(d_size
!= size
) {
87 d_size
= ((CDList
<T
>*)data
)->d_size
;
94 * Private copy constructor used only by save above. d_list and d_sizeAlloc
95 * are not copied: only the base class information and d_size are needed in
98 CDList(const CDList
<T
>& l
) :
101 d_callDestructor(l
.d_callDestructor
),
107 * Reallocate the array with more space.
108 * Throws bad_alloc if memory allocation fails.
112 // Allocate an initial list if one does not yet exist
114 d_list
= (T
*) malloc(sizeof(T
) * d_sizeAlloc
);
116 throw std::bad_alloc();
119 // Allocate a new array with double the size
121 T
* tmpList
= (T
*) realloc(d_list
, sizeof(T
) * d_sizeAlloc
);
122 if(tmpList
== NULL
) {
123 throw std::bad_alloc();
131 * Main constructor: d_list starts as NULL, size is 0
133 CDList(Context
* context
, bool callDestructor
= true) :
136 d_callDestructor(callDestructor
),
142 * Destructor: delete the list
144 ~CDList() throw(AssertionException
) {
147 if(d_callDestructor
) {
148 for(unsigned i
= 0; i
< d_size
; ++i
) {
157 * Return the current size of (i.e. valid number of objects in) the list
159 unsigned size() const {
164 * Return true iff there are no valid objects in the list.
171 * Add an item to the end of the list.
173 void push_back(const T
& data
) {
176 if(d_size
== d_sizeAlloc
) {
180 ::new((void*)(d_list
+ d_size
)) T(data
);
185 * Access to the ith item in the list.
187 const T
& operator[](unsigned i
) const {
188 Assert(i
< d_size
, "index out of bounds in CDList::operator[]");
193 * Returns the most recent item added to the list.
195 const T
& back() const {
196 Assert(d_size
> 0, "CDList::back() called on empty list");
197 return d_list
[d_size
- 1];
201 * Iterator for CDList class. It has to be const because we don't allow
202 * items in the list to be changed. It's a straightforward wrapper around a
203 * pointer. Note that for efficiency, we implement only prefix increment and
204 * decrement. Also note that it's OK to create an iterator from an empty,
205 * uninitialized list, as begin() and end() will have the same value (NULL).
207 class const_iterator
{
210 const_iterator(T
* it
) : d_it(it
) {}
212 friend class CDList
<T
>;
216 const_iterator() : d_it(NULL
) {}
218 inline bool operator==(const const_iterator
& i
) const {
219 return d_it
== i
.d_it
;
222 inline bool operator!=(const const_iterator
& i
) const {
223 return d_it
!= i
.d_it
;
226 inline const T
& operator*() const {
230 /** Prefix increment */
231 const_iterator
& operator++() {
236 /** Prefix decrement */
237 const_iterator
& operator--() { --d_it
; return *this; }
239 // Postfix operations on iterators: requires a Proxy object to
240 // hold the intermediate value for dereferencing
246 Proxy(const T
& p
): d_t(&p
) {}
251 };/* class CDList<>::const_iterator::Proxy */
253 /** Postfix increment: returns Proxy with the old value. */
254 Proxy
operator++(int) {
260 /** Postfix decrement: returns Proxy with the old value. */
261 Proxy
operator--(int) {
267 };/* class CDList<>::const_iterator */
270 * Returns an iterator pointing to the first item in the list.
272 const_iterator
begin() const {
273 return const_iterator(d_list
);
277 * Returns an iterator pointing one past the last item in the list.
279 const_iterator
end() const {
280 return const_iterator(d_list
+ d_size
);
285 }/* CVC4::context namespace */
286 }/* CVC4 namespace */
288 #endif /* __CVC4__CONTEXT__CDLIST_H */