Today I want to finish discussion of the STL list implementation and then talk about stacks, queues, and dequeues. I'll take the midterm project, which will go out by this Wednesday, as the midterm grade. This will be due on next Friday. It'll be the MOO object model, a simple inspector, a simple command interface and interpreter. To review, there are a number of list functions. These are given in the slide. There are an abundance of iterators for lists, and the idea being that we have more flexibility in terms of what "copying" means because of the architecture of lists. So for example int threeToOne [] = {3,2,1}; int fourToSix [] = {4,5,6}; int sevenToNine [] = {7,8,9}; list::iterator seven = find (aList.begin(), aList.edn(), 7); copy (fourToSix, fourToSix+3, inserter(aList, sevent); Function objects capture the notion of higher order functions. The idea is that you're really using the notion of object as closure to pass anonymous functions. One possibility is given by the widget example in the book. Another example, suppose we have an email application and want to write a member function, compact, that takes a descriptor of size and goes through a mailbox, compressing all messages longer than a particular size limit. (slide) I'll go over some final points about the implementation of lists. Lists, stl or not, are usually implemented using a facilitator structure or class. Typically the link. To refer back to Friday's lecture, the last link and first link here correspond to the pointers to the front and back of the list. Links are just storage plus the links to previous and next value. Remember that STL implements a doubly linked list. In traversing the list, size for example, all that we need to do is keep incrementing pointers. In this case, start at the head of the list and increment until the end of the list is reached. You can imagine doing the automatically as destructive operations are performed. Iterators are also straightforwardly implemented. Again, just as pointers. Stacks are first in first out structures. The idea being that objects are successively added to the front of a stack using the operation PUSH, and then are taken off the stack in reverse order using the POP operation. Using a stack, we can implement the notion of nested function call. For example, consider some program that's just been started, Program A. When we call A, space is allocated on the stack for A's activation record -- local variables and other parameters. A's instructions are executed until there is a call to B, which allocatates more space on the stack for B's activation record. When B is finished, it's activation record is popped from the stack and then we proceed with the next instruction in A. One use of the stack is in evaluating nested expressions. You'll see this in the simple expression evaluator that you'll develop to interpret MUD expressions. Basically the MUD evaluates things from two places. Command line expressions are pretty simple verb (or command) verb direct-object (e.g. open door) verb direct-object prep indirect-object (e.g. give flower to smiley) But we want users to be able to write their own commands to do stuff. for x in (players()) "Grendel's mama's so ugly that..." player:tell(x.name, "(", x, ")"); endfor We can start simple with arithmetic expressions 3 + 4 Simpler as RPN (see the book for details about converting from infix to RPN form) 3 4 + So both 3 and 4 get pushed onto the stack, and then when the + is encountered, we pop off two arguments and evaluate. We can use a similar approach to check the parenthesizing of an expression. For example, in the above expression, once we've read the expression in, we can use a stack to make sure that all the expressions are properly parenthesized. Queues. Implement the notion of waiting around for input. They are implemented in terms of the simpler container classes. e.g. stack < vector > stack_one; stack < list > stack_two; stack < dequeue > stack_three; Dequeues Insertion at both ends. There are many possible implementations. The one approach discussed in the book is to use two vectors to implement it. An application is round robin scheduling.