Polaris: BaseIter Class Reference

BaseIter Class Reference

Iterator class that works with any Collection class. More...

#include <BaseIter.h>

List of all members.

Public Member Functions

 BaseIter ()
 BaseIter (const Collection &l, const Listable *first_elem=0, const Listable *last_elem=0, cond_proc func=0, void *extra_data=0)
 BaseIter (const Collection &l, cond_proc func, void *extra_data=0)
 BaseIter (const Collection &l, iter_option option, const Listable *first_elem=0, const Listable *last_elem=0)
BaseIteroperator= (const Collection &list)
 BaseIter (const BaseIter &other)
 This method copies the entire state (including current element) of the iterator.
BaseIteroperator= (const BaseIter &other)
 This method copies the entire state (including current element) of the iterator.
virtual ~BaseIter ()
 Destructor.
void reset ()
 Go back to the beginning of the iteration space.
void set_to_last ()
 Set the iterator to the last value Useful if you need to iterate backwards.
void next (iter_option=STOP_ON_GHOSTS)
 go to the next valid element or, if STOP_ON_GHOSTS, to the next element
void prev (iter_option=STOP_ON_GHOSTS)
 go to the previous valid element or, if STOP_ON_GHOSTS, go to the previous element
Listablecurrent ()
 Return a reference to the current element If there is no current, this results in an error.
Boolean end ()
 Return true if there no more Nodes to iterate on.
Boolean valid ()
 CC 06/29/98.
Boolean has_more_elements () const
 returns true if this is not the last element in the list CC end
Boolean current_valid () const
 Return true iff valid() would return True AND the current node is still valid.
Boolean current_invalid () const
 Equivalent to ( ! current_valid() ).
Boolean skip_ghosts () const
 are we skipping ghosts?
void * current_key () const
 This returns a pointer to the Map node which contains the key to the current element.
void modify (const Listable &el)
 replace the current element with the reference.
void modify (Listable *el)
 replace the current element with the pointer.
void modify_in_place (modify_proc mod, void *extra_data GIV(0))
 modify the current node in place.
void del ()
 delete the current element.
Listablegrab ()
 return the current element.
Assign< Listableassign ()
Listablepull ()
 assign/pull is designed to allow the functionality of modifying an element of a list to be some function of the old value of that position

Friends

class Collection


Detailed Description

Iterator class that works with any Collection class.

Note that in the following, if _last_elem_ptr comes before _first_elem_ptr in the collection, the iteration space will be empty

Declare an iterator:

    BaseIter Li = some_collection;
   
    (will iterate from the first to the last elements in the collection)
   
    --or--
   
    BaseIter Li(some_collection)
    (same as above)
   
    --or--
   
    BaseIter Li(some_collection, first_elem_ptr, last_elem_ptr);
    (will iterate from first_elem_ptr to last_elem_ptr, inclusive)
   
    --or--
   
    BaseIter Li(some_collection, cond_proc, extra_data);
    (will iterate only over those (in order) where the call
    (*cond_proc)(Li.current(), extra_data) returns non-zero)
   
    --or--
   
    BaseIter Li(some_collection, first_elem_ptr, last_elem_ptr,
    cond_proc, extra_data);
    (will iterate only over those (in order) from first_elem_ptr to
    last_elem_ptr where the call (*cond_proc)(Li.current(), extra_data)
    returns non-zero)
   
   
    Example:
   
    BaseIter Li(some_collection, first_ptr, last_ptr);
    while (!Li.end()) {    /* or use valid() */
    cout << Li.current() << ", ";
    if (f(Li.current()))
    some_collection.del(Li.current());
    Li.next();
    }
   
    Resetting the iterator to the start of the subrange:
    Li.reset()

Modifications

This implementation works with the reference counting scheme of Collections. Thus, it is not possible for an element of a Collection to be deleted out from under an iterator. It is possible, however, for the current() node to suddenly become invalid--that is for the object suddenly being made inaccessable, turning the current node into a ghost-node. It is illegal to try to access the current node if it is a ghost-node. This can be checked by calling current_valid().

Ghost nodes can only be encountered in live structures by loosing ownership of the current node, but they are more frequent in reference structures. If an object is deleted from a live structure, references to it will remain. These, too, become "ghost-nodes". By default, ghost-nodes are skipped over by the iterator. For example, all of the Iterators described above skip over ghost-nodes. However, if an iterator is declared as the default, it is still possible to check for ghost nodes within the iteration space by calling next() and prev() using the STOP_ON_GHOSTS option: next(STOP_ON_GHOSTS) --or-- prev(STOP_ON_GHOSTS)

Also, it is possible to declare an iterator which will always stop on the ghost nodes. This is done by passing a positive flag in the constructor after the name of the list. This can be done as follows:

    BaseIter Li(some_collection, STOP_ON_GHOSTS)
    (iterate over whole list including ghosts)
    --or--
   
    BaseIter Li(some_collection, STOP_ON_GHOSTS, first_elem_ptr, last_elem_ptr);
    (will iterate from first_elem_ptr to last_elem_ptr, including ghosts)

