diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 29cbf1e6..869d269d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -13,6 +13,7 @@ endif () add_library(libpl ${LIBRARY_TYPE} source/pl/helpers/utils.cpp + source/pl/helpers/sort_checks.cpp source/pl/pattern_language.cpp diff --git a/lib/include/pl/core/token.hpp b/lib/include/pl/core/token.hpp index 5c9198e4..e274d914 100644 --- a/lib/include/pl/core/token.hpp +++ b/lib/include/pl/core/token.hpp @@ -220,8 +220,10 @@ namespace pl::core { constexpr bool operator==(const Comment &) const = default; }; + using LiteralVariantType = std::variant>; - struct Literal : std::variant> { + + struct Literal : LiteralVariantType { using variant::variant; [[nodiscard]] std::shared_ptr toPattern() const; diff --git a/lib/include/pl/helpers/sort_checks.hpp b/lib/include/pl/helpers/sort_checks.hpp new file mode 100644 index 00000000..74a51466 --- /dev/null +++ b/lib/include/pl/helpers/sort_checks.hpp @@ -0,0 +1,139 @@ +#pragma once + +//#define ENABLE_STD_SORT_CHECKS + +#ifdef ENABLE_STD_SORT_CHECKS +#include +#endif + +#include + +namespace pl::hlp { + +#ifdef ENABLE_STD_SORT_CHECKS + +void sortPredicateError(const char *pMsg); +void transitivityError(const char *pMsg, std::size_t b_idx, std::size_t e_idx, std::size_t x_idx, std::size_t y_idx); + +// Logical implication +inline bool imp(bool l, bool r) { + return !(l && !r); +} + +template +auto checked_pedicate(const Predicate pred) { + return [=](const auto &l, const auto &r) { + // Irreflexivity: !(x +void transitivity(const Iter cb, const Iter b, const Iter e, const Predicate pred) +{ + for (Iter l=b; l +void transitivity_of_incomparability(const Iter cb, const Iter b, const Iter e, const Predicate pred) +{ + for (Iter l=b; l +void post_sort_check(const Iter b, const Iter e, const Predicate pred) { + if (b==e) + return; + + for (Iter l=b; l=r && l>r + sortPredicateError("Not sorted"); // NOT sorted! + ++l; + } + } +} + +#endif // ENABLE_STD_SORT_CHECKS + +template +void checked_sort(RandomIt first, RandomIt last, Compare comp) { +#ifdef ENABLE_STD_SORT_CHECKS + std::sort(first, last, checked_pedicate(comp)); + post_sort_check(first, last, comp); +#else + std::sort(first, last, comp); +#endif +} + +template +void checked_stable_sort(RandomIt first, RandomIt last, Compare comp) { +#ifdef ENABLE_STD_SORT_CHECKS + std::stable_sort(first, last, checked_pedicate(comp)); + post_sort_check(first, last, comp); +#else + std::stable_sort(first, last, comp); +#endif +} + +} // namespace pl::hlp diff --git a/lib/include/pl/helpers/variant_type_index.hpp b/lib/include/pl/helpers/variant_type_index.hpp new file mode 100644 index 00000000..5252edcf --- /dev/null +++ b/lib/include/pl/helpers/variant_type_index.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +namespace pl::hlp { + +template +struct variant_type_index; + +template +struct variant_type_index> { + static constexpr auto value = [] -> std::size_t { + static_assert( + (std::is_same_v, Ts> || ...), + "T not in std::variant"); + constexpr bool matches[] = { std::is_same_v, Ts>... }; + + for (std::size_t i=0; i +inline constexpr std::size_t variant_type_index_v = variant_type_index::value; + +} // namespace pl::hlp \ No newline at end of file diff --git a/lib/include/pl/patterns/pattern_bitfield.hpp b/lib/include/pl/patterns/pattern_bitfield.hpp index 8cedee67..cc6d113f 100644 --- a/lib/include/pl/patterns/pattern_bitfield.hpp +++ b/lib/include/pl/patterns/pattern_bitfield.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace pl::ptrn { @@ -497,7 +498,7 @@ namespace pl::ptrn { for (auto &member : this->m_entries) this->m_sortedEntries.push_back(member.get()); - std::sort(this->m_sortedEntries.begin(), this->m_sortedEntries.end(), comparator); + pl::hlp::checked_sort(this->m_sortedEntries.begin(), this->m_sortedEntries.end(), comparator); if (this->isReversed()) std::reverse(this->m_sortedEntries.begin(), this->m_sortedEntries.end()); @@ -774,7 +775,7 @@ namespace pl::ptrn { for (auto &member : this->m_fields) this->m_sortedFields.push_back(member.get()); - std::sort(this->m_sortedFields.begin(), this->m_sortedFields.end(), comparator); + pl::hlp::checked_sort(this->m_sortedFields.begin(), this->m_sortedFields.end(), comparator); if (this->isReversed()) std::reverse(this->m_sortedFields.begin(), this->m_sortedFields.end()); diff --git a/lib/include/pl/patterns/pattern_struct.hpp b/lib/include/pl/patterns/pattern_struct.hpp index 900d517c..b0e2ca6b 100644 --- a/lib/include/pl/patterns/pattern_struct.hpp +++ b/lib/include/pl/patterns/pattern_struct.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace pl::ptrn { @@ -160,8 +161,7 @@ namespace pl::ptrn { for (auto &member : this->m_members) this->m_sortedMembers.push_back(member.get()); - std::sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), comparator); - + pl::hlp::checked_sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), comparator); for (auto &member : this->m_sortedMembers) member->sort(comparator); } diff --git a/lib/include/pl/patterns/pattern_union.hpp b/lib/include/pl/patterns/pattern_union.hpp index a38be0f7..a911a5ba 100644 --- a/lib/include/pl/patterns/pattern_union.hpp +++ b/lib/include/pl/patterns/pattern_union.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace pl::ptrn { @@ -159,7 +160,7 @@ namespace pl::ptrn { for (auto &member : this->m_members) this->m_sortedMembers.push_back(member.get()); - std::sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), comparator); + pl::hlp::checked_sort(this->m_sortedMembers.begin(), this->m_sortedMembers.end(), comparator); for (auto &member : this->m_members) member->sort(comparator); diff --git a/lib/source/pl/core/token.cpp b/lib/source/pl/core/token.cpp index 3bbddfe6..b8078423 100644 --- a/lib/source/pl/core/token.cpp +++ b/lib/source/pl/core/token.cpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace pl::core { @@ -160,8 +161,8 @@ namespace pl::core { return std::strong_ordering::greater; } }, - [](auto, auto) -> std::strong_ordering { - return std::strong_ordering::equal; + [](TL, TR) -> std::strong_ordering { + return hlp::variant_type_index_v <=> hlp::variant_type_index_v; } }, *this, other); } diff --git a/lib/source/pl/helpers/sort_checks.cpp b/lib/source/pl/helpers/sort_checks.cpp new file mode 100644 index 00000000..e92c8f45 --- /dev/null +++ b/lib/source/pl/helpers/sort_checks.cpp @@ -0,0 +1,25 @@ +#include + +#ifdef ENABLE_STD_SORT_CHECKS +#include +#include + +using std::size_t; +using std::cout; +using std::endl; + +namespace pl::hlp { + +void sortPredicateError(const char *pMsg) { + cout << pMsg << endl; +} + +void transitivityError(const char *pMsg, size_t b_idx, size_t e_idx, size_t x_idx, size_t y_idx) { + cout << pMsg << endl + << " Run: " << "b_idx=" << b_idx << ", e_idx=" << e_idx << endl + << " Error: " << "x_idx=" << x_idx << ", y_idx=" << y_idx << endl; +} + +} // namespace pl::hlp + +#endif // ENABLE_STD_SORT_CHECKS