Skip to content

Commit e809ee4

Browse files
committed
feat(grammar): EBO and default construction to token_rule_t
fix #936
1 parent aef0b8b commit e809ee4

File tree

3 files changed

+84
-4
lines changed

3 files changed

+84
-4
lines changed

include/boost/url/grammar/impl/token_rule.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ parse(
3131
BOOST_URL_RETURN_EC(
3232
error::need_more);
3333
}
34-
it = (find_if_not)(it, end, cs_);
34+
auto const& cs = this->get();
35+
it = grammar::find_if_not(it, end, cs);
3536
if(it != it0)
3637
return core::string_view(it0, it - it0);
3738
BOOST_URL_RETURN_EC(

include/boost/url/grammar/token_rule.hpp

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <boost/url/grammar/charset.hpp>
1515
#include <boost/url/error_types.hpp>
1616
#include <boost/core/detail/string_view.hpp>
17+
#include <boost/core/empty_value.hpp>
18+
#include <type_traits>
1719

1820
namespace boost {
1921
namespace urls {
@@ -22,6 +24,7 @@ namespace grammar {
2224
namespace implementation_defined {
2325
template<class CharSet>
2426
struct token_rule_t
27+
: private empty_value<CharSet>
2528
{
2629
using value_type = core::string_view;
2730

@@ -39,12 +42,21 @@ struct token_rule_t
3942
constexpr
4043
token_rule_t(
4144
CharSet const& cs) noexcept
42-
: cs_(cs)
45+
: empty_value<CharSet>(
46+
empty_init, cs)
4347
{
4448
}
4549

46-
private:
47-
CharSet const cs_;
50+
template<class CS = CharSet>
51+
constexpr
52+
token_rule_t(
53+
typename std::enable_if<
54+
std::is_default_constructible<CS>::value,
55+
int>::type = 0) noexcept
56+
: empty_value<CharSet>(
57+
empty_init)
58+
{
59+
}
4860
};
4961
}
5062

@@ -86,6 +98,48 @@ token_rule(
8698
return {cs};
8799
}
88100

101+
/** Match a non-empty string of characters from a default-constructible set
102+
103+
This overload is only available when CharSet is
104+
default constructible.
105+
106+
If there is no more input, the error code
107+
@ref error::need_more is returned.
108+
109+
@par Value Type
110+
@code
111+
using value_type = core::string_view;
112+
@endcode
113+
114+
@par Example
115+
Rules are used with the function @ref parse.
116+
@code
117+
system::result< core::string_view > rv = parse( "abcdef", token_rule<alpha_chars_t>() );
118+
@endcode
119+
120+
@par BNF
121+
@code
122+
token = 1*( ch )
123+
@endcode
124+
125+
@tparam CharSet The character set type to use
126+
@return The token rule
127+
128+
@see
129+
@ref alpha_chars,
130+
@ref parse.
131+
*/
132+
template<BOOST_URL_CONSTRAINT(CharSet) CharSet>
133+
constexpr
134+
auto
135+
token_rule() noexcept ->
136+
typename std::enable_if<
137+
std::is_default_constructible<CharSet>::value,
138+
implementation_defined::token_rule_t<CharSet>>::type
139+
{
140+
return implementation_defined::token_rule_t<CharSet>();
141+
}
142+
89143
} // grammar
90144
} // urls
91145
} // boost

test/unit/grammar/token_rule.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,31 @@ struct token_rule_test
3737
ok(r, "a", "a");
3838
bad(r, "", error::need_more);
3939
bad(r, "1", error::mismatch);
40+
41+
// Test default construction with stateless CharSet
42+
{
43+
constexpr auto r2 = token_rule<implementation_defined::alpha_chars_t>();
44+
ok(r2, "abc", "abc");
45+
ok(r2, "ABC", "ABC");
46+
bad(r2, "", error::need_more);
47+
bad(r2, "123", error::mismatch);
48+
}
49+
50+
// Test EBO - token_rule_t with empty CharSet should be minimal size
51+
{
52+
// alpha_chars_t is empty (no data members)
53+
static_assert(
54+
sizeof(implementation_defined::token_rule_t<implementation_defined::alpha_chars_t>) == 1,
55+
"EBO should reduce size to 1 byte for empty CharSet");
56+
}
57+
58+
// Test that default-constructed rules work correctly at runtime
59+
{
60+
auto r3 = token_rule<implementation_defined::alpha_chars_t>();
61+
auto rv = parse("abcdef", r3);
62+
BOOST_TEST(rv.has_value());
63+
BOOST_TEST_EQ(rv.value(), "abcdef");
64+
}
4065
}
4166
};
4267

0 commit comments

Comments
 (0)