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

ApplyVisitor.h

00001 #ifndef _STR_ApplyVisitor_H_  // -*-c++-*-
00002 
00003 /*
00004  * Copyright 1991-2002 Eric M. Hopper <hopper@omnifarious.org>
00005  * 
00006  *     This program is free software; you can redistribute it and/or modify it
00007  *     under the terms of the GNU Lesser General Public License as published
00008  *     by the Free Software Foundation; either version 2 of the License, or
00009  *     (at your option) any later version.
00010  * 
00011  *     This program is distributed in the hope that it will be useful, but
00012  *     WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *     Lesser General Public License for more details.
00015  * 
00016  *     You should have received a copy of the GNU Lesser General Public
00017  *     License along with this program; if not, write to the Free Software
00018  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #ifdef __GNUG__
00022 #  pragma interface
00023 #endif
00024 
00025 /* $Header: /home/hopper/src/cvs/C++/StrMod/StrMod/ApplyVisitor.h,v 1.5 2002/08/29 00:58:04 hopper Exp $ */
00026 
00027 // For a log, see ../ChangeLog
00028 
00029 #include <StrMod/UseTrackingVisitor.h>
00030 
00031 #define _STR_ApplyVisitor_H_
00032 
00033 namespace strmod {
00034 namespace strmod {
00035 
00036 class StrChunkPtr;
00037 
00038 /** \class ApplyVisitor_Base ApplyVisitor.h StrMod/ApplyVisitor.h
00039  * A base class for the ApplyVisitor template that factors out the common code
00040  * so there aren't tons of duplicates all over creation.
00041  *
00042  * This defines functions that don't vary at all no matter what type you give
00043  * to ApplyVisitor.  This will result in less redundant code being duplicated
00044  * for instances of ApplyVisitor<T> with different T.
00045 
00046 */
00047 class ApplyVisitor_Base : public UseTrackingVisitor {
00048  public:
00049    static const STR_ClassIdent identifier;
00050 
00051    /** \brief This constructor will set up apply to visit the given chunk.
00052     *
00053     * @param chunk The chunk to go through.
00054     */
00055    ApplyVisitor_Base(const StrChunkPtr &chunk);
00056    /** \brief This constructor will set up apply to visit the section of the
00057     * given chunk described by extent.
00058     *
00059     * @param chunk The chunk to go through.
00060     * @param extent Which part of the chunk to go through.
00061     */
00062    ApplyVisitor_Base(const StrChunkPtr &chunk, LinearExtent &extent);
00063    /** Whee, its a destructor, and since this class has no state that won't
00064     * destruct itself, it doesn't do much.
00065     */
00066    virtual ~ApplyVisitor_Base()                         { }
00067 
00068    virtual int AreYouA(const lcore::ClassIdent &cid) const {
00069       return((identifier == cid) || UseTrackingVisitor::AreYouA(cid));
00070    }
00071 
00072    /** \brief Visits every data block according to the parameters given in
00073     * the constructor.
00074    */
00075    void apply();
00076 
00077  protected:
00078    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00079 
00080    virtual void use_visitStrChunk(const StrChunkPtr &chunk,
00081                                   const LinearExtent &used)
00082       throw(halt_visitation)
00083    {
00084    }
00085 
00086    virtual void use_visitDataBlock(const void *start, size_t len,
00087                                    const void *realstart, size_t reallen)
00088       throw(halt_visitation) = 0;
00089 
00090  private:
00091    const StrChunkPtr chunk_;
00092    const bool extent_used_;
00093    const LinearExtent extent_;
00094 };
00095 
00096 //---
00097 
00098 /** \class ApplyVisitor ApplyVisitor.h StrMod/ApplyVisitor.h
00099  * A template class that applies a functor (can be a function pointer) to each
00100  * chunk of bytes in a StrChunk containment hierarchy.
00101  *
00102  * The functor must accept this signature <code>any functor(const void *,
00103  * size_t)</code>.
00104  */
00105 template <class _Function>
00106 class ApplyVisitor : public ApplyVisitor_Base {
00107  public:
00108    /**
00109     * \brief Does what ApplyVisitor_Base::ApplyVisitor_Base(const StrChunkPtr
00110     * &) does.
00111     *
00112     * @param chunk The chunk to go through.
00113     * @param func The functor to run on every data extent.
00114     */
00115    inline ApplyVisitor(const StrChunkPtr &chunk, _Function &func);
00116    /**
00117     * \brief Does what ApplyVisitor_Base::ApplyVisitor_Base(const StrChunkPtr
00118     * &, LinearExtent &) does.
00119     *
00120     * @param chunk The chunk to go through.
00121     * @param extent The portion of the chunk to go through.
00122     * @param func The functor to run on every data extent.
00123     */
00124    inline ApplyVisitor(const StrChunkPtr &chunk, const LinearExtent &extent,
00125                        _Function &func);
00126    /** Whee, its a destructor, and since this class has no state it
00127     * 'owns', it doesn't do much.
00128     */
00129    inline virtual ~ApplyVisitor();
00130 
00131  protected:
00132    inline virtual void use_visitDataBlock(const void *start, size_t len,
00133                                           const void *realstart, size_t reallen)
00134       throw(halt_visitation);
00135 
00136  private:
00137    _Function &func_;
00138 };
00139 
00140 //-----------------------------inline functions--------------------------------
00141 
00142 template <class _Function> inline
00143 ApplyVisitor<_Function>::ApplyVisitor(const StrChunkPtr &chunk, _Function &func)
00144      : ApplyVisitor_Base(chunk), func_(func)
00145 {
00146 }
00147 
00148 template <class _Function> inline
00149 ApplyVisitor<_Function>::ApplyVisitor(const StrChunkPtr &chunk,
00150                                       const LinearExtent &extent,
00151                                       _Function &func)
00152      : ApplyVisitor_Base(chunk, extent), func_(func)
00153 {
00154 }
00155 
00156 template <class _Function> inline
00157 ApplyVisitor<_Function>::~ApplyVisitor()
00158 {
00159 }
00160 
00161 template <class _Function> inline void
00162 ApplyVisitor<_Function>::use_visitDataBlock(const void *start, size_t len,
00163                                             const void *realstart, size_t reallen)
00164    throw(halt_visitation)
00165 {
00166    func_(start, len);
00167 }
00168 
00169 /** A function to hide the rather odd syntax for using the ApplyVisitor class.
00170  *
00171  * Much like the STL for_each function, but this one iterates over the data
00172  * extents making up a StrChunk.
00173  *
00174  * @param chunk The chunk to iterate over.
00175  * @param func The functor to apply.
00176  */
00177 template <class _Function>
00178 inline void for_each(const StrChunkPtr &chunk, _Function &func)
00179 {
00180    ApplyVisitor<_Function> av(chunk, func);
00181    av.apply();
00182 }
00183 
00184 /** A function to hide the rather odd syntax for using the ApplyVisitor class.
00185  *
00186  * Much like the STL for_each function, but this one iterates over the data
00187  * extents making up the section of the StrChunk described by extent.
00188  *
00189  * @param chunk The chunk to iterate over.
00190  * @param extent Which LinearExtent of the chunk to iterator over.
00191  * @param func The functor to apply.
00192  */
00193 template <class _Function>
00194 inline void for_each(const StrChunkPtr &chunk, const LinearExtent &extent,
00195                      _Function &func)
00196 {
00197    ApplyVisitor<_Function> av(chunk, extent, func);
00198    av.apply();
00199 }
00200 
00201 };  // namespace strmod
00202 };  // namespace strmod
00203 
00204 #endif

Generated on Wed Jan 29 00:32:43 2003 for libNet by doxygen1.3-rc1