Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / C++

Wave: a Standard conformant C++ preprocessor library

Rate me:
Please Sign up or sign in to vote.
4.96/5 (58 votes)
10 Jan 200413 min read 395.2K   4.4K   81  
Describes a free and fully Standard conformant C++ preprocessor library
/*=============================================================================
    Wave: A Standard compliant C++ preprocessor

    Global application configuration
    
    Copyright (c) 2001-2004 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to 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 Copyright.txt for full acknowledgements.
=============================================================================*/

#if !defined(CPP_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED)
#define CPP_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED

///////////////////////////////////////////////////////////////////////////////
//  Decide, wheter to work in C++ or IDL mode (select exactly one!)
#if !defined(WAVE_ACT_FOR_CPP) && !defined(WAVE_ACT_FOR_IDL)
#define WAVE_ACT_FOR_CPP 1
//#define WAVE_ACT_FOR_IDL
#endif // !defined(WAVE_ACT_FOR_CPP) && !defined(WAVE_ACT_FOR_IDL)

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to reverse the macro names before storing them into the 
//  symbol tables. This may speed up things considerably, especially if the
//  used macro names are very long and start with a common prefix.
//
//  To reverse the macro names for symbol table purposes, uncomment the 
//  following
//
//#define WAVE_REVERSE_MACRONAMES_FOR_SYMBOLTABLE 1

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to implement macro scopes (#scope/#endscope), variadics,
//  placemarkers and well defined token pasting in C++ mode
//
//  To implement these features, uncomment the following
//
#define WAVE_ENABLE_CPP0X_EXTENSIONS 1

///////////////////////////////////////////////////////////////////////////////
//  Define the macro scoping keywords to be used for the experimental macro 
//  scoping support.
//
//  If the following macros aren't defined, the corresponding default value is 
//  used.
//
//  Note, if you change this, you will have to change the corresponding entries 
//  inside the wave/cpplexer/re2c/cpp.re file too.
//
//#define WAVE_PP_REGION          "region"
//#define WAVE_PP_REGION_UC       "REGION"      // uppercase of WAVE_PP_REGION
//#define WAVE_PP_ENDREGION       "endregion"
//#define WAVE_PP_IMPORT          "import"

///////////////////////////////////////////////////////////////////////////////
//  Define the maximal include nesting depth allowed. If this value isn't 
//  defined it defaults to 1024
//
//  To define a new initial include nesting depth uncomment the following and 
//  supply a new integer value.
//
//#define WAVE_MAX_INCLUDE_LEVEL_DEPTH 1024

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to support variadics and placemarkers
//
//  To implement support variadics and placemarkers uncomment the following
//
#define WAVE_SUPPORT_VARIADICS_PLACEMARKERS 1

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to implement a #warning directive as 
//
//  To implement #warning directives, uncomment the following
//
#define WAVE_SUPPORT_WARNING_DIRECTIVE 1

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to implement #pragma once 
//
//  To implement #pragma once, uncomment the following
//
#define WAVE_SUPPORT_PRAGMA_ONCE 1

///////////////////////////////////////////////////////////////////////////////
//  Undefine the following, to enable some MS specific language extensions:
//  __int8, __int16, __int32, __int64, __based, __declspec, __cdecl, 
//  __fastcall, __stdcall, __try, __except, __finally, __leave, __inline,
//  __asm
#define WAVE_SUPPORT_MS_EXTENSIONS 1

///////////////////////////////////////////////////////////////////////////////
//  Allow the message body of the #error and #warning directives to be 
//  preprocessed before the diagnostic is issued.
//
//  Uncommenting the following will preprocess the message bodies of #error and
//  #warning messages before the error (warning) is issued
//
#define WAVE_PREPROCESS_ERROR_MESSAGE_BODY 1

///////////////////////////////////////////////////////////////////////////////
//  Allow the #pragma directives to be returned to the caller (optionally after 
//  preprocessing the body) 
//
//  Undefining the following will skip #pragma directives, so that the caller
//  will not see them.
//
#define WAVE_EMIT_PRAGMA_DIRECTIVES 1

///////////////////////////////////////////////////////////////////////////////
//  Allow the body of a #pragma directive to be preprocessed before the 
//  directive is returned to the caller.
//
//  Uncommenting the following will preprocess the bodies of #pragma directives
//
#define WAVE_PREPROCESS_PRAGMA_BODY 1

///////////////////////////////////////////////////////////////////////////////
//  Allow to define macros with the command line syntax (-DMACRO(x)=definition)
//
//  Uncommenting the following will enable the possibility to define macros
//  based on the command line syntax
//
#define WAVE_ENABLE_COMMANDLINE_MACROS 1

///////////////////////////////////////////////////////////////////////////////
//  Define the string type to be used to store the token values and the file 
//  names inside a file_position template class
//
//  If this isn't defined, it defaults to std::string (std::string may be used 
//  directly, if it is based on a COW implementation (copy on write)).
//

// use the following, if you have a fast std::allocator<char>
//#define WAVE_STRINGTYPE wave::util::flex_string< \
//        char, std::char_traits<char>, std::allocator<char>, \
//            wave::util::CowString<char, \
//                wave::util::AllocatorStringStorage<char> > \
//    > \
//    /**/

// use the following otherwise
#define WAVE_STRINGTYPE wave::util::flex_string< \
        char, std::char_traits<char>, boost::fast_pool_allocator<char>, \
            wave::util::CowString<char, \
                wave::util::AllocatorStringStorage<char, \
                    boost::fast_pool_allocator<char> \
                > \
            > \
        > \
    /**/

///////////////////////////////////////////////////////////////////////////////
// Decide, which C++ lexer to use (choose one!)
//
//  If you select WAVE_USE_RE2C_IDL_LEXER, you will implicitly select the Wave 
//  IDL mode.
//

#if defined(WAVE_ACT_FOR_CPP)
//#define WAVE_USE_SLEX_CPP_LEXER 1      // use the SLex based C++ lexer
#define WAVE_USE_RE2C_CPP_LEXER 1       // use the Re2C based C++ lexer
#else
#define WAVE_USE_RE2C_IDL_LEXER 1       // use the Re2C based IDL lexer
#endif

// building an application, i.e. only one lexer is required
#if !defined(WAVE_USE_RE2C_IDL_LEXER)

#if (defined(WAVE_USE_SLEX_CPP_LEXER) && defined(WAVE_USE_RE2C_CPP_LEXER)) || \
    (!defined(WAVE_USE_SLEX_CPP_LEXER) && !defined(WAVE_USE_RE2C_CPP_LEXER))
#error "Please choose exactly one C++ lexer to use" \
    " (define WAVE_USE_SLEX_CPP_LEXER or WAVE_USE_RE2C_CPP_LEXER or WAVE_USE_RE2C_IDL_LEXER)"
#endif

#else  // !defined(WAVE_USE_RE2C_IDL_LEXER)

#if (defined(WAVE_USE_SLEX_CPP_LEXER) || defined(WAVE_USE_RE2C_CPP_LEXER))
#error "Please choose exactly one lexer to use" \
    " (define WAVE_USE_SLEX_CPP_LEXER or WAVE_USE_RE2C_CPP_LEXER or WAVE_USE_RE2C_IDL_LEXER)"
#endif

#endif // !defined(WAVE_USE_RE2C_IDL_LEXER)

///////////////////////////////////////////////////////////////////////////////
//  Define the lexer namespace to use
#if defined(WAVE_USE_RE2C_IDL_LEXER)
#define WAVE_LEXER_NS  wave::idllexer
#else
#define WAVE_LEXER_NS  wave::cpplexer
#endif

///////////////////////////////////////////////////////////////////////////////
//  Uncomment the following, if you need debug output, the 
//  BOOST_SPIRIT_DEBUG_FLAGS constants below help to fine control the amount of 
//  the generated debug output
//#define BOOST_SPIRIT_DEBUG

///////////////////////////////////////////////////////////////////////////////
//  debug rules, subrules and grammars only, for possible flags see 
//  spirit/debug.hpp
#define BOOST_SPIRIT_DEBUG_FLAGS ( \
        BOOST_SPIRIT_DEBUG_FLAGS_NODES | \
        BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES \
    ) \
    /**/