In these above forms, the increment and decrement will stop on ghost nodes. next() and prev() will still stop on ghost- nodes only if they have a STOP_ON_GHOSTS flag. The general rule is that the ++ and -- operators behave according to how the Iterator was declared, while next and prev behave according to whether they have an argument.

The iterator does not communicate with the collection which it is iterating over except in the form of indicating references. However, the Collection must adhere to some behavior rules in order for the iterators to work properly. Specifically, when an element is removed from the collection Collection::_unlink_wrapper() should be called to do the unlinking. The iterator depenends on the fact that an unlinked wrapper\'s next and prev fields are left untouched until the wrapper deletes itself (which will happen automatically when its ref count is 0). The iterator depends on these ghost-nodes maintaining their contact with the Collection.

Definition at line 136 of file BaseIter.h.


Constructor & Destructor Documentation

BaseIter::BaseIter  ) 
 

Definition at line 279 of file BaseIter.cc.

References False, and register_instance().

BaseIter::BaseIter const Collection l,
const Listable first_elem = 0,
const Listable last_elem = 0,
cond_proc  func = 0,
void *  extra_data = 0
 

BaseIter::BaseIter const Collection l,
cond_proc  func,
void *  extra_data = 0
 

BaseIter::BaseIter const Collection l,
iter_option  option,
const Listable first_elem = 0,
const Listable last_elem = 0
 

BaseIter::BaseIter const BaseIter other  ) 
 

This method copies the entire state (including current element) of the iterator.

If you don't like this, then immediately follow this constructor with a call to reset()

Definition at line 348 of file BaseIter.cc.

References register_instance().

BaseIter::~BaseIter  )  [virtual]
 

Destructor.

Definition at line 497 of file BaseIter.cc.

References Wrapper::ref_dec(), and unregister_instance().


Member Function Documentation

BaseIter & BaseIter::operator= const Collection list  ) 
 

Definition at line 334 of file BaseIter.cc.

References Wrapper::ref_dec().

BaseIter & BaseIter::operator= const BaseIter other  ) 
 

This method copies the entire state (including current element) of the iterator.

If you don't like this, then immediately follow this constructor with a call to reset()

Definition at line 76 of file BaseIter.cc.

References Wrapper::ref_dec(), and Wrapper::ref_inc().

void BaseIter::reset  ) 
 

Go back to the beginning of the iteration space.

... cur moves off its node

... mark which node cur is on

... cur moves off its node

... Find the first element that matches

Definition at line 16 of file BaseIter.cc.

References Collection::_first, next(), Wrapper::ref_dec(), Wrapper::ref_inc(), SKIP_GHOSTS, skip_ghosts(), and STOP_ON_GHOSTS.

Referenced by KeyIterator< S, T >::reset(), and Iterator< T >::reset().

void BaseIter::set_to_last  ) 
 

Set the iterator to the last value Useful if you need to iterate backwards.

... remove _cur\'s ref

... add new ref

... remove _cur\'s ref

... Find the first (backwards) element that matches

Definition at line 46 of file BaseIter.cc.

References Collection::_last, prev(), Wrapper::ref_dec(), and Wrapper::ref_inc().

Referenced by KeyIterator< S, T >::set_to_last(), and Iterator< T >::set_to_last().

void BaseIter::next iter_option  = STOP_ON_GHOSTS  ) 
 

go to the next valid element or, if STOP_ON_GHOSTS, to the next element

Referenced by KeyIterator< S, T >::operator++(), Iterator< T >::operator++(), BaseRefList::operator=(), BaseList::operator=(), Collection::print(), and reset().

void BaseIter::prev iter_option  = STOP_ON_GHOSTS  ) 
 

go to the previous valid element or, if STOP_ON_GHOSTS, go to the previous element

Referenced by KeyIterator< S, T >::operator--(), Iterator< T >::operator--(), and set_to_last().

Listable & BaseIter::current  ) 
 

Return a reference to the current element If there is no current, this results in an error.

Definition at line 490 of file BaseIter.cc.

References Wrapper::object().

Referenced by Iterator< T >::current(), KeyIterator< S, T >::current_data(), BaseRefList::operator=(), BaseList::operator=(), and Collection::print().

Boolean BaseIter::end  ) 
 

Return true if there no more Nodes to iterate on.

Definition at line 238 of file BaseIter.cc.

Referenced by KeyIterator< S, T >::end(), and Iterator< T >::end().

Boolean BaseIter::valid  ) 
 

CC 06/29/98.

Definition at line 246 of file BaseIter.cc.

Referenced by BaseRefList::operator=(), BaseList::operator=(), Collection::print(), KeyIterator< S, T >::valid(), and Iterator< T >::valid().

Boolean BaseIter::has_more_elements  )  const [inline]
 

returns true if this is not the last element in the list CC end

Definition at line 336 of file BaseIter.h.

Boolean BaseIter::current_valid  )  const [inline]
 

Return true iff valid() would return True AND the current node is still valid.

This function will return False even if valid() returns True if the current node is invalid, which will happen if the current node has become a ghost node by being deleted from its Collection. In the event that the current node is invalid, it is a checked run-time error to make a call to current(). However, the valid() method still returns True since the end of the iteration space has not yet been reached. Also, the operator prev()/next() methods will all work correctly and properly find the next element in the iteration space. If there is any chance that the current element pointed to by a BaseIter can be deleted, both valid() and current_valid() must return True for a call to current() to be acceptable.

Definition at line 323 of file BaseIter.h.

References ProtoWrapper::valid().

Referenced by KeyIterator< S, T >::current_valid(), Iterator< T >::current_valid(), BaseList::operator=(), and Collection::print().

Boolean BaseIter::current_invalid  )  const [inline]
 

Equivalent to ( ! current_valid() ).

Definition at line 329 of file BaseIter.h.

References ProtoWrapper::valid().

Referenced by KeyIterator< S, T >::current_invalid(), and Iterator< T >::current_invalid().

Boolean BaseIter::skip_ghosts  )  const
 

are we skipping ghosts?

Definition at line 586 of file BaseIter.cc.

Referenced by KeyIterator< S, T >::operator++(), Iterator< T >::operator++(), KeyIterator< S, T >::operator--(), Iterator< T >::operator--(), and reset().

void * BaseIter::current_key  )  const
 

This returns a pointer to the Map node which contains the key to the current element.

This is ILLEGAL unless iterating over KeyWrappers.

Definition at line 592 of file BaseIter.cc.

References Wrapper::key_node().

Referenced by KeyIterator< S, T >::current_key().

void BaseIter::modify const Listable el  ) 
 

replace the current element with the reference.

Definition at line 602 of file BaseIter.cc.

References Wrapper::is_live_wrapper(), and Wrapper::object().

Referenced by Mutator< T >::modify(), Iterator< T >::modify(), and BaseList::operator=().

void BaseIter::modify Listable el  ) 
 

replace the current element with the pointer.

Definition at line 613 of file BaseIter.cc.

References Wrapper::is_live_wrapper(), and Wrapper::object().

void BaseIter::modify_in_place modify_proc  mod,
void *extra_data   GIV(0)
 

modify the current node in place.

Definition at line 624 of file BaseIter.cc.

References Wrapper::is_live_wrapper(), and ProtoWrapper::valid().

Referenced by Mutator< T >::modify_in_place(), and Iterator< T >::modify_in_place().

void BaseIter::del  ) 
 

delete the current element.

... Unlink first, since we can guarantee the object has a reference

Definition at line 639 of file BaseIter.cc.

References Wrapper::delete_object(), and Collection::static_size().

Referenced by Mutator< T >::del(), and Iterator< T >::del().

Listable * BaseIter::grab  ) 
 

return the current element.

... if static, leave linked

Definition at line 653 of file BaseIter.cc.

References Wrapper::is_live_wrapper(), Wrapper::object(), Collection::static_size(), and ProtoWrapper::valid().

Referenced by Mutator< T >::grab(), and Iterator< T >::grab().

Assign< Listable > BaseIter::assign  ) 
 

Definition at line 696 of file BaseIter.cc.

References Wrapper::object(), and ProtoWrapper::object_address().

Referenced by Mutator< T >::assign(), and Iterator< T >::assign().

Listable * BaseIter::pull  ) 
 

assign/pull is designed to allow the functionality of modifying an element of a list to be some function of the old value of that position

In, general: pull() is used to release control of an object without losing its position in the list, assign() is used to give control back to the list.

The 'pull' method removes the specified object from its list (like grab) but maintains it's 'place' in the list. Once an object has been pulled, it is no longer possible to access the List using the pulled object as a reference. Once an object has been pulled it can be modified in any way. Once the modification is complete, the object can be returned to its position in the list using the 'assign' method. The user, however, is responsible for garbage collecting any intermediate forms of the pulled object which may be created. A complete use would be as follows:

Assign<Expression> a = iter.assign(); a = function(iter.pull());

'function' is simply a funtion which returns the modified value. If the modified value is a different object than the original, function is responsible for garbage collecting the original. In this case, the specified object is pulled from the list, modified somehow by function and the returned value takes it's place in the list.

"assign" MUST be called in a statement prior to the call to pull()

These functions approximate the functionality of the late modify_in_place. *

Definition at line 676 of file BaseIter.cc.

References Wrapper::is_live_wrapper(), Wrapper::object(), Listable::pulled(), and ProtoWrapper::valid().

Referenced by Mutator< T >::pull(), and Iterator< T >::pull().


Friends And Related Function Documentation

friend class Collection [friend]
 

Definition at line 137 of file BaseIter.h.


The documentation for this class was generated from the following files:
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:58 2005