/*============================================================================= | |
Boost.Wave: A Standard compliant C++ preprocessor library | |
Definition of the preprocessor context | |
http://www.boost.org/ | |
Copyright (c) 2001-2011 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(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED) | |
#define CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED | |
#include <iterator> | |
#include <fstream> | |
#if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) | |
#include <sstream> | |
#endif | |
#include <boost/wave/wave_config.hpp> | |
#include <boost/wave/cpp_exceptions.hpp> | |
#include <boost/wave/language_support.hpp> | |
#include <boost/wave/util/file_position.hpp> | |
// #include <boost/spirit/include/iterator/classic_multi_pass.hpp> // make_multi_pass | |
// 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 iteration_context_policies { | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
// The iteration_context_policies templates are policies for the | |
// boost::wave::iteration_context which allows to control, how a given | |
// input file is to be represented by a pair of iterators pointing to the | |
// begin and the end of the resulting input sequence. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
/////////////////////////////////////////////////////////////////////////// | |
// | |
// load_file_to_string | |
// | |
// Loads a file into a string and returns the iterators pointing to | |
// the beginning and the end of the loaded string. | |
// | |
/////////////////////////////////////////////////////////////////////////// | |
struct load_file_to_string | |
{ | |
template <typename IterContextT> | |
class inner | |
{ | |
public: | |
template <typename PositionT> | |
static void init_iterators(IterContextT &iter_ctx, | |
PositionT const &act_pos, language_support language) | |
{ | |
typedef typename IterContextT::iterator_type iterator_type; | |
// read in the file | |
std::ifstream instream(iter_ctx.filename.c_str()); | |
if (!instream.is_open()) { | |
BOOST_WAVE_THROW_CTX(iter_ctx.ctx, preprocess_exception, | |
bad_include_file, iter_ctx.filename.c_str(), act_pos); | |
return; | |
} | |
instream.unsetf(std::ios::skipws); | |
iter_ctx.instring.assign( | |
std::istreambuf_iterator<char>(instream.rdbuf()), | |
std::istreambuf_iterator<char>()); | |
iter_ctx.first = iterator_type( | |
iter_ctx.instring.begin(), iter_ctx.instring.end(), | |
PositionT(iter_ctx.filename), language); | |
iter_ctx.last = iterator_type(); | |
} | |
private: | |
std::string instring; | |
}; | |
}; | |
} // namespace iteration_context_policies | |
/////////////////////////////////////////////////////////////////////////////// | |
// Base class for iteration contexts | |
template <typename ContextT, typename IteratorT> | |
struct base_iteration_context | |
{ | |
enum file_type | |
{ | |
// this iteration context handles ... | |
main_file, // ... the main preprocessed file | |
system_header, // ... a header file included used #include <> | |
user_header // ... a header file included using #include "" | |
}; | |
base_iteration_context(ContextT& ctx_, | |
BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0) | |
: real_filename(fname), real_relative_filename(fname), filename(fname), | |
line(1), emitted_lines(0), if_block_depth(if_block_depth), ctx(ctx_) | |
{} | |
base_iteration_context(ContextT& ctx_, | |
IteratorT const &first_, IteratorT const &last_, | |
BOOST_WAVE_STRINGTYPE const &fname, std::size_t if_block_depth = 0, | |
file_type type = main_file) | |
: first(first_), last(last_), real_filename(fname), | |
real_relative_filename(fname), filename(fname), | |
line(1), emitted_lines(0), if_block_depth(if_block_depth), ctx(ctx_) | |
{} | |
// the actual input stream | |
IteratorT first; // actual input stream position | |
IteratorT last; // end of input stream | |
BOOST_WAVE_STRINGTYPE real_filename; // real name of the current file | |
BOOST_WAVE_STRINGTYPE real_relative_filename; // real relative name of the current file | |
BOOST_WAVE_STRINGTYPE filename; // actual processed file | |
unsigned int line; // line counter of underlying stream | |
unsigned int emitted_lines; // count of emitted newlines | |
std::size_t if_block_depth; // depth of #if block recursion | |
ContextT& ctx; // corresponding context<> object | |
file_type type; // the type of the handled file | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
template < | |
typename ContextT, typename IteratorT, | |
typename InputPolicyT = typename ContextT::input_policy_type | |
> | |
struct iteration_context | |
: public base_iteration_context<ContextT, IteratorT>, | |
public InputPolicyT::template | |
inner<iteration_context<ContextT, IteratorT, InputPolicyT> > | |
{ | |
typedef IteratorT iterator_type; | |
typedef typename IteratorT::token_type::position_type position_type; | |
typedef base_iteration_context<ContextT, IteratorT> base_type; | |
typedef iteration_context<ContextT, IteratorT, InputPolicyT> self_type; | |
iteration_context(ContextT& ctx, BOOST_WAVE_STRINGTYPE const &fname, | |
position_type const &act_pos, | |
boost::wave::language_support language_, | |
typename base_type::file_type type = base_type::main_file) | |
: base_iteration_context<ContextT, IteratorT>(ctx, fname, type) | |
{ | |
InputPolicyT::template inner<self_type>::init_iterators( | |
*this, act_pos, language_); | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
} // 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(CPP_ITERATION_CONTEXT_HPP_00312288_9DDB_4668_AFE5_25D3994FD095_INCLUDED) |