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

more/gen/iterator.h

Go to the documentation of this file.
00001 //  Copyright (C) 1999--2002  Petter Urkedal
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: iterator.h,v 1.2 2002/08/24 13:58:16 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_GEN_ITERATOR_H
00031 #define MORE_GEN_ITERATOR_H
00032 
00033 #include <more/bits/config.h>
00034 #include <iosfwd>
00035 #include <iterator>
00036 
00037 
00038 namespace more {
00039 namespace gen {
00040 
00041   /** \class trivial_iterator_tag iterator.h more/gen/iterator.h
00042    **
00043    ** Iterator category tag for the trivial iterator concept as
00044    ** defined in the standard. However, we can't inject it as the base
00045    ** class of other iterator tags, so care must be taken when writing
00046    ** algorithms. */
00047   struct trivial_iterator_tag {};
00048 
00049   /** \class transforming_iterator iterator.h more/gen/iterator.h
00050    **
00051    ** An iterator which iterate over a transformed range. */
00052   template<typename Iterator, typename Function>
00053     struct transforming_iterator
00054     {
00055         typedef typename std::iterator_traits<Iterator>::iterator_category
00056                 iterator_category;
00057         typedef typename Function::result_type value_type;
00058         typedef typename std::iterator_traits<Iterator>::difference_type
00059                 difference_type;
00060         typedef value_type& reference;
00061         typedef value_type* pointer;
00062 
00063         transforming_iterator() {}
00064         transforming_iterator(transforming_iterator const& x) : it(x.it) {}
00065         explicit transforming_iterator(Iterator const& it0) : it(it0) {}
00066 
00067         transforming_iterator& operator=(transforming_iterator const& rhs)
00068             { it = rhs.it; return *this; }
00069         bool operator==(transforming_iterator const& rhs) const
00070             { return it==rhs.it; }
00071         bool operator!=(transforming_iterator const& rhs) const
00072             { return !operator==(rhs); }
00073         bool operator<(transforming_iterator const& rhs) const
00074             { return it<rhs.it; }
00075 
00076         transforming_iterator& operator++() { ++it; return *this; }
00077         transforming_iterator operator++(int)
00078             { transforming_iterator tmp = *this; ++it; return tmp; }
00079         transforming_iterator& operator--() { --it; return *this; }
00080         transforming_iterator& operator--(int)
00081             { transforming_iterator tmp = *this; --it; return tmp; }
00082 
00083         transforming_iterator& operator+=(int i) { it += i; return *this; }
00084         transforming_iterator& operator-=(int i) { it -= i; return *this; }
00085         int operator-(transforming_iterator const& v) const
00086             { return it - v.it; }
00087 
00088         value_type& operator*() const { return f(*it); }
00089         value_type& operator[](int i) const { return f(it[i]); }
00090         value_type* operator->() const { return &f(*it); }
00091         Iterator sub_iterator() { return it; }
00092 
00093       private:
00094         Iterator it;
00095         Function f;
00096     };
00097 
00098   template<typename T, typename U> inline transforming_iterator<T, U>
00099     operator+(transforming_iterator<T, U> u, int i)
00100     {
00101         u += i;
00102         return u;
00103     }
00104 
00105   template<typename T, typename U> inline transforming_iterator<T, U>
00106     operator+(int i, transforming_iterator<T, U> u)
00107     {
00108         u += i;
00109         return u;
00110     }
00111 
00112   template<typename T, typename U> inline transforming_iterator<T, U>
00113     operator-(transforming_iterator<T, U> u, int i)
00114     {
00115         u -= i;
00116         return u;
00117     }
00118 
00119 
00120   // --- misc ---
00121 
00122   /** \class null_output_iteraton iterator.h more/gen/iterator.h
00123    **
00124    ** An output iterator which discards its output. */
00125   class null_output_iterator
00126   {
00127       typedef std::ptrdiff_t difference_type;
00128       typedef void value_type;
00129       typedef void reference;
00130       typedef void pointer;
00131       typedef std::output_iterator_tag iterator_category;
00132 
00133       struct proxy
00134       {
00135           template<typename T> proxy operator=(const T&x) { return *this; }
00136       };
00137 
00138     public:
00139       proxy operator*() { return proxy(); }
00140       null_output_iterator operator++() { return *this; }
00141       null_output_iterator operator++(int) { return *this; }
00142   };
00143 
00144   /** \class assign_iterator iterator.h more/gen/iterator.h
00145    ** 
00146    ** An output iterator which repeatedly assigns to the same location. */
00147   template<typename T>
00148     struct assign_iterator
00149     {
00150         typedef std::ptrdiff_t difference_type;
00151         typedef void value_type;
00152         typedef void reference;
00153         typedef void pointer;
00154         typedef std::output_iterator_tag iterator_category;
00155         explicit assign_iterator(T& ref_) : ref(&ref_) {}
00156         T& operator*() { return *ref; }
00157         assign_iterator& operator++() { return *this; }
00158         assign_iterator& operator++(int) { return *this; }
00159       private:
00160         T* ref;
00161     };
00162 
00163   template<typename T>
00164     assign_iterator<T>
00165     assigner(T& x)
00166     {
00167         return assign_iterator<T>(x);
00168     }
00169 
00170 
00171   /** \class ostream_iterator iterator.h more/gen/iterator.h
00172    **
00173    ** This is an alternative to \c std::ostream_iterator. This
00174    ** iterator places the string argument between value rather than
00175    ** after. The rationale is that this is a common case, and a
00176    ** separator at the end can easily be inserted added, but redundant
00177    ** separator can not be removed from the stream. This class also
00178    ** extends std::ostream_iterator by allowing the width and
00179    ** precision to be specified.  */
00180   template< typename Value,
00181             typename Char = char, typename Traits = std::char_traits<Char> >
00182     struct ostream_iterator
00183     {
00184         typedef std::ptrdiff_t difference_type;
00185         typedef void value_type;
00186         typedef void reference;
00187         typedef void pointer;
00188         typedef std::output_iterator_tag iterator_category;
00189         typedef Char char_type;
00190         typedef Traits traits_type;
00191         typedef std::basic_ostream<Char, Traits> ostream_type;
00192 
00193         /** Construct an iterator which prints values separated with
00194          ** \a sep to \a os.  Before each value, set \a width and \a
00195          ** precision on \a os if given. */
00196         ostream_iterator(ostream_type& os, char const* sep = "",
00197                          int width = 0, int precision = 0)
00198             : m_os(&os), m_sep(sep),
00199               m_width(width), m_precision(precision),
00200               m_is_first(true) {}
00201 
00202         ostream_iterator&
00203         operator=(Value const& value)
00204         {
00205             if (m_is_first)
00206                 m_is_first = false;
00207             else
00208                 *m_os << m_sep;
00209             if (m_width > 0)
00210                 m_os->width(m_width);
00211             if (m_precision > 0)
00212                 m_os->precision(m_precision);
00213             *m_os << value;
00214             return *this;
00215         }
00216 
00217         ostream_iterator& operator*() { return *this; }
00218         ostream_iterator& operator++() { return *this; }
00219         ostream_iterator& operator++(int) { return *this; }
00220 
00221       private:
00222         ostream_type* m_os;
00223         char const* m_sep;
00224         int m_width, m_precision;
00225         bool m_is_first;
00226     };
00227 
00228 }} // more::gen
00229 
00230 #endif

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