Skip to content
Snippets Groups Projects
ParseListS.hh 6.56 KiB
Newer Older
sbund's avatar
sbund committed
// $Id$
//
// Copyright (C) 2006
sbund's avatar
sbund committed
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

/** \file

    \idea Add an optional state to the sentinel and an optional
    transition function. See ParseListS.hh for more.

    We should write a baseclass for sentinels which has no \c check()
tho's avatar
tho committed
    member, an empty \c next() member and \c void as the state
    type. This simplifies writing simple sentinels.

    The parse_listS iterator will have to pass the state in addition
    to the current list element to \c check(). The \c next() member
    will be invoked to advance the iterator. It is passer the current
    element and a (non-const) reference to the state which it may
    update. The Parse_ListS constructor must take an arbitrary number
    of additional arguments which are forwarded to the state
    initialization.

    This structure makes it simple to optimize away the overhead if
    the state type is void. If we would always instantiate the
    sentinel, this will always take up space.

    Another possibility would be to always instantiate the sentinel
    and make the baseclass mandatory. The baseclass would then hold
    the current raw iterator. The iterator itself would ONLY include a
    single sentinel instance .. I think, this is the best solution,
    sentinel members then have intrinsic access to the
    state. Arguments are forwarded from the list constructor to the
    Sentinel constructor.
 */

sbund's avatar
sbund committed
#ifndef HH_ParseListS_
#define HH_ParseListS_ 1

// Custom includes
#include <utility> // for std::pair
#include <boost/iterator/iterator_facade.hpp>
#include <boost/utility.hpp> // for boost::noncopyable
#include "ParserBase.hh"

//#include "ParseListS.mpp"
///////////////////////////////hh.p////////////////////////////////////////

sbund's avatar
sbund committed

    template <class Parser, class Sentinel, class Container> class Parse_ListS_wrapper;
    namespace impl {
        template <class Parser, class Sentinel, class Container> class Parse_ListS_iterator;
sbund's avatar
sbund committed
    }

    template <class Parser, class Sentinel, class Iterator=nil, class IPacket=nil>
    struct Parse_ListS : public ParserBase<Iterator,IPacket>
    {
        ///////////////////////////////////////////////////////////////////////////
        // Parser interface

        template <class I=nil, class P=nil>
sbund's avatar
sbund committed
        struct rebind { typedef Parse_ListS<Parser,Sentinel,I,P> parser; };
        typedef Iterator byte_iterator;
sbund's avatar
sbund committed
        Parse_ListS();
        Parse_ListS(Iterator const & i);
sbund's avatar
sbund committed
        unsigned bytes() const;
        bool check(Iterator const & e) const;
        void init() const;

        ///////////////////////////////////////////////////////////////////////////
        // Container interface

        typedef typename Parser::template rebind<Iterator>::parser value_type;
        typedef Sentinel sentinel;
        typedef impl::Parse_ListS_iterator<value_type,sentinel,byte_iterator> iterator;
        typedef unsigned size_type;
        typedef int difference_type;
        typedef std::pair<iterator,iterator> range_type;

        template <class Container>
        struct wrapper { typedef Parse_ListS_wrapper<value_type, Sentinel, Container> t; };

        size_type size() const;
        bool empty() const;

        iterator begin() const;
        iterator end() const;
        range_type range() const;
        range_type value() const;

     private:
        template <class P, class S, class C> friend class Parse_ListS_wrapper;
    };

    /** \brief
sbund's avatar
sbund committed
        Holds a reference to the container !
      */
    template <class Parser, class Sentinel, class Container>
    class Parse_ListS_wrapper
        : public boost::noncopyable
    {
    public:
        ///////////////////////////////////////////////////////////////////////////
        // Types

        typedef Container container;
        typedef Sentinel sentinel;
        typedef typename Parser::byte_iterator byte_iterator;
        typedef Parser value_type;
        typedef impl::Parse_ListS_iterator<value_type,sentinel,byte_iterator> iterator;
        typedef unsigned size_type;
        typedef int difference_type;
        typedef std::pair<iterator,iterator> range_type;

        ///////////////////////////////////////////////////////////////////////////
        ///\name Structors and default members
        ///@{

        template <class P, class S, class I, class IP>
        Parse_ListS_wrapper(Parse_ListS<P,S,I,IP> const & list, Container & container);

        // no default constructor
        // no copy
        // default destructor
        // no conversion constructors

        ///@}
        ///////////////////////////////////////////////////////////////////////////
        ///\name Accessors
        ///@{

        size_type size() const;
        bool empty() const;

        iterator begin() const;
        iterator end() const;
        range_type range() const;

        ///@}
        ///////////////////////////////////////////////////////////////////////////
        ///\name Mutators
        ///@{

        template <class Value> void insert(iterator pos, Value const & t);
        template <class Value> void insert(iterator pos, size_type n, Value const & t);
        template <class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l);

        void erase(iterator pos, size_type n=1);
        void erase(iterator f, iterator l);
        void clear();
sbund's avatar
sbund committed

        ///@}

    protected:

    private:
sbund's avatar
sbund committed
        size_type i_;
        Container & container_;
    };

sbund's avatar
sbund committed

///////////////////////////////hh.e////////////////////////////////////////
//#include "ParseListS.cci"
#include "ParseListS.ct"
#include "ParseListS.cti"
#endif


// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// comment-column: 40
sbund's avatar
sbund committed
// End: