os/ossrv/ossrv_pub/boost_apis/boost/wave/cpp_context.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*=============================================================================
sl@0
     2
    Boost.Wave: A Standard compliant C++ preprocessor library
sl@0
     3
    Definition of the preprocessor context
sl@0
     4
    
sl@0
     5
    http://www.boost.org/
sl@0
     6
sl@0
     7
    Copyright (c) 2001-2007 Hartmut Kaiser. Distributed under the Boost
sl@0
     8
    Software License, Version 1.0. (See accompanying file
sl@0
     9
    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
    10
=============================================================================*/
sl@0
    11
sl@0
    12
#if !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
sl@0
    13
#define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED
sl@0
    14
sl@0
    15
#include <string>
sl@0
    16
#include <vector>
sl@0
    17
#include <stack>
sl@0
    18
sl@0
    19
#include <boost/concept_check.hpp>
sl@0
    20
#include <boost/noncopyable.hpp>
sl@0
    21
#include <boost/filesystem/path.hpp>
sl@0
    22
sl@0
    23
#include <boost/wave/wave_config.hpp>
sl@0
    24
#if BOOST_WAVE_SERIALIZATION != 0
sl@0
    25
#include <boost/serialization/serialization.hpp>
sl@0
    26
#include <boost/wave/wave_config_constant.hpp>
sl@0
    27
#endif
sl@0
    28
#include <boost/wave/token_ids.hpp>
sl@0
    29
sl@0
    30
#include <boost/wave/util/unput_queue_iterator.hpp>
sl@0
    31
#include <boost/wave/util/cpp_ifblock.hpp>
sl@0
    32
#include <boost/wave/util/cpp_include_paths.hpp>
sl@0
    33
#include <boost/wave/util/iteration_context.hpp>
sl@0
    34
#include <boost/wave/util/cpp_iterator.hpp>
sl@0
    35
#include <boost/wave/util/cpp_macromap.hpp>
sl@0
    36
sl@0
    37
#include <boost/wave/preprocessing_hooks.hpp>
sl@0
    38
#include <boost/wave/whitespace_handling.hpp>
sl@0
    39
#include <boost/wave/cpp_iteration_context.hpp>
sl@0
    40
#include <boost/wave/language_support.hpp>
sl@0
    41
sl@0
    42
// this must occur after all of the includes and before any code appears
sl@0
    43
#ifdef BOOST_HAS_ABI_HEADERS
sl@0
    44
#include BOOST_ABI_PREFIX
sl@0
    45
#endif
sl@0
    46
sl@0
    47
///////////////////////////////////////////////////////////////////////////////
sl@0
    48
namespace boost {
sl@0
    49
namespace wave {
sl@0
    50
sl@0
    51
///////////////////////////////////////////////////////////////////////////////
sl@0
    52
// 
sl@0
    53
//  The C preprocessor context template class
sl@0
    54
//
sl@0
    55
//      The boost::wave::context template is the main interface class to 
sl@0
    56
//      control the behaviour of the preprocessing engine.
sl@0
    57
//
sl@0
    58
//      The following template parameters has to be supplied:
sl@0
    59
//
sl@0
    60
//      IteratorT       The iterator type of the underlying input stream
sl@0
    61
//      LexIteratorT    The lexer iterator type to use as the token factory
sl@0
    62
//      InputPolicyT    The input policy type to use for loading the files
sl@0
    63
//                      to be included. This template parameter is optional and 
sl@0
    64
//                      defaults to the 
sl@0
    65
//                          iteration_context_policies::load_file_to_string
sl@0
    66
//                      type.
sl@0
    67
//      HooksT          The hooks policy to use for different notification 
sl@0
    68
//                      callbacks. This template parameter is optional and
sl@0
    69
//                      defaults to the
sl@0
    70
//                          context_policies::default_preprocessing_hooks
sl@0
    71
//                      type.
sl@0
    72
//
sl@0
    73
///////////////////////////////////////////////////////////////////////////////
sl@0
    74
sl@0
    75
template <
sl@0
    76
    typename IteratorT,
sl@0
    77
    typename LexIteratorT, 
sl@0
    78
    typename InputPolicyT = iteration_context_policies::load_file_to_string,
sl@0
    79
    typename HooksT = context_policies::eat_whitespace<typename LexIteratorT::token_type>
sl@0
    80
>
sl@0
    81
class context : private boost::noncopyable
sl@0
    82
{
sl@0
    83
public:
sl@0
    84
sl@0
    85
// concept checks
sl@0
    86
// the given iterator shall be at least a forward iterator type
sl@0
    87
    BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);
sl@0
    88
    
sl@0
    89
// public typedefs
sl@0
    90
    typedef typename LexIteratorT::token_type       token_type;
sl@0
    91
    typedef context<IteratorT, LexIteratorT, InputPolicyT, HooksT> 
sl@0
    92
        self_type;
sl@0
    93
    
sl@0
    94
    typedef IteratorT                               target_iterator_type;
sl@0
    95
    typedef LexIteratorT                            lexer_type;
sl@0
    96
    typedef pp_iterator<self_type>                  iterator_type;
sl@0
    97
sl@0
    98
    typedef InputPolicyT                            input_policy_type;
sl@0
    99
    typedef typename token_type::position_type      position_type;
sl@0
   100
sl@0
   101
    
sl@0
   102
// type of a token sequence
sl@0
   103
    typedef std::list<token_type, boost::fast_pool_allocator<token_type> > 
sl@0
   104
        token_sequence_type;
sl@0
   105
// types of the policies
sl@0
   106
    typedef HooksT                                  hook_policy_type;
sl@0
   107
    
sl@0
   108
private:
sl@0
   109
// stack of shared_ptr's to the pending iteration contexts 
sl@0
   110
    typedef boost::shared_ptr<base_iteration_context<lexer_type> > 
sl@0
   111
        iteration_ptr_type;
sl@0
   112
    typedef boost::wave::util::iteration_context_stack<iteration_ptr_type> 
sl@0
   113
            iteration_context_stack_type;
sl@0
   114
    typedef typename iteration_context_stack_type::size_type iter_size_type;
sl@0
   115
sl@0
   116
    context *this_() { return this; }           // avoid warning in constructor
sl@0
   117
    
sl@0
   118
public:
sl@0
   119
    context(target_iterator_type const &first_, target_iterator_type const &last_, 
sl@0
   120
            char const *fname = "<Unknown>", HooksT const &hooks_ = HooksT())
sl@0
   121
    :   first(first_), last(last_), filename(fname)
sl@0
   122
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
sl@0
   123
        , current_filename(fname)
sl@0
   124
#endif 
sl@0
   125
        , macros(*this_())
sl@0
   126
        , language(language_support(
sl@0
   127
                      support_cpp 
sl@0
   128
                    | support_option_convert_trigraphs 
sl@0
   129
                    | support_option_emit_line_directives 
sl@0
   130
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
sl@0
   131
                    | support_option_include_guard_detection
sl@0
   132
#endif
sl@0
   133
                   ))
sl@0
   134
        , hooks(hooks_)
sl@0
   135
    {
sl@0
   136
        macros.init_predefined_macros(fname);
sl@0
   137
        includes.init_initial_path();
sl@0
   138
    }
sl@0
   139
    
sl@0
   140
// default copy constructor
sl@0
   141
// default assignment operator
sl@0
   142
// default destructor
sl@0
   143
    
sl@0
   144
// iterator interface
sl@0
   145
    iterator_type begin() 
sl@0
   146
    { 
sl@0
   147
        std::string fname(filename);
sl@0
   148
        if (filename != "<Unknown>" && filename != "<stdin>") {
sl@0
   149
            using namespace boost::filesystem;
sl@0
   150
            path fpath(complete(path(filename)));
sl@0
   151
            fname = fpath.string();
sl@0
   152
            includes.set_current_directory(fname.c_str());
sl@0
   153
        }
sl@0
   154
        return iterator_type(*this, first, last, position_type(fname.c_str())); 
sl@0
   155
    }
sl@0
   156
    iterator_type begin(
sl@0
   157
        target_iterator_type const &first_, 
sl@0
   158
        target_iterator_type const &last_) 
sl@0
   159
    { 
sl@0
   160
        std::string fname(filename);
sl@0
   161
        if (filename != "<Unknown>" && filename != "<stdin>") {
sl@0
   162
            using namespace boost::filesystem;
sl@0
   163
            path fpath(complete(path(filename)));
sl@0
   164
            fname = fpath.string();
sl@0
   165
            includes.set_current_directory(fname.c_str());
sl@0
   166
        }
sl@0
   167
        return iterator_type(*this, first_, last_, position_type(fname.c_str())); 
sl@0
   168
    }
sl@0
   169
    iterator_type end() const 
sl@0
   170
        { return iterator_type(); }
sl@0
   171
sl@0
   172
// maintain include paths
sl@0
   173
    bool add_include_path(char const *path_)
sl@0
   174
        { return includes.add_include_path(path_, false);}
sl@0
   175
    bool add_sysinclude_path(char const *path_)
sl@0
   176
        { return includes.add_include_path(path_, true);}
sl@0
   177
    void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
sl@0
   178
    typename iteration_context_stack_type::size_type get_iteration_depth() const 
sl@0
   179
        { return iter_ctxs.size(); }
sl@0
   180
sl@0
   181
// maintain defined macros
sl@0
   182
#if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
sl@0
   183
    bool add_macro_definition(std::string macrostring, 
sl@0
   184
            bool is_predefined = false)
sl@0
   185
        { return boost::wave::util::add_macro_definition(*this, macrostring, 
sl@0
   186
            is_predefined, get_language()); }
sl@0
   187
#endif 
sl@0
   188
    bool add_macro_definition(token_type const &name, bool has_params,
sl@0
   189
            std::vector<token_type> &parameters, token_sequence_type &definition,
sl@0
   190
            bool is_predefined = false)
sl@0
   191
        { return macros.add_macro(name, has_params, parameters, definition, 
sl@0
   192
            is_predefined); }
sl@0
   193
    template <typename IteratorT2>
sl@0
   194
    bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end) 
sl@0
   195
        { return macros.is_defined(begin, end); }
sl@0
   196
    bool get_macro_definition(typename token_type::string_type const &name, 
sl@0
   197
            bool &has_params, bool &is_predefined, position_type &pos,
sl@0
   198
            std::vector<token_type> &parameters, token_sequence_type &definition)
sl@0
   199
        { 
sl@0
   200
            return macros.get_macro(name, has_params, is_predefined, pos,
sl@0
   201
                parameters, definition); 
sl@0
   202
        }
sl@0
   203
    bool remove_macro_definition(typename token_type::string_type const &name, 
sl@0
   204
            bool even_predefined = false)
sl@0
   205
        { 
sl@0
   206
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
sl@0
   207
            // ensure this gets remove from the list of include guards as well
sl@0
   208
            includes.remove_pragma_once_header(std::string(name.c_str()));
sl@0
   209
#endif
sl@0
   210
            return macros.remove_macro(
sl@0
   211
                token_type(T_IDENTIFIER, name, macros.get_main_pos()), 
sl@0
   212
                even_predefined); 
sl@0
   213
        }
sl@0
   214
    void reset_macro_definitions() 
sl@0
   215
        { macros.reset_macromap(); macros.init_predefined_macros(); }
sl@0
   216
sl@0
   217
// get the Wave version information 
sl@0
   218
    static std::string get_version()  
sl@0
   219
        { return boost::wave::util::predefined_macros::get_fullversion(false); }
sl@0
   220
    static std::string get_version_string()  
sl@0
   221
        { return boost::wave::util::predefined_macros::get_versionstr(false); }
sl@0
   222
sl@0
   223
// access current language options
sl@0
   224
    void set_language(boost::wave::language_support language_,
sl@0
   225
                      bool reset_macros = true) 
sl@0
   226
    { 
sl@0
   227
        language = language_; 
sl@0
   228
        if (reset_macros)
sl@0
   229
            reset_macro_definitions();
sl@0
   230
    }
sl@0
   231
    boost::wave::language_support get_language() const { return language; }
sl@0
   232
        
sl@0
   233
// change and ask for maximal possible include nesting depth
sl@0
   234
    void set_max_include_nesting_depth(iter_size_type new_depth)
sl@0
   235
        { iter_ctxs.set_max_include_nesting_depth(new_depth); }
sl@0
   236
    iter_size_type get_max_include_nesting_depth() const
sl@0
   237
        { return iter_ctxs.get_max_include_nesting_depth(); }
sl@0
   238
sl@0
   239
// access the policies
sl@0
   240
    hook_policy_type &get_hooks() { return hooks; }
sl@0
   241
sl@0
   242
// return the directory of the currently preprocessed file
sl@0
   243
    boost::filesystem::path get_current_directory() const
sl@0
   244
        { return includes.get_current_directory(); }
sl@0
   245
        
sl@0
   246
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
sl@0
   247
protected:
sl@0
   248
    friend class boost::wave::pp_iterator<
sl@0
   249
        boost::wave::context<IteratorT, lexer_type, InputPolicyT, HooksT> >;
sl@0
   250
    friend class boost::wave::impl::pp_iterator_functor<
sl@0
   251
        boost::wave::context<IteratorT, lexer_type, InputPolicyT, HooksT> >;
sl@0
   252
#endif
sl@0
   253
    
sl@0
   254
// maintain include paths (helper functions)
sl@0
   255
    bool find_include_file (std::string &s, std::string &d, bool is_system, 
sl@0
   256
        char const *current_file) const
sl@0
   257
    { return includes.find_include_file(s, d, is_system, current_file); }
sl@0
   258
    void set_current_directory(char const *path_) 
sl@0
   259
        { includes.set_current_directory(path_); }
sl@0
   260
        
sl@0
   261
// conditional compilation contexts
sl@0
   262
    bool get_if_block_status() const { return ifblocks.get_status(); }
sl@0
   263
    bool get_if_block_some_part_status() const 
sl@0
   264
        { return ifblocks.get_some_part_status(); } 
sl@0
   265
    bool get_enclosing_if_block_status() const
sl@0
   266
        { return ifblocks.get_enclosing_status(); }
sl@0
   267
    void enter_if_block(bool new_status) 
sl@0
   268
        { ifblocks.enter_if_block(new_status); }
sl@0
   269
    bool enter_elif_block(bool new_status) 
sl@0
   270
        { return ifblocks.enter_elif_block(new_status); }
sl@0
   271
    bool enter_else_block() { return ifblocks.enter_else_block(); }
sl@0
   272
    bool exit_if_block() { return ifblocks.exit_if_block(); }
sl@0
   273
    typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const 
sl@0
   274
        { return ifblocks.get_if_block_depth(); }
sl@0
   275
sl@0
   276
// stack of iteration contexts
sl@0
   277
    iteration_ptr_type pop_iteration_context()
sl@0
   278
        { iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
sl@0
   279
    void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
sl@0
   280
        { iter_ctxs.push(act_pos, iter_ctx); }
sl@0
   281
sl@0
   282
    position_type &get_main_pos() { return macros.get_main_pos(); }
sl@0
   283
    
sl@0
   284
///////////////////////////////////////////////////////////////////////////////
sl@0
   285
//
sl@0
   286
//  expand_tokensequence(): 
sl@0
   287
//      expands all macros contained in a given token sequence, handles '##' 
sl@0
   288
//      and '#' pp operators and re-scans the resulting sequence 
sl@0
   289
//      (essentially pre-processes the token sequence).
sl@0
   290
//
sl@0
   291
//      The expand_undefined parameter is true during macro expansion inside
sl@0
   292
//      a C++ expression given for a #if or #elif statement. 
sl@0
   293
//
sl@0
   294
///////////////////////////////////////////////////////////////////////////////
sl@0
   295
    template <typename IteratorT2>
sl@0
   296
    token_type expand_tokensequence(IteratorT2 &first_, IteratorT2 const &last_, 
sl@0
   297
        token_sequence_type &pending, token_sequence_type &expanded, 
sl@0
   298
        bool expand_undefined = false)
sl@0
   299
    {
sl@0
   300
        return macros.expand_tokensequence(first_, last_, pending, expanded, 
sl@0
   301
            expand_undefined);
sl@0
   302
    }
sl@0
   303
sl@0
   304
    template <typename IteratorT2>
sl@0
   305
    void expand_whole_tokensequence(IteratorT2 &first_, IteratorT2 const &last_, 
sl@0
   306
        token_sequence_type &expanded, bool expand_undefined = true)
sl@0
   307
    {
sl@0
   308
        macros.expand_whole_tokensequence(expanded, first_, last_, 
sl@0
   309
            expand_undefined);
sl@0
   310
sl@0
   311
    // remove any contained placeholder
sl@0
   312
        boost::wave::util::impl::remove_placeholders(expanded);
sl@0
   313
    }
sl@0
   314
sl@0
   315
public:
sl@0
   316
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
sl@0
   317
// support for #pragma once
sl@0
   318
// maintain the real name of the current preprocessed file
sl@0
   319
    void set_current_filename(char const *real_name)
sl@0
   320
        { current_filename = real_name; }
sl@0
   321
    std::string const &get_current_filename() const 
sl@0
   322
        { return current_filename; }
sl@0
   323
sl@0
   324
// maintain the list of known headers containing #pragma once 
sl@0
   325
    bool has_pragma_once(std::string const &filename_)
sl@0
   326
        { return includes.has_pragma_once(filename_); }
sl@0
   327
    bool add_pragma_once_header(std::string const &filename_,
sl@0
   328
            std::string const& guard_name = "__BOOST_WAVE_PRAGMA_ONCE__")
sl@0
   329
        { return includes.add_pragma_once_header(filename_, guard_name); }
sl@0
   330
#endif 
sl@0
   331
sl@0
   332
// forwarding functions for the context policy hooks    
sl@0
   333
    template <typename ContainerT>
sl@0
   334
    bool interpret_pragma(ContainerT &pending, token_type const &option, 
sl@0
   335
        ContainerT const &values, token_type const &act_token)
sl@0
   336
    {
sl@0
   337
        return hooks.interpret_pragma(*this, pending, option, values, act_token);
sl@0
   338
    }
sl@0
   339
    
sl@0
   340
#if BOOST_WAVE_SERIALIZATION != 0
sl@0
   341
public:
sl@0
   342
    BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);
sl@0
   343
    BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);
sl@0
   344
sl@0
   345
private:
sl@0
   346
    friend class boost::serialization::access;
sl@0
   347
    template<class Archive>
sl@0
   348
    void save(Archive & ar, const unsigned int version) const
sl@0
   349
    {
sl@0
   350
        typedef typename token_type::string_type string_type;
sl@0
   351
        
sl@0
   352
        string_type cfg(BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG));
sl@0
   353
        string_type kwd(BOOST_WAVE_PRAGMA_KEYWORD);
sl@0
   354
        string_type strtype(BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE)));
