+ * @version $Id: EST_TBuffer.h,v 1.4 2004/09/29 08:24:17 robert Exp $
+ */
+//@{
+#ifndef __EST_TBUFFER_H__
+#define __EST_TBUFFER_H__
+
+#include "EST_bool.h"
+
+/// How many chunks of memory to keep around for re-use.
+#define TBUFFER_N_OLD (10)
+
+/// Initial size for buffers created with no size specified.
+#define TBUFFER_DEFAULT_SIZE 0
+
+/// Amount to increment buffer size by.
+#define TBUFFER_DEFAULT_STEP 100
+
+/** Structure to remember old buffers for re-use.
+ * @see EST_TBuffer.h
+ */
+struct old_tbuffer { void *mem; unsigned int size; };
+
+/// Memory of old buffers
+extern struct old_tbuffer EST_old_buffers[TBUFFER_N_OLD];
+
+
+/** Extending buffer class.
+ *
+ * This class provides the convenience of arrays which change in size
+ * at run time rather more efficiently than the full EST_TVector class
+ * would.
+ *
+ * Buffers can only be expanded and when a buffer is no longer needed
+ * (i.e. when the variable goes out of scope) the memory is not deleted,
+ * rather it is saved for re-use as a new buffer.
+ *
+ * A typical use would be a buffer to hold a windowed section of a signal
+ * inside a signal processing loop where the size of the window changes from
+ * iteration to iteration.
+ *
+ * @see EST_TBuffer.h, Associated definitions.
+ * @see EST_TVector, class to use for more general uses.
+ * @see lpc_analyse, example of use.
+ */
+
+template
+class EST_TBuffer {
+
+private:
+ /// Pointer to memory.
+ TYPE *p_buffer;
+ /// Current size.
+ unsigned int p_size;
+ /// Amount to grow by (if negative it is a percentage).
+ int p_step;
+
+private:
+ /// Setup code.
+ void init(unsigned int size, int step);
+ /// Expand the buffer.
+ void expand_to(unsigned int req_size, bool cpy);
+ /// Expand and set some of it to a known value.
+ void expand_to(unsigned int req_size, const TYPE &set_to, int howmany);
+
+public:
+
+ /** Create with size and increment.
+ * Increment can be negative for percentage growth.
+ *
+ * Tries to use a buffer from EST_old_buffers[] if there is one which
+ * is suitable
+ * @see EST_old_buffers
+ */
+ EST_TBuffer(unsigned int size=TBUFFER_DEFAULT_SIZE, int step=TBUFFER_DEFAULT_STEP);
+
+ /// Destructor. Places the memory in EST_old_buffers[] for re-use if there is room.
+ ~EST_TBuffer(void);
+
+ /// Current available space.
+ unsigned int length(void) const {return p_size;}
+
+ /// Set to the given value. By default sets all values.
+ void set(const TYPE &set_to, int howmany=-1);
+
+ /**@name Methods to make sure there is enough space. */
+ //@{
+
+ /// Extend if needed, copying existing data.
+ void ensure(unsigned int req_size)
+ {if (req_size > p_size) expand_to(req_size, (bool)TRUE);}
+
+ /// Make sure there is enough space, copying if requested.
+ void ensure(unsigned int req_size, bool copy)
+ {if (req_size > p_size) expand_to(req_size, copy,-1);}
+
+ /// Make sure there is enough space, setting to a known value.
+ void ensure(unsigned int req_size, const TYPE &set_to, int howmany=-1)
+ {if (req_size > p_size) expand_to(req_size, set_to, howmany);}
+ //@}
+
+ /**@name Access to the memory itself. */
+ //@{
+
+ /// Simple access as a pointer.
+ TYPE *b(void) {return p_buffer;}
+ /// Read-only access when the EST_TBuffer is a constant
+ const TYPE *b(void) const {return p_buffer;}
+
+ /// operator () is simple access
+ const TYPE &operator() (unsigned int i) const { return p_buffer[i];}
+
+ TYPE &operator[] (unsigned int i) { return p_buffer[i];}
+ const TYPE &operator[] (unsigned int i) const { return p_buffer[i];}
+
+ //@}
+};
+
+#endif
+
+//@}
diff --git a/aeneas/cfw/speech_tools/EST_TDeque.h b/aeneas/cfw/speech_tools/EST_TDeque.h
new file mode 100644
index 00000000..7539aca9
--- /dev/null
+++ b/aeneas/cfw/speech_tools/EST_TDeque.h
@@ -0,0 +1,120 @@
+ /************************************************************************/
+ /* */
+ /* Centre for Speech Technology Research */
+ /* University of Edinburgh, UK */
+ /* Copyright (c) 1996,1997 */
+ /* All Rights Reserved. */
+ /* */
+ /* Permission is hereby granted, free of charge, to use and distribute */
+ /* this software and its documentation without restriction, including */
+ /* without limitation the rights to use, copy, modify, merge, publish, */
+ /* distribute, sublicense, and/or sell copies of this work, and to */
+ /* permit persons to whom this work is furnished to do so, subject to */
+ /* the following conditions: */
+ /* 1. The code must retain the above copyright notice, this list of */
+ /* conditions and the following disclaimer. */
+ /* 2. Any modifications must be clearly marked as such. */
+ /* 3. Original authors' names are not deleted. */
+ /* 4. The authors' names are not used to endorse or promote products */
+ /* derived from this software without specific prior written */
+ /* permission. */
+ /* */
+ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+ /* THIS SOFTWARE. */
+ /* */
+ /*************************************************************************/
+
+
+#ifndef __EST_TDEQUE_H__
+#define __EST_TDEQUE_H__
+
+#include "EST_TVector.h"
+#include "instantiate/EST_TDequeI.h"
+
+/** Double ended queue.
+ *
+ * @author Richard Caley
+ * @version $Id: EST_TDeque.h,v 1.3 2006/07/19 21:52:12 awb Exp $
+ */
+
+template
+class EST_TDeque {
+private:
+ EST_TVector p_vector;
+ int p_increment;
+ int p_back;
+ int p_front;
+
+ // Make the structure bigger.
+ void expand(void);
+
+public:
+ EST_TDeque(unsigned int capacity, unsigned int increment);
+ EST_TDeque(unsigned int capacity);
+ EST_TDeque(void);
+
+ /// Used to fill empty spaces when possible.
+ static const T *Filler;
+
+ /// Empty it out.
+ void clear(void);
+
+ /// Is there anything to get?
+ bool is_empty(void) const;
+
+ /// print picture of state. Mostly useful for debugging.
+ ostream &print(ostream &s) const;
+
+ /**@name stack
+ *
+ * An interface looking like a stack.
+ */
+ //@{
+ void push(T &item);
+ T &pop(void);
+ T &nth(int i);
+ //@}
+
+ /**@name inverse stack
+ *
+ * The other end as a stack.
+ */
+ //@{
+ void back_push(T& item);
+ T &back_pop(void);
+ //@}
+
+ /**@name queue
+ *
+ * An interface looking like a queue.
+ */
+ //@{
+ void add(T& item) { push(item); }
+ T &next() { return back_pop(); }
+ T &last() { return pop(); }
+ //@}
+
+ /**@name perl
+ *
+ * For people who think in perl
+ */
+ //@{
+ void unshift(T& item) { back_push(item); }
+ T &shift() { return back_pop(); }
+ //@}
+
+ friend ostream& operator << (ostream &st, const EST_TDeque< T > &deq)
+ {
+ return deq.print(st);
+ }
+};
+
+#endif
+
diff --git a/aeneas/cfw/speech_tools/EST_THandle.h b/aeneas/cfw/speech_tools/EST_THandle.h
new file mode 100644
index 00000000..1bd880cf
--- /dev/null
+++ b/aeneas/cfw/speech_tools/EST_THandle.h
@@ -0,0 +1,152 @@
+ /************************************************************************/
+ /* */
+ /* Centre for Speech Technology Research */
+ /* University of Edinburgh, UK */
+ /* Copyright (c) 1996,1997 */
+ /* All Rights Reserved. */
+ /* */
+ /* Permission is hereby granted, free of charge, to use and distribute */
+ /* this software and its documentation without restriction, including */
+ /* without limitation the rights to use, copy, modify, merge, publish, */
+ /* distribute, sublicense, and/or sell copies of this work, and to */
+ /* permit persons to whom this work is furnished to do so, subject to */
+ /* the following conditions: */
+ /* 1. The code must retain the above copyright notice, this list of */
+ /* conditions and the following disclaimer. */
+ /* 2. Any modifications must be clearly marked as such. */
+ /* 3. Original authors' names are not deleted. */
+ /* 4. The authors' names are not used to endorse or promote products */
+ /* derived from this software without specific prior written */
+ /* permission. */
+ /* */
+ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+ /* THIS SOFTWARE. */
+ /* */
+ /*************************************************************************/
+
+#ifndef __EST_THANDLE_H__
+#define __EST_THANDLE_H__
+
+#include
+
+using namespace std;
+
+#include "EST_bool.h"
+
+/** A `smart' pointer which does reference counting.
+ *
+ * Behaves almost like a pointer as far as naive code is concerned, but
+ * keeps count of how many handles are holding on to the contents
+ * and deletes it when there are none.
+ *
+ * You need to be careful there are no dumb C++ pointers to things which
+ * are being handled this way.
+ *
+ * Things to be handled should implement the same interface as EST_Handleable
+ * (either by taking that as a superclass or by reimplementing it) and in
+ * addition define {\tt object_ptr()}. See EST_TBox for an example.
+ *
+ * There are two parameter types. In most cases the thing which contains the
+ * reference count and the data it represents will be the same object, but
+ * in the case of boxed values it may not be, so you can specify the type
+ * of both independently.
+ *
+ * @see EST_Handleable
+ * @see EST_TBox
+ * @see EST_THandle:example
+ *
+ * @author Richard Caley
+ * @version $Id: EST_THandle.h,v 1.5 2006/07/19 21:52:12 awb Exp $
+ */
+
+
+template
+class EST_THandle {
+
+private:
+ BoxT *ptr;
+
+public:
+
+ EST_THandle(void) { ptr = (BoxT *)NULL; }
+
+ EST_THandle(BoxT *p) { if ((ptr=p)) p->inc_refcount(); }
+
+ EST_THandle(const EST_THandle &cp) {
+ ptr=cp.ptr;
+ if (ptr)
+ ptr->inc_refcount();
+ }
+
+ ~EST_THandle(void) {
+ if (ptr)
+ ptr->dec_refcount();
+ if (ptr && ptr->is_unreferenced())
+ delete ptr;
+ }
+
+ bool null() const { return ptr == NULL; }
+
+ int shareing(void) const { return ptr?(ptr->refcount() > 1):0; }
+
+ EST_THandle &operator = (EST_THandle h) {
+ // doing it in this order means self assignment is safe.
+ if (h.ptr)
+ (h.ptr)->inc_refcount();
+ if (ptr)
+ ptr->dec_refcount();
+ if (ptr && ptr->is_unreferenced())
+ delete ptr;
+ ptr=h.ptr;
+ return *this;
+ }
+
+ // If they manage to get hold of one...
+ // Actually usually used to assign NULL and so (possibly) deallocate
+ // the object currently pointed to.
+ EST_THandle &operator = (BoxT *t_ptr) {
+ // doing it in this order means self assignment is safe.
+ if (t_ptr)
+ t_ptr->inc_refcount();
+ if (ptr)
+ ptr->dec_refcount();
+ if (ptr && ptr->is_unreferenced())
+ delete ptr;
+ ptr=t_ptr;
+ return *this;
+ }
+
+ operator ObjectT *() {
+ return ptr?(ptr->object_ptr()):(ObjectT *)NULL;
+ }
+
+ operator const ObjectT *() const {
+ return ptr?(ptr->object_ptr()):(const ObjectT *)NULL;
+ }
+
+
+ int operator == (const BoxT *p) const { return ptr == p; }
+ int operator != (const BoxT *p) const { return !(*this == p); }
+
+ const ObjectT& operator *() const { return *(ptr->object_ptr()); }
+ ObjectT& operator *() { return *(ptr->object_ptr()); }
+ const ObjectT* operator ->() const { return (ptr->object_ptr()); }
+ ObjectT* operator ->() { return (ptr->object_ptr()); }
+
+ friend int operator == (const EST_THandle< BoxT, ObjectT > &a, const EST_THandle< BoxT, ObjectT > & b)
+ {return a.ptr==b.ptr; }
+ friend int operator != (const EST_THandle< BoxT, ObjectT > &a, const EST_THandle< BoxT, ObjectT > & b)
+ { return !( a==b ); }
+
+ friend ostream & operator << (ostream &s, const EST_THandle< BoxT, ObjectT > &a)
+ { return s << "HANDLE"; }
+};
+
+#endif
diff --git a/aeneas/cfw/speech_tools/EST_THash.h b/aeneas/cfw/speech_tools/EST_THash.h
new file mode 100644
index 00000000..c093390f
--- /dev/null
+++ b/aeneas/cfw/speech_tools/EST_THash.h
@@ -0,0 +1,333 @@
+ /************************************************************************/
+ /* */
+ /* Centre for Speech Technology Research */
+ /* University of Edinburgh, UK */
+ /* Copyright (c) 1996,1997 */
+ /* All Rights Reserved. */
+ /* */
+ /* Permission is hereby granted, free of charge, to use and distribute */
+ /* this software and its documentation without restriction, including */
+ /* without limitation the rights to use, copy, modify, merge, publish, */
+ /* distribute, sublicense, and/or sell copies of this work, and to */
+ /* permit persons to whom this work is furnished to do so, subject to */
+ /* the following conditions: */
+ /* 1. The code must retain the above copyright notice, this list of */
+ /* conditions and the following disclaimer. */
+ /* 2. Any modifications must be clearly marked as such. */
+ /* 3. Original authors' names are not deleted. */
+ /* 4. The authors' names are not used to endorse or promote products */
+ /* derived from this software without specific prior written */
+ /* permission. */
+ /* */
+ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+ /* THIS SOFTWARE. */
+ /* */
+ /************************************************************************/
+ /* Author: Richard Caley (rjc@cstr.ed.ac.uk) */
+ /************************************************************************/
+
+#ifndef __EST_THASH_H__
+#define __EST_THASH_H__
+
+#include
+
+using namespace std;
+
+#include "EST_String.h"
+#include "EST_system.h"
+#include "EST_bool.h"
+#include "EST_TIterator.h"
+
+#include "instantiate/EST_THashI.h"
+#include "instantiate/EST_TStringHashI.h"
+
+/**@name Hash Tables
+ *
+ * @author Richard Caley
+ * @version $Id: EST_THash.h,v 1.6 2004/09/29 08:24:17 robert Exp $
+ */
+//@{
+
+/** This is just a convenient place to put some useful hash functions.
+ */
+class EST_HashFunctions {
+public:
+ /// A generally useful hash function.
+ static unsigned int DefaultHash(const void *data, size_t size, unsigned int n);
+
+ /// A hash function for strings.
+ static unsigned int StringHash(const EST_String &key, unsigned int size);
+};
+
+template class EST_THash;
+
+/** This class is used in hash tables to hold a key value pair.
+ * Not much to say beyond that.
+ */
+template
+class EST_Hash_Pair {
+public:
+ /// The key
+ K k;
+ /// The value
+ V v;
+
+private:
+ /// Pointer used to chain entries into buckets.
+ EST_Hash_Pair *next;
+
+ /// The hash table must be a friend so it can see the pointer.
+ friend class EST_THash;
+};
+
+/** An open hash table. The number of buckets should be set to allow
+ * enough space that there are relatively few entries per bucket on
+ * average.
+ */
+
+template
+class EST_THash : protected EST_HashFunctions {
+
+private:
+ /// Something to return when there is no entry in the table.
+ static V Dummy_Value;
+ static K Dummy_Key;
+
+ /// Total number of entries.
+ unsigned int p_num_entries;
+
+ /// Number of buckets.
+ unsigned int p_num_buckets;
+
+ /// Pointer to an array of p_num_bucketsbuckets.
+ EST_Hash_Pair **p_buckets;
+
+ /// The hash function to use on this table.
+ unsigned int (*p_hash_function)(const K &key, unsigned int size);
+
+public:
+ /** Create a table with the given number of buckets. Optionally setting
+ * a custom hash function.
+ */
+ EST_THash(int size,
+ unsigned int (*hash_function)(const K &key, unsigned int size)= NULL);
+
+ /// Create a copy
+ EST_THash(const EST_THash &from);
+
+ /// Destroy the table.
+ ~EST_THash(void);
+
+ /// Empty the table.
+ void clear(void);
+
+ /// Return the total number of entries in the table.
+ unsigned int num_entries(void) const
+ { return p_num_entries; };
+
+ /// Does the key have an entry?
+ int present(const K &key) const;
+
+ /** Return the value associated with the key.
+ * found is set to whether such an entry was found.
+ */
+ V &val(const K &key, int &found) const;
+
+ /// Return the value associated with the key.
+ V &val(const K &key) const {int x; return val(key, x); }
+
+ const K &key(const V &val, int &found) const;
+ const K &key(const V &val) const {int x; return key(val, x); }
+
+ /// Copy all entries
+ void copy(const EST_THash &from);
+
+ /// Apply func to each entry in the table.
+ void map(void (*func)(K&, V&));
+
+ /// Add an entry to the table.
+ int add_item(const K &key, const V &value, int no_search = 0);
+
+ /// Remove an entry from the table.
+ int remove_item(const K &rkey, int quiet = 0);
+
+ /// Assignment is a copy operation
+ EST_THash &operator = (const EST_THash &from);
+
+ /// Print the table to stream in a human readable format.
+ void dump(ostream &stream, int all=0);
+
+ /**@name Pair Iteration
+ *
+ * This iterator steps through the table returning key-value pairs.
+ */
+ //@{
+protected:
+ /** A position in the table is given by a bucket number and a
+ * pointer into the bucket.
+ */
+ // struct IPointer{ unsigned int b; EST_Hash_Pair *p; };
+ struct IPointer_s{ unsigned int b; EST_Hash_Pair *p; };
+
+ typedef struct IPointer_s IPointer;
+
+ /// Shift to point at something.
+ void skip_blank(IPointer &ip) const
+ {
+ while (ip.p==NULL && ip.bnext;
+ skip_blank(ip);
+ }
+
+ /// We are at the end if the pointer ever becomes NULL
+ bool points_to_something(const IPointer &ip) const { return ip.b &points_at(const IPointer &ip) { return *(ip.p); }
+
+ /// The iterator must be a friend to access this private interface.
+ friend class EST_TStructIterator< EST_THash, IPointer, EST_Hash_Pair >;
+ friend class EST_TRwStructIterator< EST_THash, IPointer, EST_Hash_Pair >;
+ friend class EST_TIterator< EST_THash, IPointer, EST_Hash_Pair >;
+ friend class EST_TRwIterator< EST_THash, IPointer, EST_Hash_Pair >;
+
+public:
+ /// An entry returned by the iterator is a key value pair.
+ typedef EST_Hash_Pair Entry;
+
+ /// Give the iterator a sensible name.
+ typedef EST_TStructIterator< EST_THash, IPointer, EST_Hash_Pair > Entries;
+ typedef EST_TRwStructIterator< EST_THash, IPointer, EST_Hash_Pair > RwEntries;
+ //@}
+
+ /**@name Key Iteration
+ *
+ * This iterator steps through the table returning just keys.
+ */
+ //@{
+protected:
+ /** A position in the table is given by a bucket number and a
+ * pointer into the bucket.
+ */
+ struct IPointer_k_s { unsigned int b; EST_Hash_Pair *p; };
+
+ typedef struct IPointer_k_s IPointer_k;
+
+ /// Shift to point at something.
+ void skip_blank(IPointer_k &ip) const
+ {
+ while (ip.p==NULL && ip.bnext;
+ skip_blank(ip);
+ }
+
+ /// We are at the end if the pointer ever becomes NULL
+ bool points_to_something(const IPointer_k &ip) const { return ip.bk; }
+
+ /// The iterator must be a friend to access this private interface.
+ friend class EST_TIterator< EST_THash, IPointer_k, K >;
+ friend class EST_TRwIterator< EST_THash, IPointer_k, K >;
+
+public:
+ /// An entry returned by this iterator is just a key.
+ typedef K KeyEntry;
+
+ /// Give the iterator a sensible name.
+ typedef EST_TIterator< EST_THash, IPointer_k, K > KeyEntries;
+ typedef EST_TRwIterator< EST_THash, IPointer_k, K > KeyRwEntries;
+ //@}
+
+};
+
+/** A specialised hash table for when the key is an EST_String.
+ *
+ * This is just a version of EST_THash which
+ * has a different default hash function.
+ */
+
+template
+class EST_TStringHash : public EST_THash {
+public:
+
+ /// Create a string hash table of size buckets.
+ EST_TStringHash(int size) : EST_THash(size, EST_HashFunctions::StringHash) {};
+
+ /// An entry returned by the iterator is a key value pair.
+ typedef EST_Hash_Pair Entry;
+
+/* struct IPointer_s{ unsigned int b; Entry *p; };
+ typedef struct IPointer_s IPointer; */
+
+ // Convince GCC that the IPointer we're going to use is a typename
+ typedef typename EST_THash::IPointer TN_IPointer;
+
+ /// Give the iterator a sensible name.
+ typedef EST_TStructIterator< EST_THash, typename EST_THash::IPointer,
+ EST_Hash_Pair > Entries;
+
+ typedef EST_TRwStructIterator< EST_THash, typename EST_THash::IPointer,
+ EST_Hash_Pair > RwEntries;
+ //@}
+
+ typedef EST_String KeyEntry;
+
+/* struct IPointer_k_s { unsigned int b; EST_Hash_Pair *p; };
+ typedef struct IPointer_k_s IPointer_k; */
+
+ /// Give the iterator a sensible name.
+
+ // Convince GCC that the IPointer_k we're going to use is a typename
+ typedef typename EST_THash::IPointer_k TN_IPointer_k;
+
+ typedef EST_TIterator< EST_THash, typename EST_THash::IPointer_k,
+ EST_String > KeyEntries;
+ typedef EST_TRwIterator< EST_THash, typename EST_THash::IPointer_k,
+ EST_String > KeyRwEntries;
+};
+
+
+/** The default hash function used by EST_THash
+ */
+inline static unsigned int DefaultHashFunction(const void *data, size_t size, unsigned int n)
+{
+ unsigned int x=0;
+ const char *p = (const char *)data;
+ for(; size>0 ; p++, size--)
+ x = ((x+*p)*33) % n;
+ return x;
+}
+
+//@}
+#endif
diff --git a/aeneas/cfw/speech_tools/EST_TIterator.h b/aeneas/cfw/speech_tools/EST_TIterator.h
new file mode 100644
index 00000000..832e8e37
--- /dev/null
+++ b/aeneas/cfw/speech_tools/EST_TIterator.h
@@ -0,0 +1,298 @@
+ /************************************************************************/
+ /* */
+ /* Centre for Speech Technology Research */
+ /* University of Edinburgh, UK */
+ /* Copyright (c) 1996,1997 */
+ /* All Rights Reserved. */
+ /* */
+ /* Permission is hereby granted, free of charge, to use and distribute */
+ /* this software and its documentation without restriction, including */
+ /* without limitation the rights to use, copy, modify, merge, publish, */
+ /* distribute, sublicense, and/or sell copies of this work, and to */
+ /* permit persons to whom this work is furnished to do so, subject to */
+ /* the following conditions: */
+ /* 1. The code must retain the above copyright notice, this list of */
+ /* conditions and the following disclaimer. */
+ /* 2. Any modifications must be clearly marked as such. */
+ /* 3. Original authors' names are not deleted. */
+ /* 4. The authors' names are not used to endorse or promote products */
+ /* derived from this software without specific prior written */
+ /* permission. */
+ /* */
+ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+ /* THIS SOFTWARE. */
+ /* */
+ /************************************************************************/
+
+#ifndef __EST_TITERATOR_H__
+#define __EST_TITERATOR_H__
+
+/** Template class defining interface to an iterator, i.e an object
+ * which returns elements from a structure one at a time.
+ *
+ * This is template is usually hidden in the declaration of the
+ * container classes with a typedef for Entries providing a more
+ * convenient name for the iterator. However the interface is that
+ * defined here.
+ *
+ * We support two interfaces, a pointer like interface similar to
+ * specialised iteration code elsewhere in the speech tools library
+ * and to the iterators in the C++ standard template library and an
+ * interface similar to that of Enumerations in Java.
+ *
+ *
+ * MyContainer::Entries them;
+ *
+ * for(them.begin(container); them; them++)
+ * {
+ * MyContainer::Entry &it = *them;
+ * // Do Something With it
+ * }
+ *
+ *
+ * MyContainer::Entries them;
+ *
+ * them.begin(container);
+ * while (them.has_more_entries())
+ * {
+ * MyContainer::Entry &it = them.next_entry();
+ * // Do Something With it
+ * }
+ *
+ * @author Richard Caley
+ * @version $Id: EST_TIterator.h,v 1.7 2013/04/13 14:17:11 awb Exp $
+ */
+
+template
+ class EST_TStructIterator;
+template
+ class EST_TRwIterator;
+template
+ class EST_TRwStructIterator;
+
+template
+class EST_TIterator
+{
+protected:
+ /// The container we are looking at.
+ Container *cont;
+
+ /// Position in the structure. May or may not be useful.
+ unsigned int pos;
+
+ /** Structure defined by the container class which contains the
+ * current state of the iteration.
+ */
+ IPointer pointer;
+
+public:
+ /// Name for an iterator like this
+ typedef EST_TIterator Iter;
+
+ /// Create an iterator not associated with any specific container.
+ EST_TIterator() {cont=NULL;}
+
+ /// Create an iterator ready to run over the given container.
+ EST_TIterator(const Container &over)
+ { begin(over); }
+
+ /// Copy an iterator by assignment
+ Iter &operator = (const Iter &orig)
+ { cont=orig.cont; pos=orig.pos; pointer=orig.pointer; return *this;}
+
+ /// Assigning a container to an iterator sets it ready to start.
+ Iter &operator = (const Container &over)
+ { begin(over); return *this;}
+
+ /// Set the iterator ready to run over this container.
+ void begin(const Container &over)
+ {cont=((Container *)(void *)&over); beginning();}
+
+ /// Reset to the start of the container.
+ void beginning()
+ {if (cont) cont->point_to_first(pointer); pos=0;}
+
+ /**@name End Tests
+ */
+ //@{
+ /// True if there are more elements to look at.
+ bool has_more_elements() const
+ {return cont && cont->points_to_something(pointer);}
+
+ /// True when there are no more.
+ bool at_end() const
+ {return !has_more_elements();}
+
+ /** Viewing the iterator as an integer (for instance in a test)
+ * sees a non-zero value iff there are elements still to look at.
+ */
+ operator int() const
+ {return has_more_elements();}
+ //@}
+
+ /**@name Moving Forward
+ */
+ //@{
+ /// Next moves to the next entry.
+ void next()
+ {cont->move_pointer_forwards(pointer); pos++;}
+
+ /// The increment operator does the same as next.
+ Iter &operator ++()
+ {next(); return *this;}
+ Iter operator ++(int dummy)
+ {
+ (void)dummy;
+ Iter old =*this;
+ next();
+ return old;
+ }
+ //@}
+
+ /**@name Access
+ */
+ //@{
+ /// Return the element currently pointed to.
+ const Entry& current() const
+ {return cont->points_at(pointer);}
+
+ /// The * operator returns the current element.
+ const Entry &operator *() const
+ {return current();}
+
+#if 0
+ // This only works for some Entry types.
+ const Entry *operator ->() const
+ {return ¤t();}
+#endif
+
+ /// Return the current element and move the pointer forwards.
+ const Entry& next_element()
+ {
+ const Entry &it = cont->points_at(pointer);
+ cont->move_pointer_forwards(pointer);
+ return it;
+ }
+
+ /// Return the current position
+
+ unsigned int n() const { return pos; }
+ //@}
+
+ friend class EST_TStructIterator ;
+ friend class EST_TRwIterator ;
+ friend class EST_TRwStructIterator ;
+
+};
+
+template
+class EST_TStructIterator
+ : public EST_TIterator
+{
+public:
+
+ typedef EST_TIterator Iter;
+
+ /// Create an iterator not associated with any specific container.
+ EST_TStructIterator() {this->cont=NULL;}
+
+ /// Copy an iterator by assignment
+ Iter &operator = (const Iter &orig)
+ { this->cont=orig.cont; this->pos=orig.pos; this->pointer=orig.pointer; return *this;}
+
+ /// Create an iterator ready to run over the given container.
+ EST_TStructIterator(const Container &over)
+ { this->begin(over); }
+
+ const Entry *operator ->() const
+ {return &this->current();}
+};
+
+template
+class EST_TRwIterator
+ : public EST_TIterator
+{
+private:
+ /// Can't access constant containers this way.
+ // EST_TRwIterator(const Container &over) { (void) over; }
+
+ /// Can't access constant containers this way.
+ // void begin(const Container &over) { (void) over; }
+
+public:
+
+ typedef EST_TRwIterator Iter;
+
+ /// Create an iterator not associated with any specific container.
+ EST_TRwIterator() {this->cont=NULL;}
+
+ /// Copy an iterator by assignment
+ Iter &operator = (const Iter &orig)
+ { this->cont=orig.cont; this->pos=orig.pos; this->pointer=orig.pointer; return *this;}
+
+ /// Create an iterator ready to run over the given container.
+ EST_TRwIterator(Container &over)
+ { begin(over); }
+
+ /// Set the iterator ready to run over this container.
+ void begin(Container &over)
+ {this->cont=&over; this->beginning();}
+
+ /**@name Access
+ */
+ //@{
+ /// Return the element currently pointed to.
+ Entry& current() const
+ {return this->cont->points_at(this->pointer);}
+
+ /// The * operator returns the current element.
+ Entry &operator *() const
+ {return current();}
+
+#if 0
+ Entry *operator ->() const
+ {return ¤t();}
+#endif
+
+ /// Return the current element and move the pointer forwards.
+ Entry& next_element()
+ {
+ Entry &it = this->cont->points_at(this->pointer);
+ this->cont->move_pointer_forwards(this->pointer);
+ return it;
+ }
+
+ //@}
+};
+
+template
+class EST_TRwStructIterator
+ : public EST_TRwIterator
+{
+public:
+
+ typedef EST_TRwStructIterator Iter;
+
+ /// Create an iterator not associated with any specific container.
+ EST_TRwStructIterator() {this->cont=NULL;}
+
+ /// Copy an iterator by assignment
+ Iter &operator = (const Iter &orig)
+ { this->cont=orig.cont; this->pos=orig.pos; this->pointer=orig.pointer; return *this;}
+
+ /// Create an iterator ready to run over the given container.
+ EST_TRwStructIterator(Container &over)
+ { this->begin(over); }
+
+ Entry *operator ->() const
+ {return &this->current();}
+};
+
+#endif
diff --git a/aeneas/cfw/speech_tools/EST_TKVL.h b/aeneas/cfw/speech_tools/EST_TKVL.h
new file mode 100644
index 00000000..4b9a6d5d
--- /dev/null
+++ b/aeneas/cfw/speech_tools/EST_TKVL.h
@@ -0,0 +1,204 @@
+/*************************************************************************/
+/* */
+/* Centre for Speech Technology Research */
+/* University of Edinburgh, UK */
+/* Copyright (c) 1995,1996 */
+/* All Rights Reserved. */
+/* */
+/* Permission is hereby granted, free of charge, to use and distribute */
+/* this software and its documentation without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of this work, and to */
+/* permit persons to whom this work is furnished to do so, subject to */
+/* the following conditions: */
+/* 1. The code must retain the above copyright notice, this list of */
+/* conditions and the following disclaimer. */
+/* 2. Any modifications must be clearly marked as such. */
+/* 3. Original authors' names are not deleted. */
+/* 4. The authors' names are not used to endorse or promote products */
+/* derived from this software without specific prior written */
+/* permission. */
+/* */
+/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+/* THIS SOFTWARE. */
+/* */
+/*************************************************************************/
+/* Author : Paul Taylor */
+/* Date : January 1995 */
+/*-----------------------------------------------------------------------*/
+/* Key/Value list template class */
+/* */
+/*=======================================================================*/
+#ifndef __EST_TKVL_H__
+#define __EST_TKVL_H__
+
+#include
+
+using namespace std;
+
+#include "EST_TList.h"
+#include "instantiate/EST_TKVLI.h"
+#include "EST_TIterator.h"
+
+class EST_String;
+
+
+/** Templated Key-Value Item. Serves as the items in the list of the
+EST_TKVL class. */
+template class EST_TKVI {
+ public:
+ K k;
+ V v;
+
+ inline bool operator==(const EST_TKVI &i){
+ return( (i.k == k) && (i.v == v) );
+ }
+
+ friend ostream& operator << (ostream& s, EST_TKVI const &i)
+ { return s << i.k << "\t" << i.v << "\n"; }
+};
+
+
+/** Templated Key-Value list. Objects of type EST_TKVL contain lists which
+are accessed by a key of type {\bf K}, which returns a value of type
+{\bf V}. */
+template class EST_TKVL {
+ private:
+ EST_Litem *find_pair_key(const K &key) const;
+ EST_Litem *find_pair_val(const V &val) const;
+ public:
+ /**@name Constructor functions */
+ //@{
+ /// default constructor
+ EST_TKVL() {;}
+ /// copy constructor
+ EST_TKVL(const EST_TKVL &kv);
+ //@}
+
+ /// default value, returned when there is no such entry.
+ static V *default_val;
+
+ /// default value, returned when there is no such entry.
+ static K *default_key;
+
+ /// Linked list of key-val pairs. Don't use
+ /// this as it will be made private in the future
+ EST_TList< EST_TKVI > list;
+
+ /// number of key value pairs in list
+ const int length() const {return list.length();}
+
+ /// Return First key value pair in list
+ EST_Litem * head() const {return list.head();};
+
+ /// Empty list.
+ void clear();
+
+ /**@name Access functions.
+ */
+ //@{
+ /// return value according to key (const)
+ const V &val(const K &rkey, bool m=0) const;
+ /// return value according to key (non-const)
+ V &val(const K &rkey, bool m=0);
+ /// return value according to ptr
+ const V &val(EST_Litem *ptr, bool m=0) const;
+ /// return value according to ptr
+ V &val(EST_Litem *ptr, bool m=0);
+ /// value or default
+ const V &val_def(const K &rkey, const V &def) const;
+
+ /// find key, reference by ptr
+ const K &key(EST_Litem *ptr, int m=1) const;
+ /// find key, reference by ptr
+ K &key(EST_Litem *ptr, int m=1);
+
+ /// return first matching key, referenced by val
+ const K &key(const V &v, int m=1) const;
+
+ /** change key-val pair. If no corresponding entry is present, add
+ to end of list.
+ */
+ int change_val(const K &rkey,const V &rval);
+ /** change key-val pair. If no corresponding entry is present, add
+ to end of list.*/
+ int change_val(EST_Litem *ptr,const V &rval); // change key-val pair.
+ /// change name of key pair.
+ int change_key(EST_Litem *ptr,const K &rkey);
+
+ /// add key-val pair to list
+ int add_item(const K &rkey,const V &rval, int no_search = 0);
+
+ /// remove key and val pair from list
+ int remove_item(const K &rkey, int quiet = 0);
+
+ //@}
+
+ /// Returns true if key is present.
+ const int present(const K &rkey) const;
+
+ /// apply function to each pair
+ void map(void (*func)(K&, V&));
+
+ friend ostream& operator << (ostream& s, EST_TKVL const &l)
+ {EST_Litem *p;
+ for (p = l.list.head(); p ; p = p->next())
+ s << l.list(p).k << "\t" << l.list(p).v << endl;
+ return s;
+ }
+
+ /// full copy of KV list.
+ EST_TKVL & operator = (const EST_TKVL &kv);
+ /// add kv after existing list.
+ EST_TKVL & operator += (const EST_TKVL &kv);
+ /// make new concatenated list
+ EST_TKVL operator + (const EST_TKVL &kv);
+
+ // Iteration support
+
+protected:
+ struct IPointer { EST_Litem *p; };
+
+ void point_to_first(IPointer &ip) const { ip.p = list.head(); }
+ void move_pointer_forwards(IPointer &ip) const { ip.p = ip.p->next(); }
+ bool points_to_something(const IPointer &ip) const { return ip.p != NULL; }
+ EST_TKVI &points_at(const IPointer &ip) { return list(ip.p); }
+
+ friend class EST_TIterator< EST_TKVL, IPointer, EST_TKVI >;
+ friend class EST_TStructIterator< EST_TKVL, IPointer, EST_TKVI >;
+ friend class EST_TRwIterator< EST_TKVL, IPointer, EST_TKVI >;
+ friend class EST_TRwStructIterator< EST_TKVL, IPointer, EST_TKVI >;
+
+public:
+ typedef EST_TKVI Entry;
+ typedef EST_TStructIterator< EST_TKVL, IPointer, Entry> Entries;
+ typedef EST_TRwStructIterator< EST_TKVL, IPointer, Entry> RwEntries;
+
+ // Iteration support
+
+protected:
+ struct IPointer_k { EST_Litem *p; };
+
+ void point_to_first(IPointer_k &ip) const { ip.p = list.head(); }
+ void move_pointer_forwards(IPointer_k &ip) const { ip.p = ip.p->next(); }
+ bool points_to_something(const IPointer_k &ip) const { return ip.p != NULL; }
+ K &points_at(const IPointer_k &ip) { return list(ip.p).k; }
+
+ friend class EST_TIterator< EST_TKVL, IPointer_k, K >;
+ friend class EST_TRwIterator< EST_TKVL, IPointer_k, K >;
+
+public:
+ typedef K KeyEntry;
+ typedef EST_TIterator< EST_TKVL, IPointer_k, KeyEntry> KeyEntries;
+ typedef EST_TRwIterator< EST_TKVL, IPointer_k, KeyEntry> KeyRwEntries;
+
+};
+
+#endif // __KVL_H__
diff --git a/aeneas/cfw/speech_tools/EST_TList.h b/aeneas/cfw/speech_tools/EST_TList.h
new file mode 100644
index 00000000..a5fcf6ef
--- /dev/null
+++ b/aeneas/cfw/speech_tools/EST_TList.h
@@ -0,0 +1,328 @@
+ /*************************************************************************/
+ /* */
+ /* Centre for Speech Technology Research */
+ /* University of Edinburgh, UK */
+ /* Copyright (c) 1995,1996 */
+ /* All Rights Reserved. */
+ /* Permission is hereby granted, free of charge, to use and distribute */
+ /* this software and its documentation without restriction, including */
+ /* without limitation the rights to use, copy, modify, merge, publish, */
+ /* distribute, sublicense, and/or sell copies of this work, and to */
+ /* permit persons to whom this work is furnished to do so, subject to */
+ /* the following conditions: */
+ /* 1. The code must retain the above copyright notice, this list of */
+ /* conditions and the following disclaimer. */
+ /* 2. Any modifications must be clearly marked as such. */
+ /* 3. Original authors' names are not deleted. */
+ /* 4. The authors' names are not used to endorse or promote products */
+ /* derived from this software without specific prior written */
+ /* permission. */
+ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+ /* THIS SOFTWARE. */
+ /* */
+ /*************************************************************************/
+ /* */
+ /* Author : Paul Taylor */
+ /* Date : April 1995 */
+ /* --------------------------------------------------------------------- */
+ /* Double linked list class */
+ /* */
+ /* Modified by RJC, 21/7/97. Now much of the working code is in the */
+ /* UList class, this template class provides a type safe front end to */
+ /* the untyped list. */
+ /* */
+ /*************************************************************************/
+
+#ifndef __Tlist_H__
+#define __Tlist_H__
+
+#include
+
+using namespace std;
+
+#include "EST_common.h"
+#include "EST_UList.h"
+#include "EST_TSortable.h"
+#include "EST_TIterator.h"
+
+#include "instantiate/EST_TListI.h"
+
+class EST_String;
+
+template class EST_TList;
+
+template class EST_TItem : public EST_UItem {
+private:
+ static void *operator new(size_t not_used, void *place)
+ {(void)not_used; return place;}
+ static void *operator new(size_t size)
+ {void *p;
+ p = (void *)walloc(char,size);
+ return p;}
+ static void operator delete(void *p)
+ { wfree(p);}
+
+ static EST_TItem *s_free;
+ static unsigned int s_nfree;
+ static unsigned int s_maxFree;
+
+protected:
+ static EST_TItem *make(const T &val);
+ static void release(EST_TItem *it);
+
+ friend class EST_TList;
+
+public:
+ T val;
+
+ EST_TItem(const T &v) : val(v)
+ { init(); };
+ EST_TItem()
+ { init();};
+};
+
+// pretty name
+
+typedef EST_UItem EST_Litem;
+
+/**
+
+A Template doubly linked list class. This class contains doubly linked
+lists of a type denoted by {\tt T}. A pointer of type \Ref{EST_Litem}
+is used to access items in the list. The class supports a variety of
+ways of adding, removing and accessing items in the list. For examples
+of how to operate lists, see \Ref{list_example}.
+
+Iteration through the list is performed using a pointer of type
+\Ref{EST_Litem}. See \Ref{Iteration} for example code.
+
+*/
+
+template class EST_TList : public EST_UList
+{
+ private:
+ void copy_items(const EST_TList &l);
+ public:
+ void init() { EST_UList::init(); };
+ static void free_item(EST_UItem *item);
+
+ /**@name Constructor functions */
+ //@{
+ /// default constructor
+ EST_TList() { };
+ /// copy constructor
+ EST_TList(const EST_TList &l);
+ ~ EST_TList() { clear_and_free(free_item); }
+ //@}
+
+ /**@name Access functions for reading and writing items.
+ See \Ref{EST_TList_Accessing} for examples.*/
+
+ //@{
+
+ /** return the value associated with the EST_Litem pointer. This
+ has the same functionality as the overloaded () operator.
+ */
+ T &item(const EST_Litem *p)
+ { return ((EST_TItem *)p) -> val; };
+ /** return a const value associated with the EST_Litem pointer.*/
+ const T &item(const EST_Litem *p) const
+ { return ((EST_TItem *)p) -> val; };
+ /// return the Nth value
+ T &nth(int n)
+ { return item(nth_pointer(n)); };
+ /// return a const Nth value
+ const T &nth(int n) const
+ { return item(nth_pointer(n)); };
+
+ /// return const reference to first item in list
+ const T &first() const
+ { return item(head()); };
+ /// return const reference to last item in list
+ const T &last() const
+ { return item(tail()); };
+ /** return reference to first item in list
+ * @see last
+ */
+ T &first()
+ { return item(head()); };
+ /// return reference to last item in list
+ T &last()
+ { return item(tail()); };
+
+ /// return const reference to item in list pointed to by {\tt ptr}
+ const T &operator () (const EST_Litem *ptr) const
+ { return item(ptr); };
+ /// return non-const reference to item in list pointed to by {\tt ptr}
+ T &operator () (const EST_Litem *ptr)
+ { return item(ptr); };
+
+ //@}
+
+ /**@name Removing items in a list.
+ more.
+ */
+ //@{
+ /** remove item pointed to by {\tt ptr}, return pointer to previous item.
+ See \Ref{Removing} for example code.*/
+ EST_Litem *remove(EST_Litem *ptr)
+ { return EST_UList::remove(ptr, free_item); };
+
+ /// remove nth item, return pointer to previous item
+ EST_Litem *remove_nth(int n)
+ { return EST_UList::remove(n, free_item); };
+
+ //@}
+
+
+ /**@name Adding items to a list.
+ In all cases, a complete copy of
+ the item is made and added to the list. See \Ref{Addition} for examples.
+ */
+ //@{
+ /// add item onto end of list
+ void append(const T &item)
+ { EST_UList::append(EST_TItem::make(item)); };
+ /// add item onto start of list
+ void prepend(const T &item)
+ { EST_UList::prepend(EST_TItem::make(item)); };
+
+ /** add {\tt item} after position given by {\tt ptr}, return pointer
+ to added item. */
+
+ EST_Litem *insert_after(EST_Litem *ptr, const T &item)
+ { return EST_UList::insert_after(ptr, EST_TItem::make(item)); };
+
+ /** add {\tt item} before position given by {\tt ptr}, return
+ pointer to added item. */
+
+ EST_Litem *insert_before(EST_Litem *ptr, const T &item)
+ { return EST_UList::insert_before(ptr, EST_TItem::make(item)); };
+
+ //@}
+
+ /**@name Exchange */
+ //@{
+ /// exchange 1
+ void exchange(EST_Litem *a, EST_Litem *b)
+ { EST_UList::exchange(a, b); };
+ /// exchange 2
+ void exchange(int i, int j)
+ { EST_UList::exchange(i,j); };
+ /// exchange 3
+ static void exchange_contents(EST_Litem *a, EST_Litem *b);
+ //@}
+
+ /**@name General functions */
+ //@{
+ /// make full copy of list
+ EST_TList &operator=(const EST_TList &a);
+ /// Add list onto end of existing list
+ EST_TList &operator +=(const EST_TList &a);
+
+ /// print list
+ friend ostream& operator << (ostream &st, EST_TList const &list) {
+ EST_Litem *ptr;
+ for (ptr = list.head(); ptr != 0; ptr = ptr->next())
+ st << list.item(ptr) << " ";
+ return st;
+ }
+
+ /// remove all items in list
+ void clear(void)
+ { clear_and_free(free_item); };
+ //@}
+
+ // Iteration support
+
+protected:
+ struct IPointer { EST_Litem *p; };
+
+ void point_to_first(IPointer &ip) const { ip.p = head(); }
+ void move_pointer_forwards(IPointer &ip) const { ip.p = ip.p->next(); }
+ bool points_to_something(const IPointer &ip) const { return ip.p != NULL; }
+ T &points_at(const IPointer &ip) { return item(ip.p); }
+
+ friend class EST_TIterator< EST_TList, IPointer, T >;
+ friend class EST_TRwIterator< EST_TList