///////////////////////////////////////////////////////////////////////////////
//  debug flags for the pp-iterator library, possible flags:
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR            0x0001
#define BOOST_SPIRIT_DEBUG_FLAGS_TIME_CONVERSION        0x0002
#define BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR       0x0004
#define BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR         0x0008
#define BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR          0x0010
#define BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR        0x0020
#define BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR  0x0040

#define BOOST_SPIRIT_DEBUG_FLAGS_CPP (\
        BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR \
    ) \
    /**/

///////////////////////////////////////////////////////////////////////////////
//
//  For all recognized preprocessor statements the output parse trees 
//  formatted as xml are printed. The formatted parse trees are streamed to the 
//  std::ostream defined by the WAVE_DUMP_PARSE_TREE_OUT constant.
//
//  Uncomment the following, if you want to see these parse trees. 
//
//#define WAVE_DUMP_PARSE_TREE 1
//#define WAVE_DUMP_PARSE_TREE_OUT std::cerr

///////////////////////////////////////////////////////////////////////////////
//
//  For all #if and #elif directives the preprocessed expressions are printed.
//  These expressions are streamed to the std::ostream defined by the 
//  WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT constant.
//
//  Uncomment the following, if you want to see the preprocessed expressions
//
//#define WAVE_DUMP_CONDITIONAL_EXPRESSIONS 1
//#define WAVE_DUMP_CONDITIONAL_EXPRESSIONS_OUT std::cerr

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to use the separate compilation model for the instantiation 
//  of the C++ lexer objects.
//
//  If this is defined, you should explicitly instantiate the C++ lexer
//  template with the correct parameters in a separate compilation unit of
//  your program (see the files instantiate_slex_lexer.cpp and
//  instantiate_re2c_lexer.cpp). 
//
//  To use the lexer inclusion model, uncomment the following 
//
#define WAVE_SEPARATE_LEXER_INSTANTIATION 1

