| Home | Libraries | People | FAQ | More

## Configuration and Optional Features

Boost.Parser can be used entirely on its own. If Boost is available, extra functionality provided by Boost is also available.

By default, Boost.Parser is usable entirely on its own. The only explicit opt-in use of Boost is the use of Boost.Hana. If you turn on the use of Hana, the tuple type used throughout Boost.Parser will be `boost::hana::tuple` instead of `std::tuple`. To enable this, simply define `BOOST_PARSER_USE_HANA_TUPLE`. The Boost.Hana tuple is much nicer, because it has an `operator[]`, and a whole lot of very useful algorithms; you will see this operator used throughout the tutorial and examples. I encourage you to use the Hana tuple, but I realize that it is an often-unfamiliar replacement for `std::tuple`, which is a C++ vocabulary template, and so that is the default.

| Important
Boost.Parser defines a template alias `boost::parser::tuple` that aliases to `boost::hana::tuple` by default, and `std::tuple` when `BOOST_PARSER_DISABLE_HANA_TUPLE` is defined. You can future-proof your code slightly by using `boost::parser::tuple`, so that the code is well-formed, whether or not `BOOST_PARSER_DISABLE_HANA_TUPLE` is defined. For the same reason, Boost.Parser also provides a generic `boost::parser::get` that works with both kinds of tuple (since `std::tuple` has no `operator[]` and `boost::hana::tuple` does not work with `std::get`).

The presence of Boost headers is detected using `__has_include()`. When it is present, all the typical Boost conventions are used; otherwise, non-Boost alternatives are used. This applies to the use of `BOOST_ASSERT` versus `assert`, and printing typenames with Boost.TypeIndex versus with `std::typeinfo`.

| Note
If you want to disable the use of the C macro `assert`, you define `BOOST_DISABLE_ASSERTS`. This is true whether `BOOST_ASSERT` is available or not.

| Important
Boost.Parser uses inline namespaces around definitions of all functions and types that use the optional Boost features; the name of the inline namespace varies depending on whether the Boost implementation is used. So if Boost.TypeIndex is available to one translation unit, but another TU must use `std::typeinfo`, there are no ODR violations. The exception to this is the use of `BOOST_ASSERT`/`assert`; assert macros are inherently ODR traps.

Boost.Parser automatically treats aggregate `struct`s as if they were tuples in many cases. There is some metaprogramming logic that makes this work, and this logic has a hard limit on the size of a `struct` that it can operate on. There is a configuration macro `BOOST_PARSER_MAX_AGGREGATE_SIZE` that you can adjust if the default value is too small. Note that turning this value up significantly can significantly increase compile times. Also, MSVC seems to have a hard time with large values; I successfully set this value to `50` on MSVC, but `100` broke the MSVC build entirely.

Boost.Parser uses `std::optional` and `std::variant` internally. There is no way to change this. However, when Boost.Parser generates values as a result of the parse (see Attribute Generation), it can place them into other implementations of optional and/or variant, if you tell it to do so. You tell it which templates are usable as an optional or variant by specializing the associated variable template. For instance, here is how you would tell Boost.Parser that `boost::optional` is an optional-type:

    template<typename T>
    constexpr bool boost::parser::enable_optional<boost::optional<T>> = true;

Here's how you would do the same thing for `boost::variant2::variant`:

    template<typename... Ts>
    constexpr bool boost::parser::enable_variant<boost::variant2::variant<Ts...>> = true;

The requirements on a template used as an optional are pretty simple, since Boost.Parser does almost nothing but assign to them. For a type `O` to be a usable optional, you must be able to assign to `O`, and `O` must have an `operator*` that returns the stored value, or a (possibly cv-qualified) reference to the stored value.

For variants, the requirement is even simpler; the variant type only needs to be assignable.

| Note
The only thing affected by `enable_variant` is printing. If your variant template can be printed with just `std::cout << v` (where `v` is a variant, obviously), then you don't need to define `enable_variant` for your variant template.

Boost.Parser uses `std::ranges::subrange` extensively. However, there is no C++17 equivalent. So, there is a `boost::parser::subrange` for C++17 builds. To switch between these transparently in the code, while keeping CTAD operational, Boost.Parser defines `BOOST_PARSER_SUBRANGE`. This is the name of the template, so if you use it in your own code you would use it like `BOOST_PARSER_SUBRANGE<I>` to instantiate it.

Boost.Parser allows you to debug your parsers by passing `trace::on` to `parse()`. Sometimes, your run environment does not include a terminal. If you're running Boost.Parser code in the Visual Studio debugger, you can see this trace output in the Visual Studio debugger output panel rather than in a terminal by defining `BOOST_PARSER_TRACE_TO_VS_OUTPUT`.