liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library
 
    http://www.boost.org/
 
    Copyright (c) 2001-2012 Hartmut Kaiser. 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)
=============================================================================*/
 
#if !defined(BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)
#define BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED
 
#include <boost/assert.hpp>
#include <boost/spirit/include/classic_multi_pass.hpp>
#include <boost/wave/wave_config.hpp>
 
// this must occur after all of the includes and before any code appears
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif
 
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {
namespace util {
 
///////////////////////////////////////////////////////////////////////////////
//
//  class functor_input
//
//      Implementation of the InputPolicy used by multi_pass
//      functor_input gets tokens from a functor
//      Note: the functor must have a typedef for result_type
//            It also must have a static variable of type result_type defined
//            to represent eof that is called eof.
//
//      This functor input policy template is essentially the same as the
//      predefined multi_pass functor_input policy. The difference is,
//      that the first token is not read at initialization time, but only
//      just before returning the first token. Additionally it does not
//      call operator new() twice but only once.
//
///////////////////////////////////////////////////////////////////////////////
struct functor_input {
 
    template <typename FunctorT>
    class inner {
    private:
        typedef typename FunctorT::result_type result_type;
 
    public:
        typedef result_type value_type;
 
    private:
        struct Data {
            Data(FunctorT const &ftor_)
            :   ftor(ftor_), was_initialized(false)
            {}
 
            FunctorT ftor;
            value_type curtok;
            bool was_initialized;
        };
 
        // Needed by compilers not implementing the resolution to DR45. For
        // reference, see
        // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
 
        friend struct Data;
 
    public:
        typedef std::ptrdiff_t difference_type;
        typedef result_type *pointer;
        typedef result_type &reference;
 
    protected:
        inner()
        :   data(0)
        {}
 
        inner(FunctorT const &x)
        :   data(new Data(x))
        {}
 
        inner(inner const &x)
        :   data(x.data)
        {}
 
        void destroy()
        {
            delete data;
            data = 0;
        }
 
        bool same_input(inner const &x) const
        {
            return data == x.data;
        }
 
        void swap(inner &x)
        {
            boost::spirit::classic::impl::mp_swap(data, x.data);
        }
 
        void ensure_initialized() const
        {
            if (data && !data->was_initialized) {
                data->curtok = (data->ftor)();    // get the first token
                data->was_initialized = true;
            }
        }
 
    public:
        reference get_input() const
        {
            ensure_initialized();
            return data->curtok;
        }
 
        void advance_input()
        {
            BOOST_ASSERT(0 != data);
            data->curtok = (data->ftor)();
            data->was_initialized = true;
        }
 
        bool input_at_eof() const
        {
            ensure_initialized();
            return !data || data->curtok == data->ftor.eof;
        }
 
        FunctorT& get_functor() const
        {
            BOOST_ASSERT(0 != data);
            return data->ftor;
        }
 
    private:
        mutable Data *data;
    };
};
 
///////////////////////////////////////////////////////////////////////////////
}   // namespace util
}   // namespace wave
}   // namespace boost
 
// the suffix header occurs after all of the code
#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif
 
#endif // !defined(BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)