30 : m_OutIter{std::move(
out)}
35 constexpr OutIter
out()
const
43 [&](
auto& base) {
visit(base); },
64 template <
typename State>
78 case Spec::id_unsigned:
100 case Spec::id_longlong:
111 constexpr void visit(state::BuiltinType
const& type)
123 if (!std::exchange(first,
false))
133 && (!
type.sizeSpec || lexing::keyword{
"int"} != *
type.base))
135 if (!std::exchange(first,
false))
149 case Qualifier::id_ref:
152 case Qualifier::id_refref:
163 constexpr void visit(state::CVQualifierSeq
const qualifiers)
165 if (qualifiers.isConst)
170 if (qualifiers.isVolatile)
181 static constexpr std::array syntheticAliases = std::to_array<std::pair<std::string_view, std::string_view>>({
182 {
"{anonymous}",
"{anon-ns}" },
183 {
"(anonymous namespace)",
"{anon-ns}" },
185 {
"`anonymous-namespace'",
"{anon-ns}" },
186 {
"`anonymous namespace'",
"{anon-ns}" },
187 {
"<unnamed-tag>",
"<unnamed tag>"},
190 constexpr void visit(state::Identifier
const&
id)
194 if (
auto const iter = std::ranges::find(syntheticAliases,
id.content, [](
auto const& e) {
return e.first; });
195 iter != syntheticAliases.cend())
202 if (
constexpr std::string_view prefix{
"(unnamed "}, suffix{
")"};
203 id.content.starts_with(prefix)
204 &&
id.content.ends_with(suffix))
206 std::string_view classType =
id.content;
207 classType.remove_prefix(prefix.size());
208 classType.remove_suffix(suffix.size());
209 classType = classType.substr(0, classType.find(
" at "));
216 if (
constexpr std::string_view prefix{
"(anonymous "}, suffix{
")"};
217 id.content.starts_with(prefix)
218 &&
id.content.ends_with(suffix))
220 std::string_view classType =
id.content;
221 classType.remove_prefix(prefix.size());
222 classType.remove_suffix(suffix.size());
223 classType = classType.substr(0, classType.find(
" at "));
230 if (
constexpr std::string_view prefix{
"<unnamed-type-anon_"}, suffix{
">"};
231 id.content.starts_with(prefix)
232 &&
id.content.ends_with(suffix))
234 std::string_view classType =
id.content;
235 classType.remove_prefix(prefix.size());
236 classType.remove_suffix(suffix.size());
246 constexpr void visit(state::PointerDeclarator
const& declarator)
248 if (declarator.scopes)
250 visit(*declarator.scopes);
255 if (declarator.qualifiers)
257 visit(*declarator.qualifiers);
261 constexpr void visit(state::ReferenceDeclarator
const& declarator)
263 visit(declarator.qualifier);
266 constexpr void visit(state::ArrayDeclarator
const& declarator)
272 visit(*declarator.size);
280 if (0 < m_NestedDepth)
288 state::TypeId
const voidTypeId{.base = state::BuiltinType{.base = lexing::keyword{
"void"}}};
289 if (1u != declarator.params.size()
290 || voidTypeId != declarator.params.front())
297 [&](
auto const& arg) { visit(arg); });
303 visit(declarator.qualifiers);
304 if (declarator.refQualifier)
306 visit(*declarator.refQualifier);
309 if (declarator.isNoexcept)
317 if (0 < m_NestedDepth)
329 [
this](
auto const& arg) {
331 [&](
auto const& inner) {
visit(inner); },
339 constexpr void visit(state::OperatorFunctionId
const&
id)
344 [
this](lexing::operator_or_punctuator
const& op) {
347 [
this](std::pair<lexing::keyword const, bool>
const& op) {
354 [
this](std::span<lexing::operator_or_punctuator const, 2u>
const op) {
356 std::move(m_OutIter),
364 constexpr void visit(state::ConversionFunctionId
const&
id)
370 constexpr void visit(state::DestructorFunctionId
const&
id)
375 constexpr void visit(state::LambdaFunctionId
const&
id)
385 constexpr void visit(state::UnqualifiedId
const& nested)
388 [&](
auto const& inner) {
visit(inner); },
391 if (nested.templateArgs)
393 visit(*nested.templateArgs);
396 if (nested.functionDeclarator)
398 visit(*nested.functionDeclarator);
402 constexpr void visit(std::span<state::UnqualifiedId const> scopes)
404 while (!scopes.empty())
406 auto const&
current = scopes.front();
407 scopes = scopes.subspan(1u);
409 if (
auto const*
const identifier = std::get_if<state::Identifier>(&
current.name);
411 &&
"__cxx11" == identifier->content)
421 if (std::get_if<state::LambdaFunctionId>(&
current.name)
424 if (
auto const*
const next = std::get_if<state::OperatorFunctionId>(&scopes.front().name);
428 scopes = scopes.subspan(1u);
433 else if (
auto const*
const currentId = std::get_if<state::Identifier>(&
current.name);
437 if (
auto const*
const next = std::get_if<state::Identifier>(&scopes.front().name);
439 &&
"{dtor}" == next->content)
441 visit(state::DestructorFunctionId{.name = *currentId});
443 scopes = scopes.subspan(1u);
449 constexpr void visit(state::ScopeSequence
const& sequence)
451 if (sequence.explicitRoot)
457 visit(sequence.scopes);
461 constexpr void visit(state::QualifiedId
const&
id)
464 visit(
id.identifier);
467 constexpr void visit(state::AbstractDeclarator::Layer
const& declarator)
469 for (
auto const& decoration : declarator.decorations)
472 [&](
auto const& inner) {
visit(inner); },
476 if (declarator.nested)
479 visit(*declarator.nested);
483 if (declarator.function)
485 visit(*declarator.function);
488 std::ranges::for_each(
490 [&](
auto const& arr) { visit(arr); });
493 template <std::ranges::forward_range Range>
496 std::string_view
const separator,
497 std::string_view
const terminator,
498 std::invocable<std::ranges::range_reference_t<Range>>
auto action)
500 if (std::ranges::subrange elements{range})
502 std::invoke(action, elements.front());
503 for (
auto const& element : elements.advance(1u))
506 std::invoke(action, element);
constexpr auto arg(Matcher &&matcher, Projection &&projection={}) noexcept(std::is_nothrow_constructible_v< std::remove_cvref_t< Matcher >, Matcher > &&std::is_nothrow_constructible_v< std::remove_cvref_t< Projection >, Projection >)
Checks whether the selected argument satisfies the given matcher.
Definition RequirementPolicies.hpp:233