00001
00002
00014
00015
00016 #ifndef polybori_iterators_CExpIter_h_
00017 #define polybori_iterators_CExpIter_h_
00018
00019
00020 #include <polybori/pbori_defs.h>
00021
00022
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