欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

finite_state_filter.hpp

Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
HPP
字号:
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)// (C) Copyright 2005-2007 Jonathan Turkanis// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)// See http://www.boost.org/libs/iostreams for documentation.// Adapted from an example of James Kanze, with suggestions from Peter Dimov.// See http://www.gabi-soft.fr/codebase-en.html.#ifndef BOOST_IOSTREAMS_FINITE_STATE_FILTER_HPP_INCLUDED#define BOOST_IOSTREAMS_FINITE_STATE_FILTER_HPP_INCLUDED#include <cassert>#include <cstdio>    // EOF.#include <iostream>  // cin, cout.#include <locale>#include <string>#include <boost/config.hpp>                 // JOIN, member template friends.#include <boost/detail/workaround.hpp>#include <boost/iostreams/categories.hpp>#include <boost/iostreams/char_traits.hpp>#include <boost/iostreams/checked_operations.hpp>   // put_if.#include <boost/iostreams/concepts.hpp>#include <boost/iostreams/detail/ios.hpp>           // openmode.#include <boost/iostreams/filter/stdio.hpp>#include <boost/iostreams/operations.hpp>#include <boost/mpl/begin_end.hpp>#include <boost/mpl/deref.hpp>#include <boost/preprocessor/control/expr_if.hpp>#include <boost/static_assert.hpp>#include <boost/type_traits/is_base_and_derived.hpp>namespace boost { namespace iostreams {//------------------Definition of basic character classes---------------------//struct finite_state_machine_base {    static const int initial_state = 0;        // All-inclusive character class.    struct is_any {        template<typename Ch>        static bool test(Ch, const std::locale&) { return true; }    };        // Locale-sensitive character classes.    #define BOOST_IOSTREAMS_CHARACTER_CLASS(class) \        struct BOOST_JOIN(is_, class) { \            template<typename Ch> \            static bool test(Ch event, const std::locale& loc) \            { return std::BOOST_JOIN(is, class)(event, loc); } \        }; \        /**/    BOOST_IOSTREAMS_CHARACTER_CLASS(alnum)    BOOST_IOSTREAMS_CHARACTER_CLASS(alpha)    BOOST_IOSTREAMS_CHARACTER_CLASS(cntrl)    BOOST_IOSTREAMS_CHARACTER_CLASS(digit)    BOOST_IOSTREAMS_CHARACTER_CLASS(graph)    BOOST_IOSTREAMS_CHARACTER_CLASS(lower)    BOOST_IOSTREAMS_CHARACTER_CLASS(print)    BOOST_IOSTREAMS_CHARACTER_CLASS(punct)    BOOST_IOSTREAMS_CHARACTER_CLASS(space)    BOOST_IOSTREAMS_CHARACTER_CLASS(upper)    BOOST_IOSTREAMS_CHARACTER_CLASS(xdigit)    #undef BOOST_IOSTREAMS_CHARACTER_CLASS};template<typename Ch>struct finite_state_machine_base_ex : finite_state_machine_base {    template<Ch C>    struct is {        static bool test(Ch event, const std::locale&)        {            return event == C;        }    };};//------------------Definition of base class for finite state filters---------//namespace detail {template<typename FiniteStateMachine>class finite_state_filter_impl;} // End namespace detail.template<typename Derived, typename Ch = char>class finite_state_machine : public finite_state_machine_base_ex<Ch> {public:    typedef Ch                                  char_type;    typedef typename char_traits<Ch>::int_type  int_type;    void imbue(const std::locale& loc) { loc_ = loc; }    const std::locale& getloc() const { return loc_; }protected:    finite_state_machine() : off_(0) { }    // Template whose instantiations make up transition table.    template< int State,              typename CharacterClass,              int NextState,              void (Derived::*Action)(char_type) >    struct row {        typedef CharacterClass  character_class;        static const int        state = State;        static const int        next_state = NextState;        static void execute(Derived& d, char_type event)        {            (d.*Action)(event);        }    };    // Stack interface.    bool empty() const    {        return off_ == buf_.size();    }    void push(char c) { buf_ += c; }    char_type pop()    {        char_type result = buf_[off_++];        if (off_ == buf_.size())            clear();        return result;    }    char_type& top() { return buf_[off_]; }    void clear()    {        buf_.clear();        off_ = 0;    }    // Default event handlers.    void on_eof() { }    void skip(char_type) { }#if BOOST_WORKAROUND(__MWERKS__, <= 0x3206)    template<typename Ch>    void _push_impl(Ch c) { push(c); }#endif#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS    template<typename FiniteStateFilter>    friend class detail::finite_state_filter_impl;#else    public:#endif    void on_any(char_type) { }private:    typedef std::basic_string<char_type>     string_type;    typedef typename string_type::size_type  size_type;    std::locale  loc_;    string_type  buf_;    size_type    off_;};#if !BOOST_WORKAROUND(__MWERKS__, <= 0x3206)# define BOOST_IOSTREAMS_FSM(fsm) \    template<typename Ch> \    void push(Ch c) \    { ::boost::iostreams::finite_state_machine<fsm, Ch>::push(c); } \    template<typename Ch> \    void skip(Ch c) { (void) c; } \    /**/#else // #ifndef __MWERKS__# define BOOST_IOSTREAMS_FSM(fsm) \    void push(char c) { this->_push_impl(c); } \    void push(wchar_t c) { this->_push_impl(c); } \    void skip(char c) { (void) c; } \    void skip(wchar_t c) { (void) c; } \    /**/#endif//------------------Definition of finite_state_filter_impl--------------------//namespace detail {template<typename FiniteStateMachine>class finite_state_filter_impl : protected FiniteStateMachine{private:    template<typename First, typename Last>    struct process_event_impl;public:    typedef typename char_type_of<FiniteStateMachine>::type char_type;    finite_state_filter_impl() : state_(FiniteStateMachine::initial_state) { }    template<typename T0>    explicit finite_state_filter_impl(const T0& t0)        : FiniteStateMachine(t0), state_(FiniteStateMachine::initial_state)        { }    template<typename T0, typename T1>    finite_state_filter_impl(const T0& t0, const T1& t1)        : FiniteStateMachine(t0, t1), state_(FiniteStateMachine::initial_state)        { }    template<typename T0, typename T1, typename T2>    finite_state_filter_impl(const T0& t0, const T1& t1, const T2& t2)        : FiniteStateMachine(t0, t1, t2),          state_(FiniteStateMachine::initial_state)        { }protected:    void process_event(char_type c)    {        typedef typename FiniteStateMachine::transition_table  transitions;        typedef typename mpl::begin<transitions>::type         first;        typedef typename mpl::end<transitions>::type           last;        state_ = process_event_impl<first, last>::execute(*this, state_, c);    }    int& state() { return state_; }    void reset()    {        state_ = FiniteStateMachine::initial_state;        this->clear();    }private:    template<typename First, typename Last>    struct process_event_impl {        static int execute(FiniteStateMachine& fsm, int state, char_type event)        {            typedef typename mpl::deref<First>::type  rule;            typedef typename mpl::next<First>::type   next;            typedef typename rule::character_class    character_class;            if ( state == rule::state &&                 character_class::test(event, fsm.getloc()) )            {                // Rule applies.                rule::execute(fsm, event);                return rule::next_state;            }            // Rule is inapplicable: try next rule.            return process_event_impl<next, Last>::execute(fsm, state, event);        }    };    template<typename Last>    struct process_event_impl<Last, Last> {        static int execute(FiniteStateMachine& fsm, int state, char_type c)        {            on_any(fsm, c);            return state;        }    };#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) /* Tru64 */ \ || BOOST_WORKAROUND(__MWERKS__,   BOOST_TESTED_AT(0x3205))   /* CW9.4 */    public:#endif    template<typename FSM>    static void on_any(FSM& fsm, char_type c) { fsm.on_any(c); }private:    int state_;};} // End namespace detail.//------------------Definition of finite_state_filter-------------------------//template<typename FiniteStateMachine>class finite_state_filter    : public detail::finite_state_filter_impl<FiniteStateMachine>{private:    typedef detail::finite_state_filter_impl<FiniteStateMachine>  base_type;public:    typedef typename base_type::char_type                         char_type;    typedef char_traits<char_type>                                traits_type;    typedef typename base_type::int_type                          int_type;    struct category        : dual_use, filter_tag, closable_tag, localizable_tag        { };    finite_state_filter() : flags_(0) { }    template<typename T0>    finite_state_filter(const T0& t0)        : base_type(t0), flags_(0)        { }    template<typename T0, typename T1>    finite_state_filter(const T0& t0, const T1& t1)        : base_type(t0, t1), flags_(0)        { }    template<typename T0, typename T1, typename T2>    finite_state_filter(const T0& t0, const T1& t1, const T2& t2)        : base_type(t0, t1, t2), flags_(0)        { }    template<typename Source>    int_type get(Source& src)    {        assert((flags_ & f_write) == 0);        flags_ |= f_read;        while (true) {            if ((flags_ & f_eof) == 0) {                // Read a character and process it.                int_type c;                if (traits_type::is_eof(c = iostreams::get(src))) {                    flags_ |= f_eof;                    this->on_eof();                } else if (!traits_type::would_block(c)) {                    this->process_event(c);                }            }            // Return a character, if available.            if (!this->empty())                return this->pop();            else if ((flags_ & f_eof) != 0)                return traits_type::eof();        }    }    template<typename Sink>    bool put(Sink& dest, char_type c)    {        assert((flags_ & f_read) == 0);        flags_ |= f_write;        this->process_event(c);        while (!this->empty() && iostreams::put(dest, this->top()))            this->pop();        return true;    }    template<typename Device>    void close(Device& dev, BOOST_IOS::openmode which)    {        if (which == BOOST_IOS::out) {            if (flags_ & f_write)                while (!this->empty())                    iostreams::put_if(dev, this->pop());            this->reset();            flags_ = 0;        }    }private:    enum flags {        f_read    = 1,        f_write   = f_read << 1,        f_eof     = f_write << 1    };    int flags_;};} }       // End namespaces iostreams, boost.#endif // #ifndef BOOST_IOSTREAMS_FINITE_STATE_FILTER_HPP_INCLUDED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -