summaryrefslogtreecommitdiff
path: root/src/context/context.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/context/context.h')
-rw-r--r--src/context/context.h532
1 files changed, 135 insertions, 397 deletions
diff --git a/src/context/context.h b/src/context/context.h
index 6a35945b7..4e10347d7 100644
--- a/src/context/context.h
+++ b/src/context/context.h
@@ -20,6 +20,7 @@
#include "context/context_mm.h"
#include "util/Assert.h"
+
#include <cstdlib>
#include <cstring>
#include <new>
@@ -32,28 +33,27 @@ class Scope;
class ContextObj;
class ContextNotifyObj;
- /**
- * A Context encapsulates all of the dynamic state of the system. Its main
- * methods are push() and pop(). A call to push() saves the current state,
- * and a call to pop() restores the state saved by the most recent call to
- * push().
- *
- * Objects which want to participate in this global save and restore
- * mechanism must inherit from ContextObj (see below).
- *
- * For more flexible context-dependent behavior, objects may implement the
- * ContextNotifyObj interface and simply get a notification when a pop has
- * occurred.
- *
- * Context also uses a helper class called Scope which stores information
- * specific to the portion of the Context since the last call to push() (see
- * below).
- *
- * Memory allocation in Contexts is done with the help of the
- * ContextMemoryManager. A copy is stored in each Scope object for quick
- * access.
- *
- */
+/**
+ * A Context encapsulates all of the dynamic state of the system. Its main
+ * methods are push() and pop(). A call to push() saves the current state,
+ * and a call to pop() restores the state saved by the most recent call to
+ * push().
+ *
+ * Objects which want to participate in this global save and restore
+ * mechanism must inherit from ContextObj (see below).
+ *
+ * For more flexible context-dependent behavior, objects may implement the
+ * ContextNotifyObj interface and simply get a notification when a pop has
+ * occurred.
+ *
+ * Context also uses a helper class called Scope which stores information
+ * specific to the portion of the Context since the last call to push() (see
+ * below).
+ *
+ * Memory allocation in Contexts is done with the help of the
+ * ContextMemoryManager. A copy is stored in each Scope object for quick
+ * access.
+ */
class Context {
/**
@@ -87,7 +87,7 @@ public:
/**
* Destructor: pop all scopes, delete ContextMemoryManager
*/
- ~Context();
+ ~Context() throw(AssertionException);
/**
* Return the current (top) scope
@@ -107,7 +107,7 @@ public:
/**
* Return the ContextMemoryManager associated with the context.
*/
- ContextMemoryManager* getCMM(){ return d_pCMM; }
+ ContextMemoryManager* getCMM() { return d_pCMM; }
/**
* Save the current state, create a new Scope
@@ -182,15 +182,18 @@ public:
* Constructor: Create a new Scope; set the level and the previous Scope
* if any.
*/
- Scope(Context* pContext, ContextMemoryManager* pCMM, int level)
- : d_pContext(pContext), d_pCMM(pCMM), d_level(level),
- d_pContextObjList(NULL) { }
+ Scope(Context* pContext, ContextMemoryManager* pCMM, int level) :
+ d_pContext(pContext),
+ d_pCMM(pCMM),
+ d_level(level),
+ d_pContextObjList(NULL) {
+ }
/**
* Destructor: Restore all of the objects in ContextObjList. Defined inline
* below.
*/
- ~Scope();
+ ~Scope() throw();
/**
* Get the Context for this Scope
@@ -223,8 +226,9 @@ public:
* Overload operator new for use with ContextMemoryManager to allow creation
* of new Scope objects in the current memory region.
*/
- static void* operator new(size_t size, ContextMemoryManager* pCMM)
- { return pCMM->newData(size); }
+ static void* operator new(size_t size, ContextMemoryManager* pCMM) {
+ return pCMM->newData(size);
+ }
/**
* Overload operator delete for Scope objects allocated using
@@ -232,44 +236,44 @@ public:
* automatically when the ContextMemoryManager pop() method is called.
* Include both placement and standard delete for completeness.
*/
- static void operator delete(void* pMem, ContextMemoryManager* pCMM) { }
- static void operator delete(void* pMem) { }
+ static void operator delete(void* pMem, ContextMemoryManager* pCMM) {}
+ static void operator delete(void* pMem) {}
//FIXME: //! Check for memory leaks
// void check(void);
-}; /* class Scope */
-
- /**
- * This is an abstract base class from which all objects that are context-dependent
- * should inherit. For any data structure that you want to have be
- * automatically backtracked, do the following:
- * 1. Create a class for the data structure that inherits from ContextObj
- * 2. Implement save()
- * The role of save() is to create a new ContexObj object that contains
- * enough information to restore the object to its current state, even if
- * it gets changed later. Note that save should call the (default)
- * ContextObj Copy Constructor to copy the information in the base class.
- * It is recommended that any memory allocated by save() should be done
- * through the ContextMemoryManager. This way, it does not need to be
- * explicitly freed when restore is called. However, it is only required
- * that the ContextObj itself be allocated using the
- * ContextMemoryManager. If other memory is allocated not using the
- * ContextMemoryManager, it should be freed when restore() is called. In
- * fact, any clean-up work on a saved object must be done by restore().
- * This is because the destructor is never called explicitly on saved
- * objects.
- * 3. Implement restore()
- * The role of restore() is, given the ContextObj returned by a previous
- * call to save(), to restore the current object to the state it was in
- * when save() was called. Note that the implementation of restore does
- * *not* need to worry about restoring the base class data. This is done
- * automatically. Ideally, restore() should not have to free any memory
- * as any memory allocated by save() should have been done using the
- * ContextMemoryManager (see item 2 above).
- * 4. In the subclass implementation, any time the state is about to be
- * changed, first call makeCurrent().
- */
+};/* class Scope */
+
+/**
+ * This is an abstract base class from which all objects that are context-dependent
+ * should inherit. For any data structure that you want to have be
+ * automatically backtracked, do the following:
+ * 1. Create a class for the data structure that inherits from ContextObj
+ * 2. Implement save()
+ * The role of save() is to create a new ContexObj object that contains
+ * enough information to restore the object to its current state, even if
+ * it gets changed later. Note that save should call the (default)
+ * ContextObj Copy Constructor to copy the information in the base class.
+ * It is recommended that any memory allocated by save() should be done
+ * through the ContextMemoryManager. This way, it does not need to be
+ * explicitly freed when restore is called. However, it is only required
+ * that the ContextObj itself be allocated using the
+ * ContextMemoryManager. If other memory is allocated not using the
+ * ContextMemoryManager, it should be freed when restore() is called. In
+ * fact, any clean-up work on a saved object must be done by restore().
+ * This is because the destructor is never called explicitly on saved
+ * objects.
+ * 3. Implement restore()
+ * The role of restore() is, given the ContextObj returned by a previous
+ * call to save(), to restore the current object to the state it was in
+ * when save() was called. Note that the implementation of restore does
+ * *not* need to worry about restoring the base class data. This is done
+ * automatically. Ideally, restore() should not have to free any memory
+ * as any memory allocated by save() should have been done using the
+ * ContextMemoryManager (see item 2 above).
+ * 4. In the subclass implementation, any time the state is about to be
+ * changed, first call makeCurrent().
+ */
class ContextObj {
/**
* Pointer to Scope in which this object was last modified.
@@ -325,6 +329,7 @@ class ContextObj {
ContextObj* restoreAndContinue();
protected:
+
/**
* This is a method that must be implemented by all classes inheriting from
* ContextObj. See the comment before the class declaration.
@@ -341,57 +346,70 @@ protected:
* This method checks if the object has been modified in this Scope yet. If
* not, it calls update().
*/
- void makeCurrent() { if (!(d_pScope->isCurrent())) update(); }
+ void makeCurrent() {
+ if(!(d_pScope->isCurrent())) {
+ update();
+ }
+ }
/**
- * operator new using ContextMemoryManager (common case used by subclasses
- * during save() ). No delete is required for memory allocated this way,
- * since it is automatically released when the context is popped. Also note
- * that allocations using this operator never have their destructor called,
- * so any clean-up has to be done using the restore method.
+ * operator new using ContextMemoryManager (common case used by
+ * subclasses during save() ). No delete is required for memory
+ * allocated this way, since it is automatically released when the
+ * context is popped. Also note that allocations using this
+ * operator never have their destructor called, so any clean-up has
+ * to be done using the restore method.
*/
static void* operator new(size_t size, ContextMemoryManager* pCMM) {
return pCMM->newData(size);
}
/**
- * Corresponding placement delete. Note that this is provided just to
- * satisfy the requirement that a placement delete should be provided for
- * every placement new. It would only be called if a ContextObj Constructor
- * throws an exception after a successful call to the above new operator.
+ * Corresponding placement delete. Note that this is provided just
+ * to satisfy the requirement that a placement delete should be
+ * provided for every placement new. It would only be called if a
+ * ContextObj constructor throws an exception after a successful
+ * call to the above new operator.
*/
- static void operator delete(void* pMem, ContextMemoryManager* pCMM) { }
+ static void operator delete(void* pMem, ContextMemoryManager* pCMM) {}
public:
+
/**
* Create a new ContextObj. The initial scope is set to the bottom
- * scope of the Context. Note that in the common case, the copy constructor
- * is called to create new ContextObj objects. The default copy constructor
- * does the right thing, so we do not explicitly define it.
+ * scope of the Context. Note that in the common case, the copy
+ * constructor is called to create new ContextObj objects. The
+ * default copy constructor does the right thing, so we do not
+ * explicitly define it.
*/
ContextObj(Context* context);
/**
- * Destructor: Calls restore until restored to initial version. Also removes
- * object from all Scope lists. Note that this doesn't actually free the
- * memory allocated by the ContextMemoryManager for this object. This isn't
- * done until the corresponding Scope is popped.
+ * Destructor: Calls restore until restored to initial version.
+ * Also removes object from all Scope lists. Note that this doesn't
+ * actually free the memory allocated by the ContextMemoryManager
+ * for this object. This isn't done until the corresponding Scope
+ * is popped.
*/
- virtual ~ContextObj();
+ virtual ~ContextObj() throw(AssertionException);
/**
- * If you want to allocate a ContextObj object on the heap, use this special
- * new operator. To free this memory, instead of "delete p", use
- * "p->deleteSelf()".
+ * If you want to allocate a ContextObj object on the heap, use this
+ * special new operator. To free this memory, instead of
+ * "delete p", use "p->deleteSelf()".
*/
- static void* operator new(size_t size, bool) { return ::operator new(size); }
+ static void* operator new(size_t size, bool) {
+ return ::operator new(size);
+ }
/**
- * Corresponding placement delete. Note that this is provided for the
- * compiler in case the ContextObj constructor throws an exception. The
- * client can't call it.
+ * Corresponding placement delete. Note that this is provided for
+ * the compiler in case the ContextObj constructor throws an
+ * exception. The client can't call it.
*/
- static void operator delete(void* pMem, bool) { ::operator delete(pMem); }
+ static void operator delete(void* pMem, bool) {
+ ::operator delete(pMem);
+ }
/**
* Use this instead of delete to delete memory allocated using the special
@@ -399,7 +417,9 @@ public:
* function on memory allocated using the new that takes a
* ContextMemoryManager as an argument.
*/
- void deleteSelf() { ::operator delete(this); }
+ void deleteSelf() {
+ ::operator delete(this);
+ }
/**
* Disable delete: objects allocated with new(ContextMemorymanager) should
@@ -407,23 +427,23 @@ public:
* calling deleteSelf().
*/
static void operator delete(void* pMem) {
- AlwaysAssert(false, "Not Allowed!");
+ AlwaysAssert(false, "It is not allowed to delete a ContextObj this way!");
}
-}; /* class ContextObj */
+};/* class ContextObj */
/**
- * For more flexible context-dependent behavior than that provided by
- * ContextObj, objects may implement the ContextNotifyObj interface and
- * simply get a notification when a pop has occurred. See Context class for
- * how to register a ContextNotifyObj with the Context (you can choose to
- * have notification come before or after the ContextObj objects have been
- * restored).
+ * For more flexible context-dependent behavior than that provided
+ * by ContextObj, objects may implement the ContextNotifyObj
+ * interface and simply get a notification when a pop has occurred.
+ * See Context class for how to register a ContextNotifyObj with the
+ * Context (you can choose to have notification come before or after
+ * the ContextObj objects have been restored).
*/
class ContextNotifyObj {
/**
- * Context is our friend so that when the Context is deleted, any remaining
- * ContextNotifyObj can be removed from the Context list.
+ * Context is our friend so that when the Context is deleted, any
+ * remaining ContextNotifyObj can be removed from the Context list.
*/
friend class Context;
@@ -451,18 +471,19 @@ class ContextNotifyObj {
public:
/**
- * Constructor for ContextNotifyObj. Parameters are the context to which
- * this notify object will be added, and a flag which, if true, tells the
- * context to notify this object *before* the ContextObj objects are
- * restored. Otherwise, the context notifies the object after the ContextObj
- * objects are restored. The default is for notification after.
+ * Constructor for ContextNotifyObj. Parameters are the context to
+ * which this notify object will be added, and a flag which, if
+ * true, tells the context to notify this object *before* the
+ * ContextObj objects are restored. Otherwise, the context notifies
+ * the object after the ContextObj objects are restored. The
+ * default is for notification after.
*/
ContextNotifyObj(Context* pContext, bool preNotify = false);
/**
* Destructor: removes object from list
*/
- virtual ~ContextNotifyObj();
+ virtual ~ContextNotifyObj() throw(AssertionException);
/**
* This is the method called to notify the object of a pop. It must be
@@ -473,11 +494,11 @@ public:
// Inline functions whose definitions had to be delayed:
-inline Scope::~Scope() {
+inline Scope::~Scope() throw() {
// Call restore() method on each ContextObj object in the list.
- // Note that it is the responsibility of restore() to return the next item in
- // the list.
- while (d_pContextObjList != NULL) {
+ // Note that it is the responsibility of restore() to return the
+ // next item in the list.
+ while(d_pContextObjList != NULL) {
d_pContextObjList = d_pContextObjList->restoreAndContinue();
}
}
@@ -490,290 +511,7 @@ inline void Scope::addToChain(ContextObj* pContextObj) {
d_pContextObjList = pContextObj;
}
- /**
- * Most basic template for context-dependent objects. Simply makes a copy
- * (using the copy constructor) of class T when saving, and copies it back
- * (using operator=) during restore.
- */
-template <class T>
-class CDO :public ContextObj {
-
- /**
- * The data of type T being stored in this context-dependent object.
- */
- T d_data;
-
- /**
- * Implementation of mandatory ContextObj method save: simply copies the
- * current data to a copy using the copy constructor. Memory is allocated
- * using the ContextMemoryManager.
- */
- virtual ContextObj* save(ContextMemoryManager* pCMM) {
- return new(pCMM) CDO<T>(*this);
- }
-
- /**
- * Implementation of mandatory ContextObj method restore: simply copies the
- * saved data back from the saved copy using operator= for T.
- */
- virtual void restore(ContextObj* pContextObj) {
- d_data = ((CDO<T>*)pContextObj)->d_data;
- }
-
- /**
- * Copy constructor - it's private to ensure it is only used by save().
- * Basic CDO objects, cannot be copied-they have to be unique.
- */
- CDO(const CDO<T>& cdo): ContextObj(cdo), d_data(cdo.d_data) { }
-
- /**
- * operator= for CDO is private to ensure CDO object is not copied.
- */
- CDO<T>& operator=(const CDO<T>& cdo) {}
-
-public:
- /**
- * Main constructor - uses default constructor for T to create the initial
- * value of d_data.
- */
- CDO(Context* context) : ContextObj(context) {}
-
- /**
- * Constructor from object of type T. Creates a ContextObj and sets the data
- * to the given data value. Note that this value is only valid in the
- * current Scope. If the Scope is popped, the value will revert to whatever
- * is assigned by the default constructor for T
- */
- CDO(Context* context, const T& data) : ContextObj(context) {
- makeCurrent(); d_data = data;
- }
-
- /**
- * Destructor - no need to do anything.
- */
- ~CDO() {}
-
- /**
- * Set the data in the CDO. First call makeCurrent.
- */
- void set(const T& data) { makeCurrent(); d_data = data; }
-
- /**
- * Get the current data from the CDO. Read-only.
- */
- const T& get() const { return d_data; }
-
- /**
- * For convenience, define operator T to be the same as get().
- */
- operator T() { return get(); }
-
- /**
- * For convenience, define operator= that takes an object of type T.
- */
- CDO<T>& operator=(const T& data) { set(data); return *this; }
-
-}; /* class CDO */
-
- /**
- * Generic context-dependent dynamic array. Note that for efficiency, this
- * implementation makes the following assumptions:
- * 1. Over time, objects are only added to the list. Objects are only
- * removed when a pop restores the list to a previous state.
- * 2. T objects can safely be copied using their copy constructor,
- * operator=, and memcpy.
- */
-template <class T>
-class CDList :public ContextObj {
- /**
- * d_list is a dynamic array of objects of type T.
- */
- T* d_list;
-
- /**
- * Whether to call the destructor when items are popped from the
- * list. True by default, but can be set to false by setting the
- * second argument in the constructor to false.
- */
- bool d_callDestructor;
-
- /**
- * Number of objects in d_list
- */
- unsigned d_size;
-
- /**
- * Allocated size of d_list.
- */
- unsigned d_sizeAlloc;
-
- /**
- * Implementation of mandatory ContextObj method save: simply copies the
- * current size to a copy using the copy constructor (the pointer and the
- * allocated size are *not* copied as they are not restored on a pop).
- * The saved information is allocated using the ContextMemoryManager.
- */
- ContextObj* save(ContextMemoryManager* pCMM) {
- return new(pCMM) CDList<T>(*this);
- }
-
- /**
- * Implementation of mandatory ContextObj method restore: simply restores the
- * previous size. Note that the list pointer and the allocated size are not
- * changed.
- */
- void restore(ContextObj* data) {
- if (d_callDestructor) {
- unsigned size = ((CDList<T>*)data)->d_size;
- while (d_size != size) {
- --d_size;
- d_list[d_size].~T();
- }
- }
- else {
- d_size = ((CDList<T>*)data)->d_size;
- }
- }
-
- /**
- * Privae copy constructor used only by save above. d_list and d_sizeAlloc
- * are not copied: only the base class information and d_size are needed in
- * restore.
- */
- CDList(const CDList<T>& l): ContextObj(l), d_list(NULL),
- d_size(l.d_size), d_sizeAlloc(0) { }
-
- /**
- * Reallocate the array with more space.
- * Throws bad_alloc if memory allocation fails.
- */
- void grow() {
- if (d_list == NULL) {
- // Allocate an initial list if one does not yet exist
- d_sizeAlloc = 10;
- d_list = (T*)malloc(sizeof(T)*d_sizeAlloc);
- if(d_list == NULL){
- throw std::bad_alloc();
- }
- }
- else {
- // Allocate a new array with double the size
- d_sizeAlloc *= 2;
- T* tmpList = (T*)realloc(d_list, sizeof(T)*d_sizeAlloc);
- if(tmpList == NULL){
- throw std::bad_alloc();
- }
- d_list = tmpList;
- }
- }
-
-public:
- /**
- * Main constructor: d_list starts as NULL, size is 0
- */
- CDList(Context* context, bool callDestructor = true)
- : ContextObj(context), d_list(NULL), d_callDestructor(callDestructor),
- d_size(0), d_sizeAlloc(0) { }
-
- /**
- * Destructor: delete the list
- */
- ~CDList() {
- if(d_list != NULL) {
- if (d_callDestructor) {
- while (d_size != 0) {
- --d_size;
- d_list[d_size].~T();
- }
- }
- delete d_list;
- }
- }
-
- /**
- * Return the current size of (i.e. valid number of objects in) the list
- */
- unsigned size() const { return d_size; }
-
-
- /**
- * Return true iff there are no valid objects in the list.
- */
- bool empty() const { return d_size == 0; }
-
- /**
- * Add an item to the end of the list.
- */
- void push_back(const T& data) {
- makeCurrent();
- if (d_size == d_sizeAlloc) grow();
- ::new((void*)(d_list + d_size)) T(data);
- ++ d_size;
- }
-
- /**
- * operator[]: return the ith item in the list
- */
- const T& operator[](unsigned i) const {
- Assert(i < d_size, "index out of bounds in CDList::operator[]");
- return d_list[i];
- }
-
- /**
- * return the most recent item added to the list
- */
- const T& back() const {
- Assert(d_size > 0, "CDList::back() called on empty list");
- return d_list[d_size-1];
- }
-
- /**
- * Iterator for CDList class. It has to be const because we don't allow
- * items in the list to be changed. It's a straightforward wrapper around a
- * pointer. Note that for efficiency, we implement only prefix increment and
- * decrement. Also note that it's OK to create an iterator from an empty,
- * uninitialized list, as begin() and end() will have the same value (NULL).
- */
- class const_iterator {
- friend class CDList<T>;
- T* d_it;
- const_iterator(T* it) : d_it(it) {};
- public:
- const_iterator() : d_it(NULL) {}
- bool operator==(const const_iterator& i) const { return d_it == i.d_it; }
- bool operator!=(const const_iterator& i) const { return d_it != i.d_it; }
- const T& operator*() const { return *d_it; }
- /** Prefix increment */
- const_iterator& operator++() { ++d_it; return *this; }
- /** Prefix decrement */
- const_iterator& operator--() { --d_it; return *this; }
- }; /* class const_iterator */
-
- /**
- * Returns an iterator pointing to the first item in the list.
- */
- const_iterator begin() const {
- return const_iterator(d_list);
- }
-
- /**
- * Returns an iterator pointing one past the last item in the list.
- */
- const_iterator end() const {
- return const_iterator(d_list + d_size);
- }
-
-}; /* class CDList */
-
-template <class T>
-class CDMap;
-
-template <class T>
-class CDSet;
-
-} /* CVC4::context namespace */
-
-} /* CVC4 namespace */
+}/* CVC4::context namespace */
+}/* CVC4 namespace */
#endif /* __CVC4__CONTEXT__CONTEXT_H */
-
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback