Go to the documentation of this file.00001 #ifndef PolyType_h
00002 #define PolyType_h
00003
00004 #include <boost/iterator/iterator_facade.hpp>
00005 #include <boost/operators.hpp>
00006 #include <boost/foreach.hpp>
00007 #include <iostream>
00008 #include <list>
00009 #include <set>
00010
00011 template<class T> class poly;
00012 template<class T> poly<T> operator+ (const poly<T>&, const char* );
00013 template<class T> poly<T> operator+ (const char*, const poly<T>& );
00014
00015 template<class T>
00016 class poly :
00017 boost::incrementable< poly<T>,
00018 boost::addable< poly<T>,
00019 boost::multipliable< poly<T>,
00020 boost::multipliable2< poly<T>, T,
00021 boost::less_than_comparable< poly<T> > > > > > {
00022
00023 std::list<std::set<T> > columns;
00024
00025 public:
00026
00027 class const_iterator;
00028 typedef T value_type;
00029 typedef typename std::list<std::set<T> >::iterator column_iterator;
00030 typedef typename std::list<std::set<T> >::const_iterator const_column_iterator;
00031 poly() {}
00032 poly(const T& t) {operator+=(t);}
00033
00034 bool operator<(const poly& R) const {
00035 const_column_iterator column(columns.begin()), Rcolumn(R.columns.begin());
00036 while( column!=columns.end() && Rcolumn!=R.columns.end() && *column==*Rcolumn) { ++column; ++Rcolumn; }
00037 return column!=columns.end() && Rcolumn!=R.columns.end() && *column < *Rcolumn;
00038 }
00039 poly operator++() {columns.push_back(std::set<T>()); return *this;}
00040 poly operator+=(const poly& R) { columns.insert(columns.end(),R.columns.begin(),R.columns.end()); return *this;}
00041 poly operator+=(const T& r) { operator++(); return operator*=(r);}
00042 poly operator*=(const T& r) { columns.back().insert(r); return *this;}
00043 poly operator*=(const poly& R) { columns.back().insert(R.begin(),R.end()); return *this;}
00044 friend poly<T> operator+ <> (const poly<T>&, const char*);
00045 friend poly<T> operator+ <> (const char*, const poly<T>&);
00046
00047 const_iterator begin() const { return const_iterator(*this);}
00048 const_iterator end() const { return const_iterator::end_of(*this);}
00049
00050 column_iterator begin_columns() { return columns.begin();}
00051 column_iterator end_columns() { return columns.end();}
00052
00053 const_column_iterator begin_columns() const { return columns.begin();}
00054 const_column_iterator end_columns() const { return columns.end();}
00055
00056 size_t size() const {
00057 if(columns.empty()) return 0;
00058 size_t size=1;
00059 for( const_column_iterator column = columns.begin(); column != columns.end(); ++column)
00060 size *= column->size();
00061 return size;
00062 }
00063
00064 class const_iterator
00065 : public boost::iterator_facade< const_iterator, T const, boost::bidirectional_traversal_tag, T > {
00066 friend class boost::iterator_core_access;
00067
00068 std::list<typename std::set<T>::const_iterator> state;
00069 typename std::list<std::set<T> >::const_iterator begin, end;
00070
00071 typedef typename std::list<typename std::set<T>::const_iterator>::iterator state_iterator;
00072 typedef typename std::list<typename std::set<T>::const_iterator>::const_iterator const_state_iterator;
00073
00074 bool equal(const_iterator const& rhs) const { return std::equal( state.begin(), state.end(), rhs.state.begin() ); }
00075 T dereference() const { T s; for(const_state_iterator istate=state.begin(); istate!=state.end(); ++istate) s+= **istate; return s; }
00076 void increment() {
00077 state_iterator istate = state.begin();
00078 const_column_iterator column = begin;
00079 while( column != end && ++*istate == column->end() ) { ++istate; ++column;}
00080 if( column == end ) {--column; --istate;}
00081 while( istate != state.begin() ) {--istate; *istate = (--column)->begin();}
00082 }
00083 void decrement() {
00084 state_iterator istate = state.begin();
00085 const_column_iterator column = begin;
00086 while( column != end && *istate == column->begin()) { ++istate; ++column;}
00087 if( column != end) --*istate;
00088 while( istate != state.begin() ) {--istate; *istate = --((--column)->end());}
00089 }
00090
00091 public:
00092
00093 const_iterator() {}
00094 const_iterator(const poly& p) : begin(p.begin_columns()), end(p.end_columns()) {
00095 const_column_iterator column = begin;
00096 while(column!=end) state.push_back((column++)->begin());
00097 }
00098 static const_iterator end_of(const poly& p) {
00099 const_iterator it(p);
00100 if(p.size()!=0) *--(it.state.end()) = (--p.end_columns())->end();
00101 return it;
00102 }
00103
00104 };
00105
00106 };
00107
00108 template<class T> poly<T> operator+ (const poly<T>& lhs, const char* rhs ) { return lhs + poly<T>(rhs);}
00109 template<class T> poly<T> operator+ (const char* lhs, const poly<T>& rhs ) { return poly<T>(lhs) + rhs;}
00110
00111 template <class charT, class traits, class T>
00112 inline
00113 std::basic_ostream<charT,traits>& operator<<(std::basic_ostream<charT,traits>& strm, const poly<T>& f) {
00114 BOOST_FOREACH(std::set<T> column, std::make_pair(f.begin_columns(),f.end_columns()))
00115 { strm << "( "; BOOST_FOREACH(T entry, column) strm << entry << ", "; strm << " )" << std::endl; }
00116 return strm;
00117 }
00118
00119 #endif