00001
00002
00031
00032
00033
00034 #include "pbori_defs.h"
00035
00036
00037 #include "CTermStack.h"
00038 #include "CTermIter.h"
00039
00040 #ifndef CExpIter_h_
00041 #define CExpIter_h_
00042
00043 BEGIN_NAMESPACE_PBORI
00044
00045
00046 template <class ExpType>
00047 class CExpGenerator {
00048
00049 public:
00050 typedef ExpType value_type;
00051 typedef const value_type& result_type;
00052 typedef typename value_type::size_type size_type;
00053
00055 CExpGenerator(): m_result() {}
00056
00058 template <class SequenceType>
00059 result_type operator()(const SequenceType&) const{
00060 return m_result;
00061 }
00062
00064 void resize(size_type nlen) { m_result.resize(nlen); }
00065
00067 void reserve(size_type nlen) { m_result.reserve(nlen); }
00068
00070 size_type size() const { return m_result.size(); }
00071
00073 template <class Iterator>
00074 void append(Iterator start, Iterator finish) {
00075 while (start != finish){
00076 m_result.push_back(*start);
00077 ++start;
00078 }
00079 }
00080
00081 private:
00082 value_type m_result;
00083 };
00084
00085
00086 template <class NaviType, class ExpType>
00087 struct pbori_base<CExpIter<NaviType, ExpType> > {
00088
00089 typedef CTermStack<NaviType, std::forward_iterator_tag> stack_type;
00090 typedef CTermIter<stack_type, CExpGenerator<ExpType> > type;
00091 };
00092
00093 template <class NaviType, class ExpType>
00094 class CExpIter :
00095 public pbori_base<CExpIter<NaviType, ExpType> >::type {
00096
00097 public:
00099 typedef CExpIter<NaviType, ExpType> self;
00100
00102 typedef typename pbori_base<self>::type base;
00103
00105 CExpIter(NaviType navi): base(navi, typename base::term_generator() ) {
00106 base::m_getTerm.reserve(base::m_stack.size());
00107 base::m_getTerm.append(base::begin(), base::end());
00108 }
00109
00111 CExpIter(): base() {}
00112
00114 void increment() {
00115 assert(!base::m_stack.empty());
00116 if (base::m_stack.markedOne()) {
00117 base::m_stack.clearOne();
00118 }
00119 else {
00120 base::m_stack.next();
00121 base::m_getTerm.resize( base::m_stack.size() == 0 ?
00122 0:
00123 base::m_stack.size() - 1);
00124
00125 if (!base::m_stack.empty()) {
00126 base::m_stack.followThen();
00127 base::m_stack.terminate();
00128 }
00129 }
00130 base::m_getTerm.reserve(base::m_stack.size());
00131 base::m_getTerm.append(base::begin() + base::m_getTerm.size(), base::end());
00132 }
00133
00135 self& operator++() {
00136 increment();
00137 return *this;
00138 }
00140 self operator++(int) {
00141 self copy(*this);
00142 increment();
00143 return copy;
00144 }
00145 };
00146
00147 END_NAMESPACE_PBORI
00148
00149 #endif