///////////////////////////////////////////////////////////////////////////////
//  Decide, whether to use the separate compilation model for the instantiation 
//  of the grammar objects.
//
//  If this is defined, you should explicitly instantiate the grammar
//  templates with the correct parameters in a separate compilation unit of
//  your program (see the files instantiate_cpp_grammar.cpp). 
//
//  To use the grammar inclusion model, uncomment the following 
//
#define WAVE_SEPARATE_GRAMMAR_INSTANTIATION 1

///////////////////////////////////////////////////////////////////////////////
//  You shouldn't have to change anything below

#if defined(BOOST_MSVC) && !defined(__COMO__)
#pragma warning (disable: 4355) // 'this' used in base member initializer list
#pragma warning (disable: 4800) // forcing value to bool 'true' or 'false' (performance warning)
#pragma inline_depth(255)
#pragma inline_recursion(on)
#endif // defined(BOOST_MSVC)

///////////////////////////////////////////////////////////////////////////////
//  The experimental C++0x mode implies the variadics and placemarkers
#if defined(WAVE_ENABLE_CPP0X_EXTENSIONS) && !defined(WAVE_SUPPORT_VARIADICS_PLACEMARKERS)
#define WAVE_SUPPORT_VARIADICS_PLACEMARKERS 1
#endif // 

///////////////////////////////////////////////////////////////////////////////
//  The Boost.Pool library requires to define the following constant for non-
//  threaded applications
#define BOOST_NO_MT 1

///////////////////////////////////////////////////////////////////////////////
//  If acting in IDL mode, some constants make no sense anymore
#if defined(WAVE_ACT_FOR_IDL)

#undef WAVE_ENABLE_CPP0X_EXTENSIONS
#undef WAVE_PP_REGION   
#undef WAVE_PP_REGION_UC
#undef WAVE_PP_ENDREGION
#undef WAVE_PP_IMPORT   

#undef WAVE_SUPPORT_VARIADICS_PLACEMARKERS

#endif  // defined(WAVE_ACT_FOR_IDL)

#endif // !defined(CPP_CONFIG_HPP_F143F90A_A63F_4B27_AC41_9CA4F14F538D_INCLUDED)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
Actively involved in Boost and the development of the Spirit parser construction framework.

Comments and Discussions