sl@0
   355
        ar & cfg;
sl@0
   356
        ar & kwd;
sl@0
   357
        ar & strtype;
sl@0
   358
        
sl@0
   359
        ar & language;
sl@0
   360
        ar & macros;
sl@0
   361
        ar & includes;
sl@0
   362
    }
sl@0
   363
    template<class Archive>
sl@0
   364
    void load(Archive & ar, const unsigned int loaded_version)
sl@0
   365
    {
sl@0
   366
        if (version != (loaded_version & ~version_mask)) {
sl@0
   367
            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
sl@0
   368
                "cpp_context state version", get_main_pos());
sl@0
   369
        }
sl@0
   370
        
sl@0
   371
        // check compatibility of the stored information
sl@0
   372
        typedef typename token_type::string_type string_type;
sl@0
   373
        string_type config, pragma_keyword, string_type_str;
sl@0
   374
        
sl@0
   375
        ar & config;          // BOOST_WAVE_CONFIG
sl@0
   376
        if (config != BOOST_PP_STRINGIZE(BOOST_WAVE_CONFIG)) {
sl@0
   377
            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
sl@0
   378
                "BOOST_WAVE_CONFIG", get_main_pos());
sl@0
   379
        }
sl@0
   380
        
sl@0
   381
        ar & pragma_keyword;  // BOOST_WAVE_PRAGMA_KEYWORD
