PolyBoRi
CExpIter.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00014 //*****************************************************************************
00015 
00016 #ifndef polybori_iterators_CExpIter_h_
00017 #define polybori_iterators_CExpIter_h_
00018 
00019 // include basic definitions
00020 #include <polybori/pbori_defs.h>
00021 
00022 // get stuff for term iteration
00023 #include "CTermStack.h"
00024 #include "CTermIter.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   
00093 
00095   void increment() { 
00096     PBORI_ASSERT(!base::m_stack.empty());
00097     if (base::m_stack.markedOne()) {
00098       base::m_stack.clearOne();
00099     }
00100     else {
00101       base::m_stack.next();
00102       base::m_getTerm.resize( base::m_stack.size() == 0 ?
00103                               0: 
00104                               base::m_stack.size() - 1);
00105 
00106       if (!base::m_stack.empty()) {
00107         base::m_stack.followThen();
00108         base::m_stack.terminate();
00109      }
00110     }
00111     base::m_getTerm.reserve(base::m_stack.size());
00112     base::m_getTerm.append(base::begin() + base::m_getTerm.size(), base::end());
00113   }
00114 
00116   self& operator++() {
00117     increment();
00118     return *this;
00119   }
00121   self operator++(int) {
00122     self copy(*this);
00123     increment();
00124     return copy;
00125   }
00126 };
00127 
00128 END_NAMESPACE_PBORI
00129 
00130 #endif