Boost logo

Boost-Commit :

From: chintanraoh_at_[hidden]
Date: 2008-07-05 02:38:52


Author: chintanraoh
Date: 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
New Revision: 47088
URL: http://svn.boost.org/trac/boost/changeset/47088

Log:
finished documentation for trie and patricia
Text files modified:
   sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/node_cursor.hpp | 96 +++++++++++++++++++++-
   sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp | 2
   sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia_iterator.hpp | 2
   sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie.hpp | 165 +++++++++++++++++++++++++++++++++------
   sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_array_node.hpp | 111 +++++++++++++++++++++++---
   sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_iterator.hpp | 125 ++++++++++++++++++++++++++---
   6 files changed, 435 insertions(+), 66 deletions(-)

Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/node_cursor.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/node_cursor.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/node_cursor.hpp 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
@@ -9,14 +9,23 @@
 namespace boost {
 namespace dsearch {
         using boost::tree::cursor_facade;
- template<class Key,class Mapped,class Node>
- class trie_cursor:public cursor_facade<trie_cursor<Key,Mapped,Node>,Node,
+
+///cursor poiting to the node.
+/**
+ \param Key is trie::key_type
+ \param Mapped is trie::data_type
+ \param Node is the type of node to be used.
+ */
+template<class Key,class Mapped,class Node>
+class trie_cursor:public cursor_facade<trie_cursor<Key,Mapped,Node>,Node,
                                 forward_traversal_tag,
                                 bidirectional_traversal_tag>
 
 {
         private:
+ /// cursor
         typedef trie_cursor<Key,Mapped,Node> cursor;
+ /// element_type as spefied in the key_traits
         typedef typename Node::element_type element_type;
 
         friend class boost::iterator_core_access;
@@ -24,22 +33,37 @@
         template<class K,class M,template<class K1,class M1,class K_t1,class A1 > class t_n,class K_t,class A >
         friend class trie;
         template<class K,class M,class N> friend class trie_cursor;
+
+ /// helps in avoiding conversion of const_cursor to cursor.
         struct enabler {};
+
+ ///if Node is const the node_iterator is const_iterator otherwise its
+ ///just iterator.
         typedef typename mpl::eval_if<is_const<Node>, typename Node::const_iterator,
- typename Node::iterator>::type node_iterator;
+ typename Node::iterator>::type node_iterator;
 
+ /// if the cursor points to root. then only root is set.
         unsigned char only_root;
+ /// for specifying the imaginary node above root
         bool top;
+ /// position of the child in cur. (cur,pos) specfies the child node
+ /// ie the node which cursor points to.
         node_iterator pos;
+ /// usually the parent of the node which cursor points to.
         Node *cur;
 
 
 
         public:
+ /// Default constructor.
         trie_cursor():only_root(0),top(0),cur(0)
         {
         }
 
+ /// copy constructer
+ /**
+ \param other is the cursor to be copied
+ */
         template<class K,class M,class N>
         trie_cursor( trie_cursor<K,M,N> const& other,
                                 typename enable_if< is_convertible<N*,Node*>,
@@ -52,11 +76,20 @@
                 this->cur=other.cur;
         }
 
+ ///specific the cursor using the root.
+ /**
+ \param n_ptr is the pointer to the root.
+ */
         trie_cursor(Node * const &n_ptr): only_root(1) , top(false)
         {
                 cur=n_ptr;
         }
 
+ ///construct the node usin node pointer and iterator.
+ /**
+ \param n_ptr pointer to the node.
+ \param it: is the node iterator in the child.
+ */
         trie_cursor(Node* const &n_ptr,const node_iterator &it): only_root(0), top(false)
         {
                 cur=(n_ptr);
@@ -65,6 +98,7 @@
 
         private:
 
+ ///for cursor::begin()
         cursor left() const
         {
                 if(top)
@@ -76,6 +110,7 @@
                 return cursor(*pos,(*pos)->begin());
         }
 
+ ///for cursor::end()
         cursor right() const
         {
                 if(top)
@@ -85,6 +120,7 @@
                 return cursor(*pos,(*pos)->end());
         }
 
+ /// decrement the cursor.
         void decrement()
         {
                 if(only_root)
@@ -93,16 +129,25 @@
                         pos--;
         }
 
+ /// check whether the particular node is leaf node or not.
         bool empty_() const
         {
                 return get_node()->empty();
         }
 
+ /// dereference the node
+ /**
+ \returns reference to the Node
+ */
         Node &dereference() const
         {
                 return *get_node();
         }
 
+ /// get the current node.
+ /**
+ \returns the pointer to current node.
+ */
         Node *get_node() const
         {
                 if(only_root)
@@ -110,6 +155,10 @@
                 return *pos;
         }
 
+ /// get the current node.
+ /**
+ \returns the pointer to current node.
+ */
         Node *get_node()
         {
                 if(only_root)
@@ -117,14 +166,18 @@
                 return *pos;
         }
         
- //returns const_iterator for const_cursor :(
- //used by trie erase function
+ ///get the iterator pointing to the node.
+ /**
+ \warning returns const_iterator for const_cursor
+ \note used by trie erase function
+ */
         node_iterator get_iterator() const
         {
                 assert(!only_root);
                 return pos;
         }
 
+ ///increment the cursor.
         void increment()
         {
                 if(only_root)
@@ -133,6 +186,13 @@
                         pos++;
         }
 
+ /// used to check whether two cursors are equal.
+ /**
+ \returns true if the are equyal false otherwise
+ \param other is other cursor whose equality with cursor needs to be
+ checked
+
+ */
         template<class K,class M,class N>
         bool equal(trie_cursor<K,M,N> const& other) const
         {
@@ -156,24 +216,44 @@
         }
 
         public:
+
+ /// check whether node has a value. ie end of an insert key.
+ /**
+ \returns true is it the end of an inserted key.
+ */
         bool has_value() const
         {
                 return get_node()->has_value();
         }
 
- //const because dereference is const
+
+ /// get value at the particular node. Should have a value.
+ /**
+ \returns reference to the value.
+ \note const because dereference is const.
+ \warning should not be called when has_value is false.
+ */
         Mapped &get_value() const
         {
                 return get_node()->get_value_ref();
         }
         
+ /// get element of the edge which points to the node.
+ /**
+ \returns the element.
+ */
         element_type get_element() const
         {
                 assert(!only_root && !top);
                 return cur->get_element(pos);
         }
-
- //const_cast here? trouble is only with const_cursor as get_node()=*pos = const Node *:(.
+
+ ///find the cursor corresponding to the element
+ /**
+ \returns cursor pointed to be edge specified by e
+ \param e is the egde for which cursor is to be found
+ \note const_cast here? trouble is only with const_cursor as get_node()=*pos = const Node *:(.
+ */
         cursor find(const element_type &e) const
         {
                 return cursor(this->get_node(),get_node()->find(e));

Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
@@ -22,7 +22,7 @@
 namespace boost{
 namespace dsearch{
 
-/// The pactrica class
+/// The patricia class
 /** \ingroup group_nothing
     \param Key key currently accepts a string only.
     \param Mapped can be any datatype which is supposed to be indexed using string

Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia_iterator.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia_iterator.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia_iterator.hpp 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
@@ -20,7 +20,7 @@
 {
         template<class K,class M,class K_t,class A > friend class patricia;
         protected:
- ///empty struct used for conversion from const_iterator to iterator
+ ///empty struct used for avoiding conversion from const_iterator to iterator
         struct enabler {};
         friend class boost::iterator_core_access;
         ///Pointer to prev node . usually cur->left or cur->right ==next

Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie.hpp 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
@@ -325,7 +325,7 @@
          */
         std::pair<const_iterator,const_iterator> prefix_range(const key_type &key) const
         {
- return const_cast<type *>(this)->prefix_range(key);
+ return const_cast<type *>(this)->prefix_range(key);
                 //return prefix_range<const_iterator,const_cursor,const type*>(this,key);
         }
 
@@ -336,13 +336,15 @@
          */
         std::pair<iterator,iterator> prefix_range(const key_type &key)
         {
- prefix_range<iterator,cursor,type*>(this,key);
+ return prefix_range<iterator,cursor,type*>(this,key);
+#if 0
                 typename Key_traits::const_iterator it=Key_traits::begin(key),
                                 end_it=Key_traits::end(key);
                 iterator ret_it,right;
                 cursor cur,next;
                 cur=root();
                 ret_it.push(cur);
+ //* find where the leaf is.
                 while(it!=end_it)
                 {
                         if(cur.empty()) return std::make_pair(end(),end());
@@ -353,39 +355,59 @@
                         ret_it.push(cur);
                         it++;
                 }
+
                 right=ret_it;
+ //* and left most from the leaf.
                 ret_it.to_left_most();
+ //* move right most from the leaf.
                 right.to_right_most();
+ //* since we want right range not to be closed we increment right
+ //* before returning.
                 return std::make_pair(ret_it,++right);
+#endif
+
         }
 
         ///clears the trie.
         void clear()
         {
                 typedef typename node_type::iterator node_it;
+ //* store the node and node iterator in a stack.
                 std::stack< std::pair<node_type*,node_it> > node_stack;
                 int size=1;
+
+ //* push root and its begin()
                 node_stack.push(std::make_pair(node_root,node_root->begin()));
                 while(1)
- {
+ {
+ //* if the iterator has reached the end we will need to pop
+ //* and goto to the next sub tree.
                         if(node_stack.top().first->end()==node_stack.top().second)
                         {
+ //* if size of 1 we have done every thing :)
                                 if(size==1) break;
                                 node_allocator.destroy(node_stack.top().first);
                                 node_allocator.deallocate(node_stack.top().first,1);
+ //* pop the current sub tree.
                                 node_stack.pop();
                                 size--;
+ //* move to the next subtree.
                                 node_stack.top().second++;
                                 continue;
                         }
+ //* arrange for a new node.
                         node_stack.push( std::make_pair(*(node_stack.top().second)
                         ,(*(node_stack.top().second))->begin()) );
                         size++;
                 }
                 node_stack.pop();
+ //* we have not yet deallocated root.
+ //* clean up root.
                 node_allocator.destroy(node_root);
                 node_allocator.deallocate(node_root,1);
                 node_root=node_allocator.allocate(1);
+
+ //* and allocate a new one.
                 new(node_root) node_type();
         }
         
@@ -397,25 +419,30 @@
         void erase(const iterator &it)
         {
                 iterator iter=it;
- node_type *n_t;
                 cursor cur_it;
                 typename node_type::iterator node_it;
+
+ //* check whether the iterator points to a leaf node
                 if ( iter.top().begin()==iter.top().end() )
                 {
+ //* iter.size() refers to size of the iterator's stack.
+ //* since there is no parent for the root node it does not
+ //* have a corresponding iterator.
                         if(iter.size()!=1)
                                 node_it=iter.top().get_iterator();
- node_allocator.destroy( n_t = iter.top().get_node() );
+
+ node_allocator.destroy( iter.top().get_node() );
                         node_allocator.deallocate( iter.top().get_node() , 1 );
                         iter.pop();
                 }
                 else
                 {
+ //*if it does not point to a leaf node just erase the data and return
                         iter.top().get_node()->erase_value();
                         return;
                 }
 
- if ( iter.empty() )
- if( iter.empty() ) //deallocated the root node so reallocate it.
+ if ( iter.empty() )//*deallocated the root node so reallocate it.
                 {
                         node_root=node_allocator.allocate(1);
                         new(node_root) node_type();
@@ -423,22 +450,28 @@
                 }
                         
                 cur_it=iter.top().begin();
+ //*if (++cur_it)==iter.top().end() then its only child has been erased.
                 while( (++cur_it)==iter.top().end() )
                 {
+ //* iter.size() refers to size of the iterator's stack.
+ //* since there is no parent for the root node it does not
+ //* have a corresponding iterator.
                         if(iter.size()!=1)
                                 node_it=iter.top().get_iterator();
- node_allocator.destroy ( n_t = iter.top().get_node() );
+ //* deallocate the node.
+ node_allocator.destroy ( iter.top().get_node() );
                         node_allocator.deallocate ( iter.top().get_node() , 1 );
                         iter.pop();
                         
- if( iter.empty() ) //deallocated the root node so reallocate it.
+ //* deallocated the root node so reallocate it.
+ if( iter.empty() )
                         {
                                 node_root=node_allocator.allocate(1);
                                 new(node_root) node_type();
                                 return;
                         }
 
-
+ //* if a particular node has value then break then and there.
                         if(iter.top().has_value())
                                 break;
                         cur_it=iter.top().begin();
@@ -574,7 +607,9 @@
         {
                 int num=0;
                 iterator it,end_it=this->end();
+ //* just iterate and find out no of elements.
                 for(it=this->begin();it!=end_it;it++,num++);
+
                 return num;
         }
         
@@ -587,30 +622,35 @@
         {
                 typename Key_traits::const_iterator it=Key_traits::begin(key),
                         end_it=Key_traits::end(key);
- node_type *cur=node_root,*next;
+ node_type *cur=node_root, *next;
                 typename node_type::iterator fit;
- int i=0;
- while(it!=end_it)
+
+ //*go as far as one can.
+ while ( it!=end_it )
                 {
- fit=cur->find(*it);
- if(fit==cur->end())
+ //*find the current char in the node.
+ fit=cur->find( *it );
+ //*if not found go out of the loop.
+ if ( fit == cur->end() )
                                 break;
+ //*change cur to pointer of the new node.
                         cur=*fit;
                         it++;
- assert(i!=10);
+
                 }
- i=0;
+
+ //*allocate nodes untill the end of the string.
                 while(it!=end_it)
                 {
- i++;
                         next=node_allocator.allocate(1);
                         //std::cout<<"Allocating:"<<*it<<std::endl;
                         new(next) node_type();
+ //*insert the char in to new node along with pointer to next node.
                         cur->insert(*it,next);
                         cur=next;
- assert(i!=10);
                         it++;
                 }
+ //*return the pointer to the leaf node.
                 return cur;
         }
 
@@ -620,23 +660,26 @@
          \param key is the key whose existance in the trie us supposed to be
          determined
          */
- bool exist(const key_type &key) const //make this iterator instead of bool;
+ bool exist(const key_type &key) const
         {
                 typename Key_traits::const_iterator it=Key_traits::begin(key),
                                         end_it=Key_traits::end(key);
                 typename node_type::iterator fit;
                 node_type *cur=node_root;
+
+ //* for each element in the key find the corresponding node pointer
+ //* and move the the node.
                 while(!(it==end_it))
                 {
                         fit=cur->find(*it);
- if(fit == cur->end() ) return false;
+ if ( fit == cur->end() ) return false;
                         cur=*fit;
                         it++;
                 }
+ //* if the "leaf" has the a value return true.
                 if(cur->has_value())
- {
                         return true;
- }
+ //* else
                 return false;
         }
         ///copy the trie preserving the internal structure of the node
@@ -647,15 +690,22 @@
         {
                 node_type *prev,*temp_node;
                 typedef typename node_type::iterator node_iterator;
+ //* stack to maintain the list of iterators for the other root.
                 std::stack<node_iterator> st;
+ //* stack to maintain the list of iterators.
                 std::stack<node_iterator> this_st;
+ //* maintain iterators for other root.
                 node_iterator cur_it=other_root->begin();
 
+ //* allocate the root node
                 node_root=node_allocator.allocate(1);
                 node_allocator.construct(node_root,*other_root);
                 
+ //* if the other root is empty return
                 if ( other_root->end() == other_root->begin() )
                         return;
+
+ //* push root on to the stack
                 this_st.push(node_root->begin());
 
                 while(true)
@@ -668,20 +718,34 @@
                         if( cur_it == prev->end() )
                         {
                                 if(st.empty()) return;
+
+ //* change cur_it
                                 cur_it=++st.top();
+ //* pop to change top.
                                 st.pop();
+
+ //* do the same (nearly) to other stack too.
                                 this_st.pop();
                                 ++this_st.top();
                                 continue;
                         }
 
+ //* assign new node.
                         temp_node=node_allocator.allocate(1);
+
+ //* call the copy constructor of the new node.
+ //* this helps in preserving the internal node structure.
                         node_allocator.construct( temp_node , **cur_it );
+
+ //* put the pointer of new node on the parent outward edge
                         *(this_st.top())=temp_node;
 
+ //* push the begin of new node on to the stack.
                         this_st.push(temp_node->begin());
+
+ //* push the cur_it on to the stack and move move one to new it.
                         st.push(cur_it);
-
+
                         cur_it=(*cur_it)->begin();
                 }
         }
@@ -698,19 +762,27 @@
         {
                 typename Key_traits::const_iterator it=Key_traits::begin(key),
                                 end_it=Key_traits::end(key);
+
+ //* iterator is a stack of cursors
                 It_type ret_it;
                 Cur_type cur,next;
                 cur=this_ptr->root();
+ //* goto the leaf of the key.
                 while(!(it==end_it))
                 {
+ //* push the current iterator on to the stack.
                         ret_it.push(cur);
+ //* find the particular charecter in the node.
                         next=cur.find(*it);
+ //* if not found return null.
                         if ( next == cur.end() )
                                 return this_ptr->end();
                         cur=next;
                         it++;
                 }
+
                 ret_it.push(cur);
+ //* if leaf has value return ret_it.
                 if(cur.has_value())
                 {
                         return ret_it;
@@ -727,6 +799,8 @@
         {
                 typename node_type::iterator it=node->begin(),eit=node->end();
                 typename node_type::iterator ret_it=eit;
+
+ //* linear iteration to find where the lower bound is.
                 while(it!=eit)
                 {
                         if( node->get_element(it) > ele)
@@ -755,13 +829,18 @@
                 cur=r;
                 ret_it.push(cur);
                 //std::cout<<"CONST UPPER BOUND"<<std::endl;
+
+ //go as far as possible with the key.
                 while(it!=end_it)
                 {
                         if(cur.empty())
                         {
+ //* if the cur is empty then prefix of the key is there in the trie
+ //* so goto the iterator adjacent to prefix
                                 ret_it++;
                                 return ret_it;
                         }
+ //* the usual find procedure.
                         next=cur.find(*it);
                         if ( next == cur.end() )
                         {
@@ -773,15 +852,28 @@
                         ret_it.push(cur);
                         it++;
                 }
+
+ //* if the entire key is not found
                 if( not_found )
                 {
+ //* if find the lower bound in the last node we could atmost reach.
                         next=Cur_type(cur.get_node(),lower_bound(cur.get_node(),*it));
                         //next=Cur_type(cur.get_node(),const_cast<node_type *>(cur.get_node())->lower_bound(*it));
                         
                         if(next==ret_it.top().end())
+ {
+ //* if there is no lower bound we position the cursor at begin.
                                 next=Cur_type ( cur.get_node(), cur.get_node()->begin());
+ }
                         else
+ {
+ //* if else we just need increment the cursor.
+ //* because the upper bound is adjacent to the lower bound.
                                 next++;
+ }
+
+ //* next++ could have positoned the cursor at the end.
+ //* so pop untill next++ does not position at the end.
                         while(next==ret_it.top().end())
                         {
                                 //std::cout<<"popping "<<std::endl;
@@ -793,7 +885,9 @@
                         }
                         ret_it.push(next);
                 }
- ret_it.to_left_most(); //if ret_it.top().hash_value() then this does nothing
+ //* move the iterator to the left most from the current position.
+ //* if ret_it.top().has_value() then this does nothing
+ ret_it.to_left_most();
                 return ret_it;
         }
 
@@ -816,11 +910,13 @@
                 cur=r;
                 ret_it.push(cur);
                 //std::cout<<"LOWER BOUND"<<std::endl;
+ //* try to find the key in the trie
                 while(it!=end_it)
                 {
                         if(cur.empty())
                                 break;
                         //std::cout<<"finding "<<*it<<std::endl;
+ //* find the next cursor
                         next=cur.find(*it);
                         if ( next == cur.end() )
                         {
@@ -833,13 +929,20 @@
                         it++;
                 }
 
+ //* if the entire key is not found
                 if(not_found)
                 {
+ //* then find the lower bound of the element which is not found the node.
+ //* then make cursor out of it.
                         next=Cur_type(cur.get_node(),lower_bound(cur.get_node(),*it));
                         //next=Cur_type(cur.get_node(),const_cast<node_type *>(cur.get_node())->lower_bound(*it));
+
+ //* if lower bound is found we have no problems :).
                         if(next!=cur.end())
                         {
                                 ret_it.push(next);
+ //* move the right most in the subtree.
+ //* ie the greatest element/
                                 ret_it.to_right_most();
                                 return ret_it;
                         }
@@ -847,6 +950,7 @@
 
                 do
                 {
+ //* else pop until --next!= end() or next has value
                         next=ret_it.top();
                         ret_it.pop();
                         if(next.has_value())
@@ -863,9 +967,11 @@
 
                 next--;
                 ret_it.push(next);
+ //* move to highest key in the subtree.
                 ret_it.to_right_most();
                 return ret_it;
         }
+
 
         ///find the prefix_range of the key
         /**
@@ -883,23 +989,26 @@
                 Cur_type cur,next;
                 cur=this_ptr->root();
                 ret_it.push(cur);
+ //* as usual try to find the prefix in the trie.
                 while(it!=end_it)
                 {
                         if(cur.empty()) return std::make_pair(this_ptr->end(),this_ptr->end());
                         next=cur.find(*it);
+
+ //* if not found return end() pairs
                         if(cur.end()==next)
                                 return std::make_pair(this_ptr->end(),this_ptr->end());
- //std::cout<<"LOOK AT ME:"<<*it<<std::endl;
+
                         cur=next;
                         ret_it.push(cur);
                         it++;
                 }
                 right=ret_it;
- //std::cout<<"To LEFT MOST"<<std::endl;
+ //* if prefix is found move to left most and right most.
                 ret_it.to_left_most();
                 //std::cout<<"To RIGHT MOST"<<std::endl;
                 right.to_right_most();
- //std::cout<<"pair range "<<*right<<std::endl;
+ //std::cout<<"pair range "<<*right<<std::endl;
                 return std::make_pair(ret_it,++right);
         }
 

Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_array_node.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_array_node.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_array_node.hpp 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
@@ -16,6 +16,10 @@
 namespace boost{
 namespace dsearch{
 
+/// iterator for trie array node.
+/**
+ \param trie_type is the type of trie node used.
+ */
 template <typename trie_type>
 class trie_array_node_iterator
 :public iterator_facade<trie_array_node_iterator<trie_type>,trie_type *,boost::bidirectional_traversal_tag>
@@ -23,33 +27,43 @@
         private:
         friend class boost::iterator_core_access;
         template<class Trie_t> friend class trie_array_node_iterator;
-
         template<class K,class M,class Ke,class Allocator> friend class trie_array_node;
 
+ /// helps in avoiding conversion of const_iterator to iterator.
         struct enabler {};
 
+ /// pointer to the child array.
         trie_type** child_ptr;
+ /// pos is the position in the child array.
         std::size_t pos;
 
         public:
+ ///Self
         typedef trie_array_node_iterator<trie_type> type;
+
+ /// Default constructor
         trie_array_node_iterator()
         :child_ptr(0), pos(0){}
 
+ /// Intialize a iterator from the node. ie begin().
         trie_array_node_iterator(trie_type*node)
         {
                 child_ptr=(trie_type**)(node->child_ptr);
                 int i=0;
+ //* find the first non zero position in the node.
                 for(i=0;i<trie_type::max;i++)
                         if(child_ptr[i]!=0) break;
                 pos=i;
         }
 
+ /// Intialize the iterator to a particular position.
         trie_array_node_iterator(trie_type *node,int p):pos(p)
         {
                 child_ptr=(trie_type**)node->child_ptr;
         }
         private:
+
+ /// Used to check whether two iterators are equal.
         template<class Trie_t>
         bool equal( trie_array_node_iterator<Trie_t> const &other ) const
         {
@@ -58,60 +72,90 @@
                 return false;
         }
 
+ /// increment the iterator.
         void increment()
         {
+ //* check for the next non zero entry.
                 for(pos++; pos<trie_type::max; pos++)
                         if(child_ptr[pos]!=0) break;
         }
 
+ /// decrement the iterator.
         void decrement()
         {
                 for(pos--; pos>0; pos--)
                         if(child_ptr[pos]!=0) break;
         }
 
+ /// dereference the iterator
         trie_type *&dereference() const
         {
                 return child_ptr[pos];
         }
 
         public:
+ ///copy constructor
+ /**
+ \param other is the iterator to be copied
+ */
         template<class Trie_t>
         trie_array_node_iterator(const trie_array_node_iterator<Trie_t> &other,
                         typename enable_if< is_convertible<Trie_t*,trie_type*>,
                         enabler >::type = enabler()
                      )
         {
- child_ptr=(trie_type **)(other.child_ptr);//converting from x* to const x*
+ //* converting from x* to const x*
+ child_ptr=(trie_type **)(other.child_ptr);
                 pos=other.pos;
         }
 };
 
-//TODO:const_cast (if safe) at other places to avoid duplication. Remove const functions here.
+/// This makes the trie class use an array for index children in every node.
+/**
+ \param Key is trie::key_type.
+ \param Mapped is trie::data_type.
+ \param Alloc is the allocator used.
+ */
 template<class Key,class Mapped,class Key_traits,class Alloc=std::allocator<char> >
 class trie_array_node
 {
         public:
+ ///Self
         typedef trie_array_node<Key,Mapped,Key_traits,Alloc> type;
         template<class T> friend class trie_array_node_iterator;
 
         private:
+ /// An array of children indexed by the element_type.
         type* child_ptr[Key_traits::max+1];
         //typedef typename Alloc::template rebind<node_type>::other node_allocator_type;
 
         public:
+ /// Element_type is type of each element in the key.
         typedef typename Key_traits::element_type element_type;
+
+ /// iterator for the array node. Should iterate in increasing order or
+ /// decreasing order of elements.
         typedef trie_array_node_iterator<type> iterator;
+
+ /// iterator for the array node. Should iterate in increasing order or
+ /// decreasing order of elements.
         typedef trie_array_node_iterator<const type> const_iterator;
+
+ /// element_type is the key_type of trie_array node
         typedef element_type key_type;
+
+ /// type* is the value type.
         typedef type* value_type;
 
+ /// stored the value of the array in a pointer
         Mapped *value_ptr;
 
+ /// maximum value of element_type
         enum{
                 max=Key_traits::max
         };
 
+ /// Default constructor
         trie_array_node()
         {
 // std::cout<<"here"<<std::endl;
@@ -119,6 +163,7 @@
                 value_ptr=0;
         }
 
+ /// Copy constructor
         trie_array_node(const type &other)
         {
                 if(other.value_ptr!=0)
@@ -131,13 +176,23 @@
                 assert( memcpy(child_ptr, other.child_ptr, sizeof(child_ptr) ) == child_ptr);
         }
 
- void insert(const element_type &key,type * const &child_cursor)
+ /// insert a new child corresponding to the key.
+ /**
+ \param key element_type specifying the edge to the child.
+ \param child is the pointer to the child.
+ */
+ void insert(const element_type &key,type * const &child)
         {
- child_ptr[Key_traits::get_value(key)]=child_cursor;
+ child_ptr[Key_traits::get_value(key)]=child;
         }
 
 
- //*iterator should give reference to the value Mapped to by key;
+
+ // *iterator should give reference to the value Mapped to by key;
+ /// find a particular key in trie_array_node
+ /**
+ \param key for which the iterator is to be found.
+ */
         iterator find(const element_type &key)
         {
                 if(child_ptr[Key_traits::get_value(key)]==0)
@@ -155,11 +210,16 @@
                         return const_iterator(this,Key_traits::get_value(key));
         }*/
 
+ /// erase value correspoding the iterator.
         void erase(const iterator&it)
         {
                 child_ptr[it.pos]=0;
         }
 
+ /// returns an iterator which shows the elements in sorted order.
+ /**
+ \returns iterator pointing to the least element.
+ */
         iterator begin()
         {
                 return iterator(this);
@@ -170,6 +230,10 @@
                 return const_iterator(this);
         }*/
 
+ /// returns an iterator which shows the elements in sorted order.
+ /**
+ \returns iterator pointing to the greatest element.
+ */
         iterator end()
         {
                 return iterator(this,max);
@@ -180,7 +244,14 @@
                 return const_iterator(this,max);
         }*/
 
- //called only from insert function and trie::iterator
+ /// get reference to value stored
+ /**
+ \brief if has_value is false, assign default to value and return reference
+ to value.
+ Called only by insert and operator []
+ \note This function should be const
+ */
+
         Mapped &get_value_ref()
         {
                 if(value_ptr==0)
@@ -188,18 +259,28 @@
                 return *value_ptr;
         }
 
- //called to get const reference fron const_* iterators and cursors
+ /// get reference to value stored
+ /**
+ \note This function should be const.
+ */
         Mapped &get_value_ref() const
         {
                 return *value_ptr;
         }
 
+ ///erase value from trie_array_node
+ /**
+ */
         void erase_value()
         {
                 delete value_ptr;
                 value_ptr=0;
         }
 
+ /// check whether this node has value or not.
+ /**
+ \returns true if node has a value stored. false otherwise.
+ */
         bool has_value() const
         {
                 return value_ptr!=0;
@@ -214,11 +295,6 @@
                 return t_size;
         }*/
 
- element_type get_element(const iterator &it)
- {
- return Key_traits::get_element(it.pos);
- }
-
 /* iterator lower_bound(const element_type &e)
         {
                 int k=Key_traits::get_value(e);
@@ -228,6 +304,10 @@
                 return iterator(this,k);
         }*/
 
+ /// check whether the node is empty or not.
+ /**
+ \returns true if node is empty false otherwise.
+ */
         bool empty() const
         {
                 for(int i=0;i<max;i++)
@@ -236,11 +316,16 @@
                 return true;
         }
         
+ /// get element at a particular position specified by the iterator.
+ /**
+ \param it is the iterator whose element is to be got.
+ */
         element_type get_element(const_iterator it) const
         {
                 return Key_traits::get_element(it.pos);
         }
 
+ /// Class destructor
         ~trie_array_node()
         {
                 if(value_ptr!=0)

Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_iterator.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_iterator.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/trie_iterator.hpp 2008-07-05 02:38:50 EDT (Sat, 05 Jul 2008)
@@ -8,11 +8,18 @@
 #include<boost/type_traits/is_convertible.hpp>
 #include<boost/utility/enable_if.hpp>
 
-//TODO:Add specializations for ascending cursors without use of stack.
 
 namespace boost{
 namespace dsearch{
 
+/// iterator class for trie
+/**
+ \brief iterator is implemented using a stack of cursor.
+ \param Key is patricia::key_type
+ \param Mapped is patricia::data_type
+ \param Cursor is the type of cursor to be used iterate through the node.
+ \todo add specialization when the node has a parent pointer
+ */
 template<class Key,class Mapped,class Cursor>
 class trie_iterator
 :public iterator_facade< trie_iterator<Key,Mapped,Cursor>,Mapped,bidirectional_traversal_tag >
@@ -23,47 +30,62 @@
         friend class trie;
         template<class K,class M,class C> friend class trie_iterator;
 
+ /// helps in avoiding conversion of const_iterator to iterator.
         struct enabler {};
+ /// Self.
         typedef trie_iterator<Key,Mapped,Cursor> self;
 
+ /// "stack" of cursors.
         std::vector<Cursor> cur_st;
+ /// size of the stack.
         int cur_size;
+ /// flag is true if the iterator is end()
         bool end_flag;
 
+ /// push cursor into the stack
+ /**
+ \param c is the cursor to be pushed.
+ */
         void push ( const Cursor &c )
         {
                 ++cur_size;
                 cur_st.push_back(c);
         }
         
+ /// pop the cursor from the stack.
         void pop()
         {
                 --cur_size;
                 cur_st.pop_back();
         }
 
+ /// get reference to top of the stack
         Cursor &top()
         {
                 assert(!(this->empty()));
                 return cur_st[cur_size-1];
         }
         
+ /// returns the size of the stack
         std::size_t size()
         {
                 return cur_size;
         }
 
+ /// get the top of the stack
         Cursor get_top() const
         {
                 assert(!(this->empty()));
                 return cur_st[cur_size-1];
         }
 
+ ///checks whether the stack is empty.
         bool empty() const
         {
                 return cur_st.empty();
         }
 
+ ///go to the right most leaf from the current top.
         void to_right_most()
         {
                 Cursor c=this->top();
@@ -77,6 +99,10 @@
                 assert(this->top().has_value());
         }
 
+ ///check whether two iterators are equal.
+ /**
+ \param other is the other iterator. It can be const or non const.
+ */
         template<class K,class M,class C>
         bool equal(trie_iterator<K,M,C> const& other) const
         {
@@ -85,6 +111,7 @@
                 return false;
         }
 
+ ///go to the left most leaf from the current top.
         void to_left_most()
         {
                 Cursor c=this->top();
@@ -104,6 +131,7 @@
                 assert(this->top().has_value());
         }
 
+ ///decrement the iterator.
         void decrement()
         {
                 bool first_loop=true;
@@ -124,16 +152,25 @@
                         end_flag=true;
                         return;
                 }
+
+ //* if we one the left edge of a node.
                 while(top==this->top().begin())
                 {
+ //* If top has value then we need to stop.
                         if(top.has_value() && !first_loop)
                         {
- this->push(top); //to make sure to_right_most still works
+ //* to make sure to_right_most still works
+ this->push(top);
                                 return;
                         }
+
                         first_loop=false;
                         top=this->top();
                         this->pop();
+
+ //* we have reached the and empty stack? then we have reached
+ //* then we can go up no more.Also is top has value then
+ //* root has value.
                         if(this->empty())
                         {
                                 this->push(top);
@@ -142,19 +179,26 @@
                                 return;
                         }
                 }
+
+ //finally we found an edge which we can shift to the right
                 --top;
                 this->push(top);
+
+ //* move to the right most.
                 to_right_most();
         }
 
+ ///increment the iterator.
         void increment()
         {
- assert(end_flag==false && NULL!="incrementing at end");//just for debugging
+ assert(end_flag==false && NULL!="incrementing at end");
                 assert(!this->empty() && NULL!="incrementing before begin");
                 Cursor top=this->top().begin();
 
+ //*if if it is the leaf node || we reached the edge a node.
                 while(this->top().end()==top)
                 {
+ //* pop in search of a new top.
                         top=this->top();
                         this->pop();
                         if(this->empty())
@@ -166,15 +210,18 @@
                         ++top;
                 }
                 this->push (top);
+ //* go to left most.
                 to_left_most();
         }
 
+ ///return a reference to the node the the is pointing to.
         Mapped &dereference() const
         {
                 assert ( (cur_st[cur_size-1]).has_value() );
                 return ( (cur_st[cur_size-1]).get_value() );
         }
         
+ /*
         bool equal( const self &other ) const
         {
                 assert(!this->empty());
@@ -182,14 +229,19 @@
                 if(other.cur_st[other.cur_size-1]==cur_st[cur_size-1])
                         return true;
                 return false;
- }
+ }*/
 
         public:
- trie_iterator():end_flag(false) //to be pushed later.. thats why
- {
- cur_size=0;
+ ///default constructor
+ trie_iterator():cur_size(0), end_flag(false)
+ {
         }
 
+ ///constructor for begin() or end()
+ /**
+ \param cursor_root is patricia::node_root
+ \param end_flag specifies whether its begin cursor or end cursor.
+ */
         trie_iterator( Cursor const &cursor_root,bool end_flag=false ) //returns begin cursor
         {
                 cur_size=0;
@@ -199,20 +251,24 @@
                         this->push(cursor_root);
                         return;
                 }
-
- if( cursor_root.empty() && !cursor_root.has_value() ) //special case of only empty root
+ //*special case of only empty root
+ if( cursor_root.empty() && !cursor_root.has_value() )
                 {
-// std::cout<<"IN"<<std::endl;
                         this->end_flag=true;
                         this->push(cursor_root);
                         return;
                 }
-// std::cout<<"OUT"<<std::endl
+
                 this->push(cursor_root);
+ //goto the begin();
                 to_left_most();
         }
 
         public:
+ ///copy constructor
+ /**
+ \param other is the iterator to be copied
+ */
         template<class K,class M,class C>
         trie_iterator( trie_iterator<K,M,C> const& other,
                         typename enable_if< is_convertible<M*,Mapped*>,
@@ -222,6 +278,7 @@
                 end_flag=other.end_flag;
                 cur_size=0;
 
+ //* copy stack elements one by one.
                 typename std::vector<C>::const_iterator it=other.cur_st.begin();
                 while ( it!=other.cur_st.end() )
                 {
@@ -231,6 +288,16 @@
         }
 };
 
+
+/// reverse iterator class for trie
+/**
+ \brief reverse iterator class is implemented using an iterator.
+ \param Key is patricia::key_type
+ \param Mapped is patricia::data_type
+ \param Cursor is the type of cursor to be used iterate through the node.
+ \todo add specialization when the node has a parent pointer
+ */
+
 template<class Key,class Mapped,class Cursor>
 class trie_reverse_iterator
 :public iterator_facade< trie_reverse_iterator<Key,Mapped,Cursor>,Mapped,bidirectional_traversal_tag >
@@ -239,15 +306,23 @@
         friend class boost::iterator_core_access;
         template<class K,class M,template<class K1,class M1,class K_t1,class A1 > class t_n,class K_t,class A >
         friend class trie;
-
- struct enabler {};
         template<class K,class M,class C> friend class trie_reverse_iterator;
+
+ /// helps in avoiding conversion of const_iterator to iterator.
+ struct enabler {};
+ /// Self
         typedef trie_reverse_iterator<Key,Mapped,Cursor> self;
+ /// type of iterator corresponding to reverse_iterator.
         typedef trie_iterator<Key,Mapped,Cursor> iterator;
 
- iterator correspond_it,beg_it;
+ /// use the corresponding iterator to iterate.
+ iterator correspond_it;
+ /// one must know when one hits rend :). thats this exists
+ iterator beg_it;
+ /// end_flag=true ==> we have reached rend
         bool end_flag;
 
+ ///increments the reverse iterator.
         void increment()
         {
                 assert(!end_flag);
@@ -257,11 +332,13 @@
                 --correspond_it;
         }
         
+ /// gets the corresponding iterator.
         const iterator &get_iterator() const
         {
                 return correspond_it;
         }
 
+ /// decrements the reverse iterator.
         void decrement()
         {
                 if(end_flag)
@@ -275,6 +352,10 @@
                 return ( this->correspond_it==other.correspond_it && this->end_flag==other.end_flag);
         }
 */
+ /// checks whether two reverse iterator.
+ /**
+ \param other is the other reverse iterator.
+ */
         template<class K,class M,class C>
         bool equal(trie_reverse_iterator<K,M,C> const& other) const
         {
@@ -282,7 +363,8 @@
                         return true;
                 return false;
         }
-
+
+ /// dereferences iterator.
         Mapped &dereference() const
         {
                 assert(!end_flag);
@@ -290,9 +372,18 @@
         }
 
         public:
+
+ /// default constructor
         trie_reverse_iterator(): end_flag(0)
         {
         }
+
+ /// constructor of instilaizing to rbegin and rend
+ /**
+ \param beg_it is trie::begin()
+ \param end_it is trie::end()
+ \param is_beg_flag is true if its rbegin() otherwise false if its rend()
+ */
         trie_reverse_iterator(const iterator &beg_it,const iterator &end_it,bool is_beg_flag)//should be intialized with end iterator
         {
                 if(is_beg_flag)
@@ -309,6 +400,10 @@
                 }
         }
 
+ ///copy constructor
+ /**
+ \param other is the reverse_iterator to be copied
+ */
         template<class K,class M,class C>
         trie_reverse_iterator( trie_reverse_iterator<K,M,C> const& other,
                                 typename enable_if< is_convertible<M*,Mapped*>,


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk