PolyBoRi
CExpIter.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00014 //*****************************************************************************
00015 
00016 // include basic definitions
00017 #include "pbori_defs.h"
00018 
00019 // get stuff for term iteration
00020 #include "CTermStack.h"
00021 #include "CTermIter.h"
00022 
00023 #ifndef CExpIter_h_
00024 #define CExpIter_h_
00025 
00026 BEGIN_NAMESPACE_PBORI
00027 
00028 
00029 template <class ExpType>
00030 class CExpGenerator {
00031 
00032 public:
00033   typedef ExpType value_type;
00034   typedef const value_type& result_type;
00035   typedef typename value_type::size_type size_type;
00036 
00038   CExpGenerator(): m_result() {}
00039 
00041   template <class SequenceType>
00042   result_type operator()(const SequenceType&) const{
00043     return m_result;
00044   }
00045 
00047   void resize(size_type nlen) { m_result.resize(nlen); }
00048 
00050   void reserve(size_type nlen) { m_result.reserve(nlen); }
00051 
00053   size_type size() const { return m_result.size(); }
00054 
00056   template <class Iterator>
00057   void append(Iterator start, Iterator finish) { 
00058     while (start != finish){
00059       m_result.push_back(*start);
00060       ++start;
00061     }
00062   }
00063 
00064 private:
00065   value_type m_result;
00066 };
00067 
00068 
00069 template <class NaviType, class ExpType>
00070 struct pbori_base<CExpIter<NaviType, ExpType> > {
00071 
00072   typedef CTermStack<NaviType, std::forward_iterator_tag> stack_type;
00073   typedef CTermIter<stack_type, CExpGenerator<ExpType> > type;
00074 };
00075 
00076 template <class NaviType, class ExpType>
00077 class CExpIter : 
00078   public pbori_base<CExpIter<NaviType, ExpType> >::type {
00079 
00080 public:
00082   typedef CExpIter<NaviType, ExpType> self;
00083 
00085   typedef typename pbori_base<self>::type base;
00086 
00088   CExpIter(NaviType navi): base(navi, typename base::term_generator() ) {
00089     base::m_getTerm.reserve(base::m_stack.size());
00090     base::m_getTerm.append(base::begin(), base::end()); 
00091   }
00092   
00094   CExpIter(): base() {}
00095 
00097   void increment() { 
00098     assert(!base::m_stack.empty());
00099     if (base::m_stack.markedOne()) {
00100       base::m_stack.clearOne();
00101     }
00102     else {
00103       base::m_stack.next();
00104       base::m_getTerm.resize( base::m_stack.size() == 0 ?
00105                               0: 
00106                               base::m_stack.size() - 1);
00107 
00108       if (!base::m_stack.empty()) {
00109         base::m_stack.followThen();
00110         base::m_stack.terminate();
00111      }
00112     }
00113     base::m_getTerm.reserve(base::m_stack.size());
00114     base::m_getTerm.append(base::begin() + base::m_getTerm.size(), base::end());
00115   }
00116 
00118   self& operator++() {
00119     increment();
00120     return *this;
00121   }
00123   self operator++(int) {
00124     self copy(*this);
00125     increment();
00126     return copy;
00127   }
00128 };
00129 
00130 END_NAMESPACE_PBORI
00131 
00132 #endif