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

more/gen/view.h

Go to the documentation of this file.
00001 //  Copyright (C) 2000--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: view.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_GEN_VIEW_H
00031 #define MORE_GEN_VIEW_H
00032 
00033 #include <iterator>
00034 
00035 
00036 namespace more {
00037 namespace gen {
00038 
00039   //  TODO.  The two if-view assumes the subiterator is bidirectional
00040   //  or better, though if-views are meaningful also for forward and
00041   //  input iterators.
00042 
00043   template< typename Subiterator, typename Filter >
00044     struct if_view
00045     {
00046         typedef Subiterator subiterator;
00047         typedef std::iterator_traits<subiterator> subiterator_traits;
00048         typedef typename subiterator_traits::value_type value_type;
00049 
00050         struct iterator
00051             : std::iterator<std::bidirectional_iterator_tag, value_type>
00052         {
00053             typedef typename if_view::value_type value_type;
00054             typedef iterator self;
00055 
00056             iterator() {}
00057             iterator(if_view* context_,
00058                      subiterator subit_)
00059                 : context(context_), subit(subit_) {}
00060             iterator(self const& it)
00061                 : context(it.context), subit(it.subit) {}
00062             self& operator=(self const& rhs) {
00063                 context = rhs.context;
00064                 subit = rhs.subit;
00065                 return *this;
00066             }
00067 
00068             bool operator==(self const& rhs) const
00069             { return subit == rhs.subit; }
00070             bool operator!=(self const& rhs) const
00071             { return subit != rhs.subit; }
00072 
00073             self& operator++() {
00074                 do ++subit;
00075                 while (subit != context->last && !context->test(*subit));
00076                 return *this;
00077             }
00078             self operator++(int) {
00079                 self tmp = *this;
00080                 ++*this;
00081                 return tmp;
00082             }
00083             self& operator--() {
00084                 do --subit;
00085                 while (subit != context->first && !context->test(*subit));
00086                 return *this;
00087             }
00088             self operator--(int) {
00089                 self tmp = *this;
00090                 --*this;
00091                 return tmp;
00092             }
00093 
00094             value_type operator*() { return *subit; }
00095             value_type* operator->() { return &(*subit); }
00096 
00097           private:
00098             if_view* context;
00099             subiterator subit;
00100         };
00101 
00102         if_view() {}
00103         if_view(Subiterator first_, Subiterator last_,
00104                      Filter const& test_)
00105             : first(first_), last(last_), test(test_) { fix_bounds(); }
00106         if_view(Subiterator first_, Subiterator last_)
00107             : first(first_), last(last_) { fix_bounds(); }
00108         if_view(if_view const& x)
00109             : first(x.first), last(x.last), test(x.test) {}
00110         if_view& operator=(if_view const& rhs) {
00111             first = rhs.first;
00112             last = rhs.last;
00113             test = rhs.test;
00114             return *this;
00115         }
00116 
00117         iterator begin() { return iterator(this, first); }
00118         iterator end() { return iterator(this, last); }
00119         subiterator sub_begin() { return first; }
00120         subiterator sub_end() { return last; }
00121 
00122       private:
00123         void fix_bounds() {
00124             while (first != last && !test(*first))  ++first;
00125             if (first != last) {
00126                 --last;
00127                 while (first != last && !test(*last))  --last;
00128                 ++last;
00129             }
00130         }
00131 
00132         subiterator first, last;
00133         Filter test;
00134         friend class iterator;
00135     };
00136 
00137   template< typename Subiterator, typename Filter, typename Transform >
00138     struct transform_if_view
00139     {
00140         typedef Subiterator subiterator;
00141         typedef std::iterator_traits<subiterator> subiterator_traits;
00142         typedef typename Transform::result_type value_type;
00143 
00144         struct iterator
00145             : std::iterator<std::bidirectional_iterator_tag, value_type>
00146         {
00147             typedef typename transform_if_view::value_type value_type;
00148             typedef iterator self;
00149 
00150             iterator() {}
00151             iterator(transform_if_view* context_,
00152                      subiterator subit_)
00153                 : context(context_), subit(subit_) {}
00154             iterator(self const& it)
00155                 : context(it.context), subit(it.subit) {}
00156             self& operator=(self const& rhs) {
00157                 context = rhs.context;
00158                 subit = rhs.subit;
00159                 return *this;
00160             }
00161 
00162             bool operator==(self const& rhs) const
00163             { return subit == rhs.subit; }
00164             bool operator!=(self const& rhs) const
00165             { return subit != rhs.subit; }
00166 
00167             self& operator++() {
00168                 do ++subit;
00169                 while (subit != context->last && !context->test(*subit));
00170                 return *this;
00171             }
00172             self operator++(int) {
00173                 self tmp = *this;
00174                 ++*this;
00175                 return tmp;
00176             }
00177             self& operator--() {
00178                 do --subit;
00179                 while (subit != context->first && !context->test(*subit));
00180                 return *this;
00181             }
00182             self operator--(int) {
00183                 self tmp = *this;
00184                 --*this;
00185                 return tmp;
00186             }
00187 
00188             value_type operator*() { return context->trn(*subit); }
00189             value_type* operator->() { return &(context->trn(*subit)); }
00190 
00191           private:
00192             transform_if_view* context;
00193             subiterator subit;
00194         };
00195 
00196         transform_if_view() {}
00197         transform_if_view(Subiterator first_, Subiterator last_,
00198                           Filter const& test_, Transform const& trn_)
00199             : first(first_), last(last_),
00200               test(test_), trn(trn_) { fix_bounds(); }
00201         transform_if_view(Subiterator first_, Subiterator last_,
00202                           Filter const& test_)
00203             : first(first_), last(last_), test(test_)  { fix_bounds(); }
00204         transform_if_view(Subiterator first_, Subiterator last_)
00205             : first(first_), last(last_) { fix_bounds(); }
00206         transform_if_view(transform_if_view const& x)
00207             : first(x.first), last(x.last), test(x.test) {}
00208         transform_if_view& operator=(transform_if_view const& rhs) {
00209             first = rhs.first;
00210             last = rhs.last;
00211             test = rhs.test;
00212             trn = rhs.trn;
00213             return *this;
00214         }
00215 
00216         iterator begin() { return iterator(this, first); }
00217         iterator end() { return iterator(this, last); }
00218         subiterator sub_begin() { return first; }
00219         subiterator sub_end() { return last; }
00220 
00221       private:
00222         void fix_bounds() {
00223             while (first != last && !test(*first))  ++first;
00224             if (first != last) {
00225                 --last;
00226                 while (first != last && !test(*last))  --last;
00227                 ++last;
00228             }
00229         }
00230 
00231         subiterator first, last;
00232         Filter test;
00233         Transform trn;
00234         friend class iterator;
00235     };
00236 
00237 }} // more::gen
00238 
00239 #endif

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