CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/CalibTracker/SiStripCommon/interface/poly.h

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