Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/gen/outer_product_container.h

Go to the documentation of this file.
00001 //  Copyright (C) 2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: outer_product_container.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
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 }} // more::gen
00157 
00158 #endif

Generated on Sat Sep 7 19:11:13 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.