// Make a single container from two other containers suitable for ORxC template<class PARSER, class AB, class A, class B> class OR_CONTAINER2: public AB
{ using SELF= OR_CONTAINER2;
static_assert(std::is_base_of_v<A, AB>, "AB must derive from A");
static_assert(std::is_base_of_v<B, AB>, "AB must derive from B");
static_assert(std::negation_v<std::is_copy_constructible<AB>>, "Invalid use of OR_CONTAINER2"); public: using AB::AB; // Initialization on parse error
OR_CONTAINER2()
:AB(A(), B())
{ } // Initialization from its components
OR_CONTAINER2(A && rhs)
:AB(std::move(rhs),
B::Container::empty())
{ }
OR_CONTAINER2(B && rhs)
:AB(A::Container::empty(),
std::move(rhs))
{ } // Delete copying
OR_CONTAINER2(const SELF & rhs) = delete;
SELF & operator=(const SELF & rhs) = delete; // Initialization from itself
OR_CONTAINER2(SELF && rhs) = default;
SELF & operator=(SELF && rhs) = default; // Generating empty values explicit OR_CONTAINER2(AB && rhs) :AB(std::move(rhs)) { } static SELF empty(const PARSER &p)
{ return SELF(AB(A::Container::empty(p), B::Container::empty(p)));
} static SELF empty()
{ return SELF(AB(A::Container::empty(), B::Container::empty()));
}
};
// Make a single container from three other containers suitable for ORxC template<class PARSER, class ABC, class A, class B, class C> class OR_CONTAINER3: public ABC
{ using SELF= OR_CONTAINER3;
static_assert(std::is_base_of_v<A, ABC>, "ABC must derive from A");
static_assert(std::is_base_of_v<B, ABC>, "ABC must derive from B");
static_assert(std::is_base_of_v<C, ABC>, "ABC must derive from C");
static_assert(std::negation_v<std::is_copy_constructible<ABC>>, "Invalid use of OR_CONTAINER3"); public: using ABC::ABC;
template<class PARSER, typename PARSER::TokenID a, typename PARSER::TokenID b> class TokenChoiceCond2
{ public: staticbool allowed_token_id(typename PARSER::TokenID id)
{ return id == a || id == b; }
};
template<class PARSER, typename PARSER::TokenID a, typename PARSER::TokenID b, typename PARSER::TokenID c> class TokenChoiceCond3
{ public: staticbool allowed_token_id(typename PARSER::TokenID id)
{ return id == a || id == b || id == c; }
};
/* Aruleconsistingoftwootherrulesinarow: rule::=rule1rule2
*/ template<class PARSER, class A, class B> class AND2: public A, public B
{ public:
AND2() = default; // Delete copying
AND2(const AND2 & rhs) = delete;
AND2 & operator=(const AND2 & rhs) = delete; // Initializing from itself
AND2(AND2 && rhs) = default;
AND2 & operator=(AND2 &&rhs) = default; // Initializing from its components
AND2(A &&a, B &&b)
:A(std::move(a)), B(std::move(b))
{ }
AND2(PARSER *p)
:A(p),
B(A::operatorbool() ? B(p) : B())
{ if (A::operatorbool() && !B::operatorbool())
{
p->set_syntax_error(); // Reset A to have A, B reported as "false" by their operator bool()
A::operator=(std::move(A()));
}
DBUG_ASSERT(!operatorbool() || !p->is_error());
} explicitoperatorbool() const
{ return A::operatorbool() && B::operatorbool();
} static AND2 empty(const PARSER &p)
{ return AND2(A::empty(p), B::empty(p));
} using Opt= OPT<PARSER, AND2<PARSER, A, B>>;
};
/* Aruleconsistingofthreeotherrulesinarow: rule::=rule1rule2rule3
*/ template<class PARSER, class A, class B, class C> class AND3: public A, public B, public C
{ public:
AND3() = default; // Delete copying
AND3(const AND3 & rhs) = delete;
AND3 & operator=(const AND3 & rhs) = delete; // Initializing from itself
AND3(AND3 && rhs) = default;
AND3 & operator=(AND3 &&rhs) = default; // Initializing from components
AND3(A &&a, B &&b, C &&c)
:A(std::move(a)), B(std::move(b)), C(std::move(c))
{ }
AND3(PARSER *p)
:A(p),
B(A::operatorbool() ? B(p) : B()),
C(A::operatorbool() && B::operatorbool() ? C(p) : C())
{ if (A::operatorbool() && (!B::operatorbool() || !C::operatorbool()))
{
p->set_syntax_error(); // Reset A to have A, B, C reported as "false" by their operator bool()
A::operator=(std::move(A()));
B::operator=(std::move(B()));
C::operator=(std::move(C()));
}
DBUG_ASSERT(!operatorbool() || !p->is_error());
} explicitoperatorbool() const
{ return A::operatorbool() && B::operatorbool() && C::operatorbool();
} static AND3 empty(const PARSER &p)
{ return AND3(A::empty(p), B::empty(p), C::empty(p));
}
};
/* Aruleconsistingoffourotherrulesinarow: rule::=rule1rule2rule3rule4
*/ template<class PARSER, class A, class B, class C, class D> class AND4: public A, public B, public C, public D
{ public:
AND4() = default; // Delete copying
AND4(const AND4 & rhs) = delete;
AND4 & operator=(const AND4 & rhs) = delete; // Initializing from itself
AND4(AND4 && rhs) = default;
AND4 & operator=(AND4 &&rhs) = default; // Initializing from components
AND4(A &&a, B &&b, C &&c, D &&d)
:A(std::move(a)), B(std::move(b)), C(std::move(c)), D(std::move(d))
{ }
AND4(PARSER *p)
:A(p),
B(A::operatorbool() ? B(p) : B()),
C(A::operatorbool() && B::operatorbool() ? C(p) : C()),
D(A::operatorbool() && B::operatorbool() && C::operatorbool() ?
D(p) : D())
{ if (A::operatorbool() &&
(!B::operatorbool() || !C::operatorbool() || !D::operatorbool()))
{
p->set_syntax_error(); // Reset A to have A, B, C reported as "false" by their operator bool()
A::operator=(A());
B::operator=(B());
C::operator=(C());
D::operator=(D());
}
DBUG_ASSERT(!operatorbool() || !p->is_error());
} explicitoperatorbool() const
{ return A::operatorbool() && B::operatorbool() &&
C::operatorbool() && D::operatorbool();
} static AND4 empty(const PARSER &p)
{ return AND4(A::empty(p), B::empty(p), C::empty(), D::empty());
}
};
Forthecasewhenthethreebrancheshaveincompatiblestorage
*/ template<class PARSER, class A, class B, class C> class OR3: public A, public B, public C
{ public:
OR3() = default; // Delete copying
OR3(const OR3 & rhs) = delete;
OR3 & operator=(const OR3 & rhs) = delete; // Initializing from itself
OR3(OR3 &&rhs) = default;
OR3 & operator=(OR3 &&rhs) = default; // Initializing from components
OR3(A &&a, B &&b, C &&c)
:A(std::move(a)), B(std::move(b)), C(std::move(c))
{ }
OR3C(PARSER *p)
:CONTAINER(A(p))
{ if (CONTAINER::operatorbool() ||
CONTAINER::operator=(B(p)) ||
CONTAINER::operator=(C(p))) return;
DBUG_ASSERT(!CONTAINER::operatorbool());
} using Opt= OPT<PARSER, OR3C<PARSER, CONTAINER, A, B, C>>;
};
/* Aruleconsistingofachoiceoffourrules: rule::=rule1|rule2|rule3|rule4 Forthecasewhenthefourbrancheshaveincompatiblestorage
*/ template<class PARSER, class A, class B, class C, class D> class OR4: public A, public B, public C, public D
{ public:
OR4() = default; // Delete copying
OR4(const OR4 & rhs) = delete;
OR4 & operator=(const OR4 & rhs) = delete; // Initializing from itself
OR4(OR4 &&rhs) = default;
OR4 & operator=(OR4 &&rhs) = default;
ElementsareallocatedontheTHD'smemorypoolandmovedintoplace, ensuringproperlifetimemanagementwithintheparser'smemorycontext.
*/ template<typename ELEM_TYPE, typename PARSER> class List_container : public List<ELEM_TYPE>
{ public: bool add(PARSER *p, ELEM_TYPE &&elem)
{ // Allocate memory for the new list element
ELEM_TYPE *new_elem= (ELEM_TYPE*) p->thd()->alloc(sizeof(ELEM_TYPE)); if (!new_elem) returntrue; // Move-construct the new element in the preallocated memory
::new (new_elem) ELEM_TYPE(std::move(elem)); return List<ELEM_TYPE>::push_back(new_elem, p->thd()->mem_root);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.39Bemerkung:
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.