PolyBoRi
|
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