sl@0
   382
        if (pragma_keyword != BOOST_WAVE_PRAGMA_KEYWORD) {
sl@0
   383
            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
sl@0
   384
                "BOOST_WAVE_PRAGMA_KEYWORD", get_main_pos());
sl@0
   385
        }
sl@0
   386
sl@0
   387
        ar & string_type_str; // BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))
sl@0
   388
        if (string_type_str != BOOST_PP_STRINGIZE((BOOST_WAVE_STRINGTYPE))) {
sl@0
   389
            BOOST_WAVE_THROW(preprocess_exception, incompatible_config, 
sl@0
   390
                "BOOST_WAVE_STRINGTYPE", get_main_pos());
sl@0
   391
        }
sl@0
   392
        
sl@0
   393
        // read in the useful bits
sl@0
   394
        ar & language;
sl@0
   395
        ar & macros;
sl@0
   396
        ar & includes;
sl@0
   397
    }
sl@0
   398
    BOOST_SERIALIZATION_SPLIT_MEMBER()
sl@0
   399
#endif
sl@0
   400
sl@0
   401
private:
sl@0
   402
// the main input stream
sl@0
   403
    target_iterator_type first;         // underlying input stream
sl@0
   404
    target_iterator_type last;
sl@0
   405
    std::string filename;               // associated main filename
