00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #ifndef MORE_GEN_OUTER_PRODUCT_CONTAINER_H
00031 #define MORE_GEN_OUTER_PRODUCT_CONTAINER_H
00032 
00033 
00034 #include <iterator>
00035 #include <assert.h>
00036 
00037 
00038 namespace more {
00039 namespace gen {
00040 
00041   template< typename Iterator,
00042             template <typename> class Container,
00043             typename IteratorCategory
00044             = typename std::iterator_traits<Iterator>::iterator_category >
00045     struct outer_product_container {
00046         struct iterator {
00047             typedef std::bidirectional_iterator_tag iterator_category;
00048             typedef Container< typename std::iterator_traits<Iterator>
00049                                ::value_type > value_type;
00050             typedef value_type& reference;
00051             typedef value_type* pointer;
00052 
00053             iterator() : context(0), value(0) {}
00054             iterator(outer_product_container* context_,
00055                      Container<Iterator> const& cur_)
00056                 : context(context_), cur(cur_), value(0) {}
00057             iterator(outer_product_container* context_,
00058                      Container<Iterator> const& cur_,
00059                      Container<Iterator> const& last)
00060                 : context(context_), cur(cur_), value(0) {
00061                 *cur.begin() = *last.begin();
00062                 assert(cur.size() == context->first.size());
00063                 assert(cur.size() == context->last.size());
00064             }
00065             iterator(iterator const& x)
00066                 : context(x.context), cur(x.cur), value(0) {}
00067             iterator& operator=(iterator const x) {
00068                 this->~iterator();
00069                 new(this) iterator(x);
00070             }
00071             ~iterator() { delete value; }
00072             iterator& operator++() {
00073                 delete value;
00074                 value = 0;
00075                 typename Container<Iterator>::iterator
00076                     it_cur = cur.end(),
00077                     it_first = context->first.end(),
00078                     it_last = context->last.end();
00079                 assert(it_cur != cur.begin());
00080                 while (--it_cur != cur.begin()) {
00081                     --it_first, --it_last;
00082                     if (++*it_cur != *it_last) return *this;
00083                     *it_cur = *it_first;
00084                 }
00085                 ++*it_cur;
00086                 return *this;
00087             }
00088             iterator& operator--() {
00089                 delete value;
00090                 value = 0;
00091                 typename Container<Iterator>::iterator
00092                     it_cur = cur.end(),
00093                     it_first = context->first.end(),
00094                     it_last = context->last.end();
00095                 assert(it_cur != cur.begin());
00096                 while (--it_cur != cur.begin()) {
00097                     --it_first, --it_last;
00098                     if (--*it_cur != *it_first) return *this;
00099                     *it_cur = *it_last;
00100                 }
00101                 --*it_cur;
00102                 return *this;
00103             }
00104             iterator operator++(int) {
00105                 iterator tmp = *this;
00106                 ++*this;
00107                 return tmp;
00108             }
00109             iterator operator--(int) {
00110                 iterator tmp = *this;
00111                 --*this;
00112                 return tmp;
00113             }
00114             bool operator==(iterator const& rhs) const {
00115                 return cur == rhs.cur;
00116             }
00117             bool operator!=(iterator const& rhs) const {
00118                 return cur != rhs.cur;
00119             }
00120 
00121             reference operator*() { update_value(); return *value; }
00122             pointer operator->() { update_value(); return value; }
00123 
00124           private:
00125             void update_value() {
00126                 if (value == 0) {
00127                     value = new value_type;
00128                     typename Container<Iterator>::iterator
00129                         it_it = cur.begin();
00130                     while (it_it != cur.end()) {
00131                         value->insert(value->end(), **it_it);
00132                         ++it_it;
00133                     }
00134                 }
00135             }
00136             outer_product_container* context;
00137             Container<Iterator> cur;
00138             value_type* value;
00139         };
00140 
00141         outer_product_container() {}
00142 
00143         void insert_component(Iterator comp_begin, Iterator comp_end) {
00144             first.insert(first.end(), comp_begin);
00145             last.insert(last.end(), comp_end);
00146         }
00147 
00148         iterator begin() { return iterator(this, first); }
00149         iterator end() { return iterator(this, first, last); }
00150 
00151       private:
00152         Container<Iterator> first;
00153         Container<Iterator> last;
00154     };
00155 
00156 }} 
00157 
00158 #endif