source: NonGTP/Boost/boost/wave/cpp_iteration_context.hpp @ 857

Revision 857, 7.5 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3    Definition of the preprocessor context
4   
5    http://www.boost.org/
6
7    Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost
8    Software License, Version 1.0. (See accompanying file
9    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10=============================================================================*/
11
12#if !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)
13#define CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED
14
15#include <iterator>
16#include <fstream>
17#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
18#include <sstream>
19#endif
20
21#include <boost/wave/wave_config.hpp>
22#include <boost/wave/cpp_exceptions.hpp>
23#include <boost/wave/language_support.hpp>
24#include <boost/wave/util/file_position.hpp>
25
26///////////////////////////////////////////////////////////////////////////////
27namespace boost {
28namespace wave {
29namespace iteration_context_policies {
30
31///////////////////////////////////////////////////////////////////////////////
32//
33//      The iteration_context_policies templates are policies for the
34//      boost::wave::iteration_context which allows to control, how a given input file
35//      is to be represented by a pair of iterators pointing to the begin and
36//      the end of the resulting input sequence.
37//
38///////////////////////////////////////////////////////////////////////////////
39
40    ///////////////////////////////////////////////////////////////////////////
41    //
42    //  load_file_to_string
43    //
44    //      Loads a file into a string and returns the iterators pointing to
45    //      the beginning and the end of the loaded string.
46    //
47    ///////////////////////////////////////////////////////////////////////////
48    struct load_file_to_string
49    {
50        template <typename IterContextT>
51        class inner
52        {
53        public:
54            template <typename PositionT>
55            static
56            void init_iterators(IterContextT &iter_ctx,
57                PositionT const &act_pos)
58            {
59                typedef typename IterContextT::iterator_type iterator_type;
60               
61                std::ifstream instream(iter_ctx.filename.c_str());
62                if (!instream.is_open()) {
63                    BOOST_WAVE_THROW(preprocess_exception, bad_include_file,
64                        iter_ctx.filename.c_str(), act_pos);
65                }
66                instream.unsetf(std::ios::skipws);
67               
68#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
69            // this is known to be very slow for large files on some systems
70                std::copy (istream_iterator<char>(instream),
71                    istream_iterator<char>(),
72                    std::inserter(iter_ctx.instring, iter_ctx.instring.end()));
73#else
74                iter_ctx.instring = std::string(
75                    std::istreambuf_iterator<char>(instream.rdbuf()),
76                    std::istreambuf_iterator<char>());
77#endif // defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
78
79                iter_ctx.first = iterator_type(iter_ctx.instring.begin(),
80                    iter_ctx.instring.end(), PositionT(iter_ctx.filename),
81                    iter_ctx.language);
82                iter_ctx.last = iterator_type();
83            }
84
85        private:
86            std::string instring;
87        };
88    };
89   
90///////////////////////////////////////////////////////////////////////////////
91//
92//  load_file
93//
94//      The load_file policy opens a given file and returns the wrapped
95//      istreambuf_iterators.
96//
97///////////////////////////////////////////////////////////////////////////////
98    struct load_file
99    {
100        template <typename IterContextT>
101        class inner {
102
103        public:
104            ~inner() { if (instream.is_open()) instream.close(); }
105           
106            template <typename PositionT>
107            static
108            void init_iterators(IterContextT &iter_ctx,
109                PositionT const &act_pos)
110            {
111                typedef typename IterContextT::iterator_type iterator_type;
112               
113                iter_ctx.instream.open(iter_ctx.filename.c_str());
114                if (!iter_ctx.instream.is_open()) {
115                    BOOST_WAVE_THROW(preprocess_exception, bad_include_file,
116                        iter_ctx.filename.c_str(), act_pos);
117                }
118                iter_ctx.instream.unsetf(std::ios::skipws);
119
120                using boost::spirit::make_multi_pass;
121                iter_ctx.first = iterator_type(
122                    make_multi_pass(std::istreambuf_iterator<char>(
123                        iter_ctx.instream.rdbuf())),
124                    make_multi_pass(std::istreambuf_iterator<char>()),
125                    PositionT(iter_ctx.filename), iter_ctx.language);
126                iter_ctx.last = iterator_type();
127            }
128
129        private:
130            std::ifstream instream;
131        };
132    };
133   
134}   // namespace iterattion_context_policies
135
136///////////////////////////////////////////////////////////////////////////////
137// 
138template <typename IteratorT>
139struct base_iteration_context
140{
141public:
142    base_iteration_context(
143            BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0)   
144    :   real_filename(fname), filename(fname), line(1), emitted_lines(1),
145        if_block_depth(if_block_depth)
146    {}
147    base_iteration_context(IteratorT const &first_, IteratorT const &last_,
148            BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0)
149    :   first(first_), last(last_), real_filename(fname), filename(fname),
150        line(1), emitted_lines(1), if_block_depth(if_block_depth)
151    {}
152
153// the actual input stream
154    IteratorT first;            // actual input stream position
155    IteratorT last;             // end of input stream
156    BOOST_WAVE_STRINGTYPE real_filename;  // real name of the current file
157    BOOST_WAVE_STRINGTYPE filename;       // actual processed file
158    unsigned int line;                    // line counter of underlying stream
159    unsigned int emitted_lines;           // count of emitted newlines
160    std::size_t if_block_depth; // depth of #if block recursion
161};
162
163///////////////////////////////////////////////////////////////////////////////
164// 
165template <
166    typename IteratorT,
167    typename InputPolicyT =
168        iteration_context_policies::load_file_to_string
169>
170struct iteration_context
171:   public base_iteration_context<IteratorT>,
172    public InputPolicyT::template
173        inner<iteration_context<IteratorT, InputPolicyT> >
174{
175    typedef IteratorT iterator_type;
176    typedef typename IteratorT::token_type::position_type position_type;
177   
178    typedef iteration_context<IteratorT, InputPolicyT> self_type;
179   
180    iteration_context(BOOST_WAVE_STRINGTYPE const &fname,
181            position_type const &act_pos,
182            boost::wave::language_support language_)
183    :   base_iteration_context<IteratorT>(fname),
184        language(language_)
185    {
186        InputPolicyT::template inner<self_type>::init_iterators(*this, act_pos);
187    }
188   
189    boost::wave::language_support language;
190};
191
192///////////////////////////////////////////////////////////////////////////////
193}   // namespace wave
194}   // namespace boost
195
196#endif // !defined(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED)
Note: See TracBrowser for help on using the repository browser.