Using JCLists

Introduction

The JCList class is a templated doubly linked list class for use with JEWEL. It provides all of the standard things that one would want to do with lists without a lot of extra overhead or baggage found in some of the class libraries that have been looked at for the JEWEL project. In addition there is another class called JCIterator that provides a convinent way to walk forwards or backwards through a JCList.

Using JCLists

The JCList class is templated, so it are declared a little differently from most C++ variables. For instance to create a list of integers use the syntax:
JCList<int> integerlist;
As you can see the list type declared along with the list. Once a list is created you can use its methods to add, remove, and access elements in the list. The following methods are provided:
push_front() - takes one element and pushes it onto the front of the list.
               no return value.
push_back()  - takes one element and pushes it onto the back of the list.
               no return value.
pop_front()  - remove the element from the front of the list.  no return 
               value.
pop_back()   - remove the element from the back of the list.  no return 
               value.
front()      - returns a copy of the object at the front of the list.
back()       - returns a copy of the object at the front of the list.

Using JCIterators

The JCIterator class is used to traverse JCList classe). They are declared similarly to JCList classes, so to make a JCIterator of type int you would use the syntax:
JCIterator<int> integeriterator;
Once an iterator is declared you want to attach it to a list for traversal. The iterators methods are:
begin()      - takes a JCList as an argument and sets the iterator to 
               the first object in the list.
end()        - takes a JCList as an argument and sets the iterator to 
               the last object in the list.
operator==   - sees if two JCIterators are equal (refer to the same object
               in the same list).
operator++   - moves the iterator forward one object in the list.
operator--   - moves the iterator backward one object in the list.
operator*    - returns the object at the current location in the list.

Notes for G++ users

G++ is a little wierd about instianting templates. The best solution I've found has been to manually instainate them and disable implicit instantiation. To do this add -fno-implicit-templates to the C++FLAGS line in your Makeit.mk. Then in one of the C++ files for your program you should have a bunch of lines that look like:
USEJCLIST(int);
USEJCLIST(double);
This instiantes all of the classes required by the JCList class for each of the types specified. Note that if you are using DODL the following classes are already instiated:
USEJCLIST(long int);
USEJCLIST(long unsigned);
USEJCLIST(short int);
USEJCLIST(short unsigned);
USEJCLIST(double);
USEJCLIST(char *);
USEJCLIST(DObject *);

Notes for Macintosh users

Due to some compiler bugs in the Metrowerks C++ compilers JCLists are slightly different when used on the Macintosh. Basically, the begin() and end() methods in JCIterators will not work, so some friend methods have been defined to replace them. These have a very similar syntax, but are not as elegant as the methods they replace. Here are the prototypes:
template <class T> void iterator_begin(JCIterator &it, JCList &l);
template <class T> void iterator_end(JCIterator &it, JCList &l);
So code that looked like iterator.begin(list); now looks like iterater_begin(iterator, list);. These functions are also available with JCList classes on other machines, so if you need to write code that is portable to the Macintosh you should use them.

To make sure that the begin() and end() methods are not defined in the jclist.h header file you must add the line #define MACINTOSH to any lines before any lines that include jclist.h.

Example

Here is a very simple example of how lists and iterators can be used.
#include "jclist.h"

// instiante the list templates for the type int
USEJCLIST(int);

int main(int argc, char **argv) {
    // make a list of integers
    JCList<int> a;                                  
    // we have two iterators, one that we move and one that represents the
    // lists end.
    JCIterator<int> it, itend;
    
    // push some stuff onto our list
    a.push_front(1);
    a.push_front(3);
    a.push_front(6);

    // set our iterator to point at the beginning of our list
    it.begin(a);      
    // set another iterator to point at the end of the list
    itend.end(a);
    
    // while we aren't at the end of our list.
    while (it != itend) {
        printf("%i\n", *it);    // print out this item
        it++;                   // go to the next item in the list
    }
}

Questions, Comments and Bug Reports

Send any questions, comments or bugs to Alex Wetmore (alex@phred.org), or post them on the bboard academic.cs.15-499a.discuss.