boostorg / boostorg/metaparse

Proposal for value-based Interface in Boost.Metaparse

Open
#21 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
48
Forks
35
PR merge metrics
No merged PRs in 30d

Description

**Motivation**

Boost.Metaparse is a powerful library for compile-time parsing, but its interface remains largely centered around template metafunctions in the classic `typename ...` style. While the library has already taken a step toward value-based with `BOOST_METAPARSE_STRING_VALUE`—this improvement is only partial. In 2025, developers should not be forced to write verbose and archaic constructs like:

```cpp
typedef
foldl_reject_incomplete1<
one_of<
always_c<'.', r_any_char>,
transform, r_char_lit>
>,
r_epsilon,
r_append
>
non_bracket_expr;
```

Such syntax is not only cumbersome and hard to read, but it also stands in stark contrast to modern C++ idioms. The existing value-based support for strings demonstrates the library's potential to evolve, but stopping halfway leaves the interface inconsistent and underutilized.

I propose to **complete this evolution** by introducing a comprehensive, value-based C++11 interface for the entire library. This will align Boost.Metaparse with contemporary C++ practices, making it more accessible, expressive, and maintainable.

**Proposed Solution**

Extend the value-based approach consistently across all metafunctions by introducing lightweight `constexpr` wrapper functions. Each wrapper will accept value-based arguments (types as template parameters, callable objects, or already wrapped values) and return an instance of the corresponding Boost.Metaparse metafunction. For example:

```cpp
template
constexpr auto middle_of(Left, Middle, Right) ->
boost::metaparse::middle_of
{
return {};
}
```

We have to negotiate the way how to ensure full backward compatibility and a clear distinction from the classic metafunction-based interface.
As a temporary solution i've put all these wrappers into `boost::metaparse::cxx11`.

**Benefits**

1. **Consistency** – If `BOOST_METAPARSE_STRING_VALUE` enables value-based strings, why should the rest of the library remain type-based? A uniform value-based interface eliminates cognitive dissonance and simplifies learning.
2. **Modern readability** – Complex parser definitions become clean, linear, and visually similar to runtime parsing code—lowering the barrier for new users.
3. **Seamless integration with modern C++** – The wrappers leverage `constexpr`, `auto`, and lambda expressions, fitting naturally into C++11 and beyond.
4. **Zero-cost abstraction** – The wrappers are trivial, header-only, and impose no compile-time or runtime overhead.
5. **Progressive evolution** – This change complements rather than replaces the existing interface, allowing gradual adoption.

**Example Transformation**

With the proposed wrappers, the regexp example from the repository transforms into a much clearer and more maintainable form:
```cpp
#include "boost_metaparse_cxx11/wrappers.hpp"
#include
#include

using boost::metaparse::cxx11::foldl_reject_incomplete;
using boost::metaparse::cxx11::foldl_reject_incomplete1;
using boost::metaparse::cxx11::lit_c;
using boost::metaparse::cxx11::transform;
using boost::metaparse::cxx11::build_parser;
using boost::metaparse::cxx11::one_of;
using boost::metaparse::cxx11::always_c;
using boost::metaparse::cxx11::middle_of;
using boost::metaparse::cxx11::one_char_except_c;
using boost::metaparse::cxx11::entire_input;

using boost::xpressive::sregex;
using boost::xpressive::as_xpr;

void test_string(const std::string& s)
{
/*
* Results of parsing
*/

using boost::xpressive::sregex;
using boost::xpressive::as_xpr;

constexpr auto r_any_char = []() {
return boost::xpressive::_;
};

constexpr auto r_char_lit = [](char C) {
return as_xpr(C);
};

constexpr auto r_append = [](const sregex& lhs, const sregex& rhs) -> sregex {
return lhs >> rhs;
};

constexpr auto r_epsilon = []{
return as_xpr("");
};

using boost::xpressive::regex_match;
using boost::xpressive::smatch;
using std::cout;
using std::endl;

/*
* The grammar
*
* regexp ::= (bracket_expr | non_bracket_expr)*
* non_bracket_expr ::= '.' | char_lit
* bracket_expr ::= '(' regexp ')'
* char_lit ::= any character except: . ( )
*/

constexpr auto non_bracket_expr = foldl_reject_incomplete1(
one_of(
always_c<'.'>(r_any_char),
transform(
one_char_except_c<'.', '(', ')'>(),
r_char_lit
)
),
r_epsilon,
r_append
);

constexpr auto bracket_expr = middle_of(
lit_c<'('>(),
non_bracket_expr,
lit_c<')'>()
);

constexpr auto regexp = foldl_reject_incomplete(
one_of(
bracket_expr,
non_bracket_expr
),
r_epsilon,
r_append
);

constexpr auto regexp_parser =
build_parser(entire_input(regexp));

const sregex re = regexp_parser(BOOST_METAPARSE_STRING_VALUE(".(bc)"));

smatch w;

cout << s << (regex_match(s, w, re) ? " matches " : " doesn't match ")
<< ".(bc)" << endl;
}

int main()
{
test_string("abc");
test_string("aba");

return 0;
}
```

Working prototypes are available:
- C++11 prototype: https://godbolt.org/z/8PP1Y9sn3
- C++20 prototype: https://godbolt.org/z/EGP7xsaG7

The wrapper implementation (sufficient for the regexp example) can be reviewed here:
https://github.com/denzor200/boost_metaparse_cxx11/blob/main/wrappers.hpp

**Implementation Outline**

The change is non-breaking and can be introduced incrementally. It requires only the addition of header files containing wrapper functions for each metafunction—building naturally on the foundation laid by `BOOST_METAPARSE_STRING_VALUE`.

**Conclusion**

Boost.Metaparse has already begun moving toward a value-based interface. Let’s finish that journey. By extending this approach library-wide, we can modernize Boost.Metaparse, enhance its usability, and ensure it remains a first-choice tool for compile-time parsing in modern C++. I am eager to contribute a pull request if the idea is accepted.

Thank you for your consideration.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.