FrontQueue.h

Go to the documentation of this file.
00001 #ifndef FrontQueue_HEADER
00002 #define FrontQueue_HEADER
00003 
00004 #ifdef HAVE_CONFIG_H
00005 # include <config.h>
00006 #endif
00007 
00008 /***************************************************************************
00009  * Benoit Hudson (C) 2007.
00010  ***************************************************************************/
00011 #include "SmallList.h"
00012 
00013 namespace hudson {
00014 /***************************************************************************
00015   * A container adaptor much like the STL's queue, except that we only require
00016   * the container to be a Front Insertion Sequence, not both front and back.
00017   * We also require the 'reverse' and 'swap' operations to be defined.
00018   * This works, e.q., for a hudson::SmallList or a std::list or std::deque.
00019   *
00020   * Unlike in the STL queue, we do not implement back() or size().
00021   * All operations are amortized constant so long as Sequence::push_front(),
00022   * pop_front(), and front() are amortized constant.
00023   *
00024   * This adaptor is faster than QueueFromStack because it assumes the existence
00025   * of reverse and swap.
00026  ***************************************************************************/
00027   template <class Item, class Sequence = SmallList<Item> > struct FrontQueue {
00028     typedef Sequence container_type;
00029     typedef typename container_type::value_type value_type;
00030     typedef typename container_type::reference reference;
00031     typedef typename container_type::const_reference const_reference;
00032 
00033     FrontQueue() { }
00034     FrontQueue(const FrontQueue& q): in_(q.in_), out_(q.out_) { }
00035     FrontQueue& operator=(const FrontQueue& q) { in_ = q.in_; out_ = q.out_; }
00036 
00037     bool empty() const { return out_.empty(); }
00038 
00039     reference top() {
00040       assert(!out_.empty());
00041       return out_.front();
00042     }
00043     const_reference top() const {
00044       assert(!out_.empty());
00045       return out_.front();
00046     }
00047     reference front() { return top(); }
00048     const_reference front() const { return top(); }
00049 
00050     void push(const_reference v) {
00051       if (out_.empty()) {
00052         assert(in_.empty());
00053         out_.push_front(v);
00054       } else {
00055         in_.push_front(v);
00056       }
00057     }
00058 
00059     void pop() {
00060       assert(!out_.empty());
00061       out_.pop_front();
00062 
00063       /* If out_ is empty, copy in the elements from in_, in reverse order.
00064        * Knowing that this is a SmallList means we can do it without any
00065        * allocation. */
00066       if (out_.empty() && !in_.empty()) {
00067         out_.swap(in_);
00068         out_.reverse();
00069       }
00070     }
00071 
00072     private:
00073     container_type in_;
00074     container_type out_;
00075   };
00076 
00077 } // namespace hudson
00078 
00079 #endif

Generated on Thu Mar 27 19:04:14 2008 by  doxygen 1.4.6