Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:14:44

0001 #ifndef PolyType_h
0002 #define PolyType_h
0003 
0004 #include <boost/iterator/iterator_facade.hpp>
0005 #include <boost/operators.hpp>
0006 #include <iostream>
0007 #include <list>
0008 #include <set>
0009 
0010 template <class T>
0011 class poly;
0012 template <class T>
0013 poly<T> operator+(const poly<T>&, const char*);
0014 template <class T>
0015 poly<T> operator+(const char*, const poly<T>&);
0016 
0017 template <class T>
0018 class poly
0019     : boost::incrementable<
0020           poly<T>,
0021           boost::addable<
0022               poly<T>,
0023               boost::multipliable<poly<T>, boost::multipliable2<poly<T>, T, boost::less_than_comparable<poly<T> > > > > > {
0024   std::list<std::set<T> > columns;
0025 
0026 public:
0027   class const_iterator;
0028   typedef T value_type;
0029   typedef typename std::list<std::set<T> >::iterator column_iterator;
0030   typedef typename std::list<std::set<T> >::const_iterator const_column_iterator;
0031   poly() {}
0032   poly(const T& t) { operator+=(t); }
0033 
0034   bool operator<(const poly& R) const {
0035     const_column_iterator column(columns.begin()), Rcolumn(R.columns.begin());
0036     while (column != columns.end() && Rcolumn != R.columns.end() && *column == *Rcolumn) {
0037       ++column;
0038       ++Rcolumn;
0039     }
0040     return column != columns.end() && Rcolumn != R.columns.end() && *column < *Rcolumn;
0041   }
0042   poly operator++() {
0043     columns.push_back(std::set<T>());
0044     return *this;
0045   }
0046   poly operator+=(const poly& R) {
0047     columns.insert(columns.end(), R.columns.begin(), R.columns.end());
0048     return *this;
0049   }
0050   poly operator+=(const T& r) {
0051     operator++();
0052     return operator*=(r);
0053   }
0054   poly operator*=(const T& r) {
0055     columns.back().insert(r);
0056     return *this;
0057   }
0058   poly operator*=(const poly& R) {
0059     columns.back().insert(R.begin(), R.end());
0060     return *this;
0061   }
0062   friend poly<T> operator+<>(const poly<T>&, const char*);
0063   friend poly<T> operator+<>(const char*, const poly<T>&);
0064 
0065   const_iterator begin() const { return const_iterator(*this); }
0066   const_iterator end() const { return const_iterator::end_of(*this); }
0067 
0068   auto const& getColumns() const { return columns; }
0069   auto& getColumns() { return columns; }
0070 
0071   size_t size() const {
0072     if (columns.empty())
0073       return 0;
0074     size_t size = 1;
0075     for (const_column_iterator column = columns.begin(); column != columns.end(); ++column)
0076       size *= column->size();
0077     return size;
0078   }
0079 
0080   class const_iterator : public boost::iterator_facade<const_iterator, T const, boost::bidirectional_traversal_tag, T> {
0081     friend class boost::iterator_core_access;
0082 
0083     std::list<typename std::set<T>::const_iterator> state;
0084     typename std::list<std::set<T> >::const_iterator begin, end;
0085 
0086     typedef typename std::list<typename std::set<T>::const_iterator>::iterator state_iterator;
0087     typedef typename std::list<typename std::set<T>::const_iterator>::const_iterator const_state_iterator;
0088 
0089     bool equal(const_iterator const& rhs) const { return std::equal(state.begin(), state.end(), rhs.state.begin()); }
0090     T dereference() const {
0091       T s;
0092       for (const_state_iterator istate = state.begin(); istate != state.end(); ++istate)
0093         s += **istate;
0094       return s;
0095     }
0096     void increment() {
0097       state_iterator istate = state.begin();
0098       const_column_iterator column = begin;
0099       while (column != end && ++*istate == column->end()) {
0100         ++istate;
0101         ++column;
0102       }
0103       if (column == end) {
0104         --column;
0105         --istate;
0106       }
0107       while (istate != state.begin()) {
0108         --istate;
0109         *istate = (--column)->begin();
0110       }
0111     }
0112     void decrement() {
0113       state_iterator istate = state.begin();
0114       const_column_iterator column = begin;
0115       while (column != end && *istate == column->begin()) {
0116         ++istate;
0117         ++column;
0118       }
0119       if (column != end)
0120         --*istate;
0121       while (istate != state.begin()) {
0122         --istate;
0123         *istate = --((--column)->end());
0124       }
0125     }
0126 
0127   public:
0128     const_iterator() {}
0129     const_iterator(const poly& p) : begin(p.getColumns().begin()), end(p.getColumns().end()) {
0130       const_column_iterator column = begin;
0131       while (column != end)
0132         state.push_back((column++)->begin());
0133     }
0134     static const_iterator end_of(const poly& p) {
0135       const_iterator it(p);
0136       if (p.size() != 0)
0137         *--(it.state.end()) = (--p.getColumns().end())->end();
0138       return it;
0139     }
0140   };
0141 };
0142 
0143 template <class T>
0144 poly<T> operator+(const poly<T>& lhs, const char* rhs) {
0145   return lhs + poly<T>(rhs);
0146 }
0147 template <class T>
0148 poly<T> operator+(const char* lhs, const poly<T>& rhs) {
0149   return poly<T>(lhs) + rhs;
0150 }
0151 
0152 template <class charT, class traits, class T>
0153 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& strm, const poly<T>& f) {
0154   for (auto const& column : f.getColumns()) {
0155     strm << "( ";
0156     for (auto const& entry : column)
0157       strm << entry << ", ";
0158     strm << " )" << std::endl;
0159   }
0160   return strm;
0161 }
0162 
0163 #endif