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