sl@0
   406
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
sl@0
   407
    std::string current_filename;       // real name of current preprocessed file
sl@0
   408
#endif 
sl@0
   409
    
sl@0
   410
    boost::wave::util::if_block_stack ifblocks;   // conditional compilation contexts
sl@0
   411
    boost::wave::util::include_paths includes;    // lists of include directories to search
sl@0
   412
    iteration_context_stack_type iter_ctxs;       // iteration contexts
sl@0
   413
    boost::wave::util::macromap<self_type> macros;  // map of defined macros
sl@0
   414
    boost::wave::language_support language;       // supported language/extensions
sl@0
   415
    hook_policy_type hooks;                       // hook policy instance
sl@0
   416
};
sl@0
   417
sl@0
   418
///////////////////////////////////////////////////////////////////////////////
sl@0
   419
}   // namespace wave
sl@0
   420
}   // namespace boost
sl@0
   421
sl@0
   422
#if BOOST_WAVE_SERIALIZATION != 0
sl@0
   423
namespace boost { namespace serialization {
sl@0
   424
sl@0
   425
template<
sl@0
   426
    typename Iterator, typename LexIterator, 
sl@0
   427
    typename InputPolicy, typename Hooks
sl@0
   428
>
sl@0
   429
struct tracking_level<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
sl@0
   430
{
sl@0
   431
    typedef mpl::integral_c_tag tag;
sl@0
   432
    typedef mpl::int_<track_never> type;
sl@0
   433
    BOOST_STATIC_CONSTANT(
sl@0
   434
        int,
sl@0
   435
        value = tracking_level::type::value
sl@0
   436
    );
sl@0
   437
};
sl@0
   438
sl@0
   439
template<
sl@0
   440
    typename Iterator, typename LexIterator, 
sl@0
   441
    typename InputPolicy, typename Hooks
sl@0
   442
>
sl@0
   443
struct version<boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks> >
sl@0
   444
{
sl@0
   445
    typedef boost::wave::context<Iterator, LexIterator, InputPolicy, Hooks>
sl@0
   446
        target_type;
sl@0
   447
    typedef mpl::int_<target_type::version> type;
sl@0
   448
    typedef mpl::integral_c_tag tag;
sl@0
   449
    BOOST_STATIC_CONSTANT(unsigned int, value = version::type::value);
sl@0
   450
};
sl@0
   451
sl@0
   452
}}  // namespace boost::serialization
sl@0
   453
#endif
sl@0
   454
sl@0
   455
// the suffix header occurs after all of the code
sl@0
   456
#ifdef BOOST_HAS_ABI_HEADERS
sl@0
   457
#include BOOST_ABI_SUFFIX
sl@0
   458
#endif
sl@0
   459
sl@0
   460
#endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)