Inferno  0.2
containers.hpp
Go to the documentation of this file.
00001 /*
00002  * containers.hpp
00003  *
00004  *  Created on: 30 Aug 2009
00005  *      Author: jgraley
00006  */
00007 
00008 #ifndef CONTAINERS_HPP
00009 #define CONTAINERS_HPP
00010 
00011 #include "common.hpp"
00012 
00013 /// OOStd namespace contains wrappers for STL and Boost features adding run-time polymorphism
00014 namespace OOStd {
00015 
00016 //
00017 // Template for a base class for STL containers with forward iterators.
00018 // Supports direct calls and iterators.
00019 //
00020 // The base container will be derived from SUB_BASE. VALUE_INTERFACE should
00021 // be a base (or compatible type) for the elements of all sub-containers.
00022 //
00023 
00024 template< class SUB_BASE, typename VALUE_INTERFACE >
00025 class ContainerInterface : public virtual Traceable, public virtual SUB_BASE
00026 {
00027 public:
00028   // Abstract base class for the implementation-specific iterators in containers.
00029   struct iterator_interface : public Traceable
00030   {
00031     // TODO const iterator and const versions of begin(), end()
00032     virtual shared_ptr<iterator_interface> Clone() const = 0; // Make another copy of the present iterator
00033     virtual iterator_interface &operator++() = 0;
00034     virtual iterator_interface &operator--() { ASSERTFAIL("Only on reversible iterator"); };
00035     const virtual VALUE_INTERFACE &operator*() const = 0;
00036     const virtual VALUE_INTERFACE *operator->() const = 0;
00037     virtual bool operator==( const iterator_interface &ib ) const = 0;
00038     virtual void Overwrite( const VALUE_INTERFACE *v ) const = 0;
00039     virtual const bool IsOrdered() const = 0;
00040     virtual const int GetCount() const { ASSERTFAIL("Only on CountingIterator"); }
00041   };
00042 
00043 public:
00044   // Wrapper for iterator_interface, uses boost::shared_ptr<> and Clone() to manage the real iterator
00045   // and forwards all the operations using co-variance where possible. These can be passed around
00046   // by value, and have copy-on-write semantics, so big iterators will actually get optimised
00047   // (in your face, Stepanov!)
00048   class iterator : public Traceable
00049   {
00050   public:
00051     typedef forward_iterator_tag iterator_category;
00052     typedef VALUE_INTERFACE value_type;
00053     typedef int difference_type;
00054     typedef const value_type *pointer;
00055     typedef const value_type &reference;
00056 
00057     iterator() :
00058       pib( shared_ptr<iterator_interface>() ) {}
00059 
00060     iterator( const iterator_interface &ib ) :
00061       pib( ib.Clone() ) {} // Deep copy because from unmanaged source
00062 
00063     iterator( const iterator &i ) :
00064       pib( i.pib ) {} // Shallow copy
00065 
00066     iterator &operator=( const iterator &i )
00067     {
00068       pib = i.pib; // Shallow copy
00069       return *this;
00070     }
00071 
00072     iterator &operator++()
00073     {
00074       ASSERT(pib)("Attempt to increment uninitialised iterator");
00075       EnsureUnique();
00076       pib->operator++();
00077       return *this;
00078     }
00079 
00080     iterator &operator--()
00081     {
00082       ASSERT(pib)("Attempt to increment uninitialised iterator");
00083       EnsureUnique();
00084       pib->operator--();
00085       return *this;
00086     }
00087 
00088     const value_type &operator*() const 
00089     {
00090       ASSERT(pib)("Attempt to dereference uninitialised iterator");
00091       return pib->operator*();
00092     }
00093 
00094     const value_type *operator->() const
00095     {
00096       ASSERT(pib)("Attempt to dereference uninitialised iterator");
00097       return pib->operator->();
00098     }
00099 
00100     bool operator==( const iterator &i ) const
00101     {
00102       ASSERT(pib)("Attempt to compare uninitialised iterator");
00103       return pib->operator==( *(i.pib) );
00104     }
00105 
00106     bool operator!=( const iterator &i ) const
00107     {
00108       ASSERT(pib)("Attempt to compare uninitialised iterator");
00109       return !operator==( i );
00110     }
00111 
00112     void Overwrite( const value_type *v ) const
00113     {
00114       ASSERT(pib)("Attempt to Overwrite through uninitialised iterator");
00115         pib->Overwrite( v );
00116     }
00117         
00118     const bool IsOrdered() const
00119     {
00120       return pib->IsOrdered();
00121     }
00122 
00123     const int GetCount() const
00124     {
00125       return pib->GetCount();
00126     }
00127 
00128     iterator_interface *GetUnderlyingIterator()
00129     {
00130       if( pib )
00131         return pib.get();
00132       else
00133         return NULL;
00134     }
00135     
00136     virtual shared_ptr<iterator_interface> Clone() // TODO does this need to be virtual?
00137     {
00138       ASSERT(pib)("Attempt to Clone() uninitialised iterator");
00139       return pib->Clone();
00140     }
00141     
00142     operator string()
00143     {   
00144         if( pib )
00145             return (string)(Traceable::CPPFilt( typeid( *pib ).name() ));
00146         else 
00147             return (string)("no-impl");
00148     }
00149   private:
00150     void EnsureUnique()
00151     {
00152       // Call this before modifying the underlying iterator - Performs a deep copy
00153       // if required to make sure there are no other refs.
00154       if( pib && !pib.unique() )
00155         pib = Clone();
00156       ASSERT( !pib || pib.unique() );
00157     }
00158 
00159     shared_ptr<iterator_interface> pib;
00160   };
00161   typedef iterator const_iterator; // TODO const iterators properly
00162 
00163   // These direct calls to the container are designed to support co-variance.
00164     virtual void insert( const VALUE_INTERFACE &gx ) = 0;
00165   virtual const iterator_interface &begin() = 0;
00166     virtual const iterator_interface &end() = 0;
00167     virtual void erase( typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator it ) = 0;
00168     virtual bool empty() const { return size() == 0; }
00169     virtual int size() const
00170     {
00171       // TODO support const_interator properly and get rid of this const_cast
00172       ContainerInterface *nct = const_cast<ContainerInterface *>(this);
00173       int n=0;
00174       FOREACH( const VALUE_INTERFACE &x, *nct )
00175           n++;
00176       return n;
00177     }
00178     virtual void clear() = 0;
00179 };
00180 
00181 
00182 template< class SUB_BASE, typename VALUE_INTERFACE >
00183 struct SequenceInterface : virtual ContainerInterface<SUB_BASE, VALUE_INTERFACE>
00184 {
00185     virtual VALUE_INTERFACE &operator[]( int i ) = 0;
00186     virtual void push_back( const VALUE_INTERFACE &gx ) = 0;
00187 };
00188 
00189 
00190 template< class SUB_BASE, typename VALUE_INTERFACE >
00191 struct SimpleAssociativeContainerInterface : virtual ContainerInterface<SUB_BASE, VALUE_INTERFACE>
00192 {
00193   virtual int erase( const VALUE_INTERFACE &gx ) = 0;
00194   virtual bool IsExist( const VALUE_INTERFACE &gx ) = 0;
00195 };
00196 
00197 
00198 //
00199 // Abstract template for containers that will be use any STL container as
00200 // the actual implementation.
00201 // Params as for ContainerInterface except we now have to fill in CONTAINER_IMPL
00202 // as the stl container class eg std::list<blah>
00203 //
00204 template<class SUB_BASE, typename VALUE_INTERFACE, class CONTAINER_IMPL>
00205 struct ContainerCommon : virtual ContainerInterface<SUB_BASE, VALUE_INTERFACE>, CONTAINER_IMPL
00206 {
00207   struct iterator : public CONTAINER_IMPL::iterator,
00208                     public ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface
00209   {
00210     virtual iterator &operator++()
00211     {
00212       CONTAINER_IMPL::iterator::operator++();
00213         return *this;
00214     }
00215 
00216     virtual iterator &operator--()
00217     {
00218       CONTAINER_IMPL::iterator::operator--();
00219         return *this;
00220     }
00221 
00222     virtual const typename CONTAINER_IMPL::value_type &operator*() const
00223     {
00224       return CONTAINER_IMPL::iterator::operator*();
00225     }
00226 
00227     virtual const typename CONTAINER_IMPL::value_type *operator->() const
00228     {
00229       return CONTAINER_IMPL::iterator::operator->();
00230     }
00231 
00232     virtual bool operator==( const typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface &ib ) const
00233     {
00234         const typename CONTAINER_IMPL::iterator *pi = dynamic_cast<const typename CONTAINER_IMPL::iterator *>(&ib);
00235         ASSERT(pi)("Comparing iterators of different type");
00236       return *(const typename CONTAINER_IMPL::iterator *)this == *pi;
00237     }
00238   };
00239 
00240   typedef iterator const_iterator;
00241 
00242     virtual void erase( typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator it )
00243     {
00244         iterator *cit = dynamic_cast<iterator *>( it.GetUnderlyingIterator() );
00245         ASSERT( cit ); // if this fails, you passed erase() the wrong kind of iterator
00246         CONTAINER_IMPL::erase( *(typename CONTAINER_IMPL::iterator *)cit );
00247     }
00248     virtual bool empty() const
00249     {
00250         return CONTAINER_IMPL::empty();
00251     }
00252     virtual int size() const
00253     {
00254         return CONTAINER_IMPL::size();
00255     }
00256     virtual void clear()
00257     {
00258       return CONTAINER_IMPL::clear();
00259     }
00260   virtual operator string() const
00261   {
00262         return Traceable::CPPFilt( typeid( typename CONTAINER_IMPL::value_type ).name() );
00263   }
00264 };
00265 
00266 
00267 //
00268 // Template for containers that use ordered STL containers as implementation
00269 // (basically vector, deque etc). Instantiate as per ContainerCommon.
00270 //
00271 template<class SUB_BASE, typename VALUE_INTERFACE, class CONTAINER_IMPL>
00272 struct Sequence : virtual ContainerCommon<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>, virtual SequenceInterface<SUB_BASE, VALUE_INTERFACE>
00273 {
00274     using typename CONTAINER_IMPL::insert; // due to silly C++ rule where different overloads hide each other
00275     inline Sequence<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>() {}
00276   struct iterator : public ContainerCommon<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>::iterator
00277     {
00278     inline iterator( typename CONTAINER_IMPL::iterator &i ) : CONTAINER_IMPL::iterator(i) {}
00279     inline iterator() {}
00280     virtual typename CONTAINER_IMPL::value_type &operator*() const
00281     {
00282       return CONTAINER_IMPL::iterator::operator*();
00283     }
00284     virtual typename CONTAINER_IMPL::value_type *operator->() const
00285     {
00286       return CONTAINER_IMPL::iterator::operator->();
00287     }
00288     virtual shared_ptr<typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface> Clone() const
00289     {
00290       shared_ptr<iterator> ni( new iterator );
00291       *ni = *this;
00292       return ni;
00293     }
00294       virtual void Overwrite( const VALUE_INTERFACE *v ) const
00295     {
00296         // JSG Overwrite() just writes through the pointer got from dereferencing the iterator,
00297         // because in Sequences (ordererd containers) elements may be modified.
00298         typename CONTAINER_IMPL::value_type x( CONTAINER_IMPL::value_type::InferredDynamicCast(*v) );
00299         CONTAINER_IMPL::iterator::operator*() = x;
00300     }
00301       virtual const bool IsOrdered() const
00302       {
00303         return true; // yes, Sequences are ordered
00304       }
00305   };
00306 
00307     virtual typename CONTAINER_IMPL::value_type &operator[]( int i )
00308     {
00309       return CONTAINER_IMPL::operator[](i);
00310     }
00311   virtual void insert( const VALUE_INTERFACE &gx )
00312   {
00313     push_back( gx );
00314   }
00315   virtual void push_back( const VALUE_INTERFACE &gx )
00316   {
00317     typename CONTAINER_IMPL::value_type sx( CONTAINER_IMPL::value_type::InferredDynamicCast(gx) );
00318     CONTAINER_IMPL::push_back( sx );
00319   }
00320   template<typename OTHER>
00321   inline void push_back( const OTHER &gx )
00322   {
00323     typename CONTAINER_IMPL::value_type sx(gx);
00324     CONTAINER_IMPL::push_back( sx );
00325   }
00326 
00327   // Covariant style only works with refs and pointers, so force begin/end to return refs safely
00328   // This complies with STL's thread safety model. To quote SGI,
00329   // "The SGI implementation of STL is thread-safe only in the sense that simultaneous accesses
00330   // to distinct containers are safe, and simultaneous read accesses to to shared containers are
00331   // safe. If multiple threads access a single container, and at least one thread may potentially
00332   // write, then the user is responsible for ensuring mutual exclusion between the threads during
00333   // the container accesses."
00334   // So that's OK then.
00335     iterator my_begin, my_end;
00336 
00337     virtual const iterator &begin()
00338     {
00339       my_begin.CONTAINER_IMPL::iterator::operator=( CONTAINER_IMPL::begin() );
00340       return my_begin;
00341     }
00342     virtual const iterator &end()
00343     {
00344       my_end.CONTAINER_IMPL::iterator::operator=( CONTAINER_IMPL::end() );
00345       return my_end;
00346     }
00347   Sequence( const SequenceInterface<SUB_BASE, VALUE_INTERFACE> &cns )
00348   {
00349     // TODO support const_interator properly and get rid of this const_cast
00350     SequenceInterface<SUB_BASE, VALUE_INTERFACE> *ns = const_cast< SequenceInterface<SUB_BASE, VALUE_INTERFACE> * >( &cns );
00351     for( typename SequenceInterface<SUB_BASE, VALUE_INTERFACE>::iterator i=ns->begin();
00352          i != ns->end();
00353          ++i )
00354     {
00355             CONTAINER_IMPL::push_back( (typename CONTAINER_IMPL::value_type)*i );
00356     }
00357   }
00358   Sequence( const VALUE_INTERFACE &nx )
00359   {
00360     typename CONTAINER_IMPL::value_type sx( CONTAINER_IMPL::value_type::InferredDynamicCast(nx) );
00361     CONTAINER_IMPL::push_back( sx );
00362   }
00363   template<typename L, typename R>
00364   inline Sequence( const pair<L, R> &p )
00365   {
00366     *this = Sequence<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>( p.first );
00367     Sequence<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL> t( p.second );
00368 
00369     for( typename Sequence<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>::iterator i=t.begin();
00370          i != t.end();
00371          ++i )
00372     {
00373             CONTAINER_IMPL::push_back( *i );
00374     }
00375   }
00376   inline Sequence( const typename CONTAINER_IMPL::value_type &v )
00377   {
00378     push_back( v );
00379   }
00380 };
00381 
00382 
00383 //
00384 // Template for containers that use unordered STL containers as implementation
00385 // (basically associative containers). Instantiate as per ContainerCommon.
00386 //
00387 template<class SUB_BASE, typename VALUE_INTERFACE, class CONTAINER_IMPL>
00388 struct SimpleAssociativeContainer : virtual ContainerCommon<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>, virtual SimpleAssociativeContainerInterface<SUB_BASE, VALUE_INTERFACE>
00389 {
00390     inline SimpleAssociativeContainer<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>() {}
00391   struct iterator : public ContainerCommon<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>::iterator
00392     {
00393     inline iterator( typename CONTAINER_IMPL::iterator &i ) : CONTAINER_IMPL::iterator(i) {}
00394     inline iterator() {}
00395     virtual shared_ptr<typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface> Clone() const
00396     {
00397       shared_ptr<iterator> ni( new iterator );
00398       *ni = *this;
00399       return ni;
00400     }
00401       virtual void Overwrite( const VALUE_INTERFACE *v ) const
00402     {
00403         // SimpleAssociativeContainers (unordered containers) do not allow elements to be modified
00404         // because the internal data structure depends on element values. So we 
00405         // erase the old element and insert the new one; thus, Overwrite() should not be assumed O(1)
00406         typename CONTAINER_IMPL::value_type s( CONTAINER_IMPL::value_type::InferredDynamicCast(*v) );
00407         ((CONTAINER_IMPL *)owner)->erase( *this );
00408         *(typename CONTAINER_IMPL::iterator *)this = ((CONTAINER_IMPL *)owner)->insert( s ); // become an iterator for the newly inserted element
00409     }
00410       virtual const bool IsOrdered() const
00411       {
00412         return false; // no, SimpleAssociativeContainers are not ordered
00413       }
00414         SimpleAssociativeContainer<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL> *owner;
00415   };
00416 
00417   virtual void insert( const VALUE_INTERFACE &gx )
00418   {
00419     typename CONTAINER_IMPL::value_type sx( CONTAINER_IMPL::value_type::InferredDynamicCast(gx) );
00420     CONTAINER_IMPL::insert( sx );
00421   }
00422   template<typename OTHER>
00423   inline void insert( const OTHER &gx )
00424   {
00425     typename CONTAINER_IMPL::value_type sx(gx);
00426     CONTAINER_IMPL::insert( sx );
00427   }
00428   virtual int erase( const VALUE_INTERFACE &gx )
00429   {
00430     typename CONTAINER_IMPL::value_type sx( CONTAINER_IMPL::value_type::InferredDynamicCast(gx) );
00431     return CONTAINER_IMPL::erase( sx );
00432   }
00433   virtual bool IsExist( const VALUE_INTERFACE &gx )
00434   {
00435     typename CONTAINER_IMPL::value_type sx( CONTAINER_IMPL::value_type::InferredDynamicCast(gx) );
00436     typename CONTAINER_IMPL::iterator it = CONTAINER_IMPL::find( sx );
00437     return it != CONTAINER_IMPL::end();
00438   }
00439 
00440   iterator my_begin, my_end;
00441     virtual const iterator &begin()
00442     {
00443       my_begin.CONTAINER_IMPL::iterator::operator=( CONTAINER_IMPL::begin() );
00444       my_begin.owner = this;
00445       return my_begin;
00446     }
00447     virtual const iterator &end()
00448     {
00449       my_end.CONTAINER_IMPL::iterator::operator=( CONTAINER_IMPL::end() );
00450       my_end.owner = this;
00451       return my_end;
00452     }
00453     SimpleAssociativeContainer( const ContainerInterface<SUB_BASE, VALUE_INTERFACE> &cns )
00454   {
00455     // TODO support const_interator properly and get rid of this const_cast
00456       ContainerInterface<SUB_BASE, VALUE_INTERFACE> *ns = const_cast< ContainerInterface<SUB_BASE, VALUE_INTERFACE> * >( &cns );
00457     for( typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator i=ns->begin();
00458          i != ns->end();
00459          ++i )
00460     {
00461             CONTAINER_IMPL::insert( *i );
00462     }
00463   }
00464     SimpleAssociativeContainer( const VALUE_INTERFACE &nx )
00465   {
00466     typename CONTAINER_IMPL::value_type sx( CONTAINER_IMPL::value_type::InferredDynamicCast(nx) );
00467         CONTAINER_IMPL::insert( sx );
00468   }
00469   template<typename L, typename R>
00470   inline SimpleAssociativeContainer( const pair<L, R> &p )
00471   {
00472     *this = SimpleAssociativeContainer<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>( p.first );
00473     SimpleAssociativeContainer<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL> t( p.second );
00474 
00475     for( typename SimpleAssociativeContainer<SUB_BASE, VALUE_INTERFACE, CONTAINER_IMPL>::iterator i=t.begin();
00476          i != t.end();
00477          ++i )
00478     {
00479             CONTAINER_IMPL::insert( *i );
00480     }
00481   }
00482   inline SimpleAssociativeContainer( const typename CONTAINER_IMPL::value_type &v )
00483   {
00484     insert( v );
00485   }
00486 };
00487 
00488 //
00489 // Iterator that points to a single object, no container required.
00490 // We do not support looping/incrementing or FOREACH (which requires a
00491 // container) but we do permit compare, deref and Overwrite(). This lets
00492 // ContainerInterface::iterator be used generically even when objects are
00493 // not in containers.
00494 //
00495 template<class SUB_BASE, typename VALUE_INTERFACE>
00496 struct PointIterator : public ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface
00497 {
00498     VALUE_INTERFACE * element;
00499 
00500     PointIterator() :
00501         element(NULL) // means end-of-range
00502     {
00503     }
00504 
00505     PointIterator( const PointIterator &other ) :
00506         element(other.element)
00507     {
00508     }
00509 
00510     PointIterator( VALUE_INTERFACE *i ) :
00511         element(i)
00512     {      
00513         ASSERT(i); // We don't allow NULL as input because it means end-of-range
00514     }
00515 
00516   virtual shared_ptr<typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface> Clone() const
00517   {
00518     shared_ptr<PointIterator> ni( new PointIterator(*this) );
00519     return ni;
00520   }
00521 
00522   virtual PointIterator &operator++()
00523   {
00524     element = NULL; // ie if we increment, we get to the end of the range
00525     return *this;
00526   }
00527 
00528   virtual VALUE_INTERFACE &operator*() const
00529   {
00530       ASSERT(element)("Tried to dereference NULL PointIterator");
00531     return *element;
00532   }
00533 
00534   virtual VALUE_INTERFACE *operator->() const
00535   {
00536       ASSERT(element)("Tried to dereference NULL PointIterator");
00537     return element;
00538   }
00539 
00540   virtual bool operator==( const typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface &ib ) const
00541   {
00542     const PointIterator *pi = dynamic_cast<const PointIterator *>(&ib);
00543     ASSERT(pi)("Comparing point iterator with something else ")(ib);
00544     return pi->element == element;
00545   }
00546   
00547   virtual void Overwrite( const VALUE_INTERFACE *v ) const
00548   {
00549       *element = *v;
00550   }
00551 
00552   virtual const bool IsOrdered() const
00553   {
00554     return true; // shouldn't matter what we return here
00555   }
00556 };
00557 
00558 template<class SUB_BASE, typename VALUE_INTERFACE>
00559 struct CountingIterator : public ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface
00560 {
00561     int element;
00562 
00563     CountingIterator() :
00564         element(0)
00565     {
00566     }
00567 
00568     CountingIterator( int i ) :
00569         element(i)
00570     {
00571     }
00572 
00573   virtual shared_ptr<typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface> Clone() const
00574   {
00575     shared_ptr<CountingIterator> ni( new CountingIterator(*this) );
00576     return ni;
00577   }
00578 
00579   virtual CountingIterator &operator++()
00580   {
00581     element++;
00582     return *this;
00583   }
00584 
00585   virtual CountingIterator &operator--()
00586   {
00587     element--;
00588     return *this;
00589   }
00590 
00591   virtual VALUE_INTERFACE &operator*() const
00592   {
00593       ASSERTFAIL("Cannot dereference CountingIterator, use GetCount instead");
00594   }
00595 
00596   const virtual VALUE_INTERFACE *operator->() const
00597   {
00598     ASSERTFAIL("Cannot dereference CountingIterator, use GetCount instead");
00599   }
00600 
00601   virtual bool operator==( const typename ContainerInterface<SUB_BASE, VALUE_INTERFACE>::iterator_interface &ib ) const
00602   {
00603     const CountingIterator *pi = dynamic_cast<const CountingIterator *>(&ib);
00604     ASSERT(pi)("Comparing counting iterator with something else ")( ib );
00605     return pi->element == element;
00606   }
00607 
00608   virtual void Overwrite( const VALUE_INTERFACE *v ) const
00609   {
00610       ASSERTFAIL("Cannot Overwrite through CountingIterator");
00611   }
00612 
00613   virtual const bool IsOrdered() const
00614   {
00615     return true; // counting iterator counts 1, 2, 3, like that, so seems to be ordered
00616   }
00617 
00618   const int GetCount() const
00619   {
00620     return element;
00621   }
00622 };
00623 
00624 // Allow operator, to be used to create pairs. Also handy for maps.
00625 template<typename L, typename R>
00626 inline pair<L,R> operator,( const L &l, const R &r )
00627 {
00628     return pair<L,R>(l,r);
00629 }
00630 
00631 }; // namespace
00632 
00633 #endif /* GENERICS_HPP */