Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ordered_match() function #26

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.d
test
result
test_ordering
tests/benchmark-exec/*
!tests/benchmark-exec/*.cpp
*.pyc
Expand All @@ -10,4 +11,4 @@ mtent12.txt
*.zip
tests/benchmark-range/*
!tests/benchmark-range/*.cpp
!tests/benchmark-range/*.hpp
!tests/benchmark-range/*.hpp
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

default: all

TARGETS := result.cpp test.cpp $(wildcard tests/benchmark-exec/*.cpp)
TARGETS := result.cpp test_ordering.cpp test.cpp $(wildcard tests/benchmark-exec/*.cpp)

DESATOMAT := /www/root/desatomat/console/desatomat.php

Expand Down
32 changes: 32 additions & 0 deletions include/ctre/atoms_characters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define CTRE__ATOMS_CHARACTERS__HPP

#include "utility.hpp"
#include "ordering.hpp"
#include <cstdint>

namespace ctre {
Expand All @@ -21,22 +22,41 @@ template <auto V> struct character {
template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value) noexcept {
return value == V;
}

template <typename CharT> CTRE_FORCE_INLINE static constexpr equal_less_greater compare_char(CharT value) noexcept {
if (value == V) return {1,1,1};
if (value < V) return {0,1,0};
return {0,0,1};
}
};

struct any {
template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT) noexcept { return true; }
template <typename CharT> CTRE_FORCE_INLINE static constexpr equal_less_greater compare_char(CharT value) noexcept {
return {1,0,0};
}
};

template <typename... Content> struct negative_set {
template <typename CharT> inline static constexpr bool match_char(CharT value) noexcept {
return !(Content::match_char(value) || ... || false);
}
template <typename CharT> inline static constexpr equal_less_greater compare_char(CharT value) noexcept {
return {!(Content::match_char(value) || ... || false), 0, 0};
}
};

template <typename... Content> struct set {
template <typename CharT> inline static constexpr bool match_char(CharT value) noexcept {
return (Content::match_char(value) || ... || false);
}

template <typename CharT> inline static constexpr equal_less_greater compare_char(CharT value) noexcept {
bool equal = (Content::compare_char(value).equal || ... || false);
bool less = (Content::compare_char(value).less && ... && true);
bool greater = (Content::compare_char(value).greater && ... && true);
return {equal, less, greater};
}
};

template <auto... Cs> struct enumeration : set<character<Cs>...> { };
Expand All @@ -45,12 +65,24 @@ template <typename... Content> struct negate {
template <typename CharT> inline static constexpr bool match_char(CharT value) noexcept {
return !(Content::match_char(value) || ... || false);
}

template <typename CharT> inline static constexpr equal_less_greater compare_char(CharT value) noexcept {
return {!(Content::match_char(value) || ... || false), 0, 0};
}
};

template <auto A, auto B> struct char_range {
template <typename CharT> CTRE_FORCE_INLINE static constexpr bool match_char(CharT value) noexcept {
return (value >= A) && (value <= B);
}

template <typename CharT> CTRE_FORCE_INLINE static constexpr equal_less_greater compare_char(CharT value) noexcept {
equal_less_greater ret;
if (value >= A && value <= B) ret.equal = true;
if (value <= A) ret.less = true;
if (value >= B) ret.greater = true;
return ret;
}
};

struct word_chars : set<char_range<'A','Z'>, char_range<'a','z'>, char_range<'0','9'>, character<'_'> > { };
Expand Down
324 changes: 324 additions & 0 deletions include/ctre/evaluation.hpp

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions include/ctre/ordering.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef CTRE__ORDERING__HPP
#define CTRE__ORDERING__HPP

namespace ctre {

enum class partial_ordering { less, greater, equal, unordered };

struct equal_less_greater {
bool equal : 1;
bool less : 1;
bool greater : 1;

constexpr equal_less_greater() noexcept : equal(0), less(0), greater(0) { }
constexpr equal_less_greater(bool e, bool l, bool g) noexcept : equal(e), less(l), greater(g) { }
};

} // namespace ctre

#endif // CTRE__ORDERING__HPP
68 changes: 61 additions & 7 deletions include/ctre/return_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define CTRE__RETURN_TYPE__HPP

#include "id.hpp"
#include "ordering.hpp"
#include <type_traits>
#include <tuple>
#include <string_view>
Expand All @@ -19,18 +20,31 @@ template <size_t Id, typename Name = void> struct captured_content {

using char_type = typename std::iterator_traits<Iterator>::value_type;

bool _matched{false};
equal_less_greater _elg;

using name = Name;

constexpr CTRE_FORCE_INLINE storage() noexcept {}
constexpr CTRE_FORCE_INLINE storage() noexcept : _elg{1, 1, 1} {}
constexpr CTRE_FORCE_INLINE storage(not_matched_tag_t) noexcept : _elg{0, 0, 0} {}

constexpr CTRE_FORCE_INLINE void matched() noexcept {
_matched = true;
// TODO review how matched() and unmatched() are used and revisit those algorithms.
_elg = {1, 0, 0};
}
constexpr CTRE_FORCE_INLINE void unmatch() noexcept {
_matched = false;
_elg = {0, 0, 0};
}

constexpr CTRE_FORCE_INLINE void mask_elg(equal_less_greater elg) {
_elg.equal &= elg.equal;
_elg.less &= elg.less;
_elg.greater &= elg.greater;
}
constexpr CTRE_FORCE_INLINE void mask_lg(equal_less_greater elg) {
_elg.less &= elg.less;
_elg.greater &= elg.greater;
}

constexpr CTRE_FORCE_INLINE void set_start(Iterator pos) noexcept {
_begin = pos;
}
Expand All @@ -51,7 +65,26 @@ template <size_t Id, typename Name = void> struct captured_content {
}

constexpr CTRE_FORCE_INLINE operator bool() const noexcept {
return _matched;
return _elg.equal;
}

constexpr CTRE_FORCE_INLINE bool is_less() const noexcept {
return _elg.less;
}

constexpr CTRE_FORCE_INLINE bool is_greater() const noexcept {
return _elg.greater;
}

constexpr CTRE_FORCE_INLINE operator equal_less_greater() const noexcept {
return _elg;
}

constexpr CTRE_FORCE_INLINE operator partial_ordering() const noexcept {
if (_elg.equal) return partial_ordering::equal;
if (_elg.less) return partial_ordering::less;
if (_elg.greater) return partial_ordering::greater;
return partial_ordering::unordered;
}

constexpr CTRE_FORCE_INLINE auto to_view() const noexcept {
Expand All @@ -77,6 +110,7 @@ template <typename... Captures> struct captures;
template <typename Head, typename... Tail> struct captures<Head, Tail...>: captures<Tail...> {
Head head{};
constexpr CTRE_FORCE_INLINE captures() noexcept { }
constexpr CTRE_FORCE_INLINE captures(not_matched_tag_t tag) noexcept : head(tag) { }
template <size_t id> CTRE_FORCE_INLINE static constexpr bool exists() noexcept {
if constexpr (id == Head::get_id()) {
return true;
Expand Down Expand Up @@ -143,7 +177,7 @@ template <typename Iterator, typename... Captures> struct regex_results {
captures<captured_content<0>::template storage<Iterator>, typename Captures::template storage<Iterator>...> _captures{};

constexpr CTRE_FORCE_INLINE regex_results() noexcept { }
constexpr CTRE_FORCE_INLINE regex_results(not_matched_tag_t) noexcept { }
constexpr CTRE_FORCE_INLINE regex_results(not_matched_tag_t tag) noexcept : _captures(tag) { }

// special constructor for deducting
constexpr CTRE_FORCE_INLINE regex_results(Iterator, ctll::list<Captures...>) noexcept { }
Expand All @@ -165,9 +199,29 @@ template <typename Iterator, typename... Captures> struct regex_results {
_captures.template select<0>().unmatch();
return *this;
}
constexpr CTRE_FORCE_INLINE regex_results & mask_elg(equal_less_greater elg) noexcept {
_captures.template select<0>().mask_elg(elg);
return *this;
}
constexpr CTRE_FORCE_INLINE regex_results & mask_lg(equal_less_greater elg) noexcept {
_captures.template select<0>().mask_lg(elg);
return *this;
}
constexpr CTRE_FORCE_INLINE operator bool() const noexcept {
return bool(_captures.template select<0>());
}
constexpr CTRE_FORCE_INLINE bool is_less() const noexcept {
return _captures.template select<0>().is_less();
}
constexpr CTRE_FORCE_INLINE bool is_greater() const noexcept {
return _captures.template select<0>().is_greater();
}
constexpr CTRE_FORCE_INLINE operator equal_less_greater() const noexcept {
return equal_less_greater(_captures.template select<0>());
}
constexpr CTRE_FORCE_INLINE operator partial_ordering() const noexcept {
return partial_ordering(_captures.template select<0>());
}

constexpr operator std::basic_string_view<char_type>() const noexcept {
return to_view();
Expand Down Expand Up @@ -215,4 +269,4 @@ namespace std {
};
}

#endif
#endif
2 changes: 1 addition & 1 deletion include/ctre/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
#define CTRE_FLATTEN __attribute__((flatten))
#endif

#endif
#endif
40 changes: 39 additions & 1 deletion include/ctre/wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,23 @@ struct zero_terminated_string_end_iterator {
constexpr CTRE_FORCE_INLINE bool operator!=(const wchar_t * ptr) const noexcept {
return *ptr != 0;
}
template<typename T>
friend constexpr CTRE_FORCE_INLINE bool operator==(T t, zero_terminated_string_end_iterator it) {
return it == t;
}
template<typename T>
friend constexpr CTRE_FORCE_INLINE bool operator!=(T t, zero_terminated_string_end_iterator it) {
return it != t;
}
};

template <typename RE> struct regular_expression {
template <typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto match_2(IteratorBegin begin, IteratorEnd end) noexcept {
return match_re(begin, end, RE());
}
template <typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto ordered_match_2(IteratorBegin begin, IteratorEnd end) noexcept {
return ordered_match_re(begin, end, RE());
}
template <typename IteratorBegin, typename IteratorEnd> constexpr CTRE_FORCE_INLINE static auto search_2(IteratorBegin begin, IteratorEnd end) noexcept {
return search_re(begin, end, RE());
}
Expand Down Expand Up @@ -60,6 +71,33 @@ template <typename RE> struct regular_expression {
static constexpr CTRE_FORCE_INLINE auto match(std::u32string_view sv) noexcept {
return match(sv.begin(), sv.end());
}
template <typename Iterator> constexpr CTRE_FORCE_INLINE static auto ordered_match(Iterator begin, Iterator end) noexcept {
return ordered_match_re(begin, end, RE());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(const char * s) noexcept {
return ordered_match_2(s, zero_terminated_string_end_iterator());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(const wchar_t * s) noexcept {
return ordered_match_2(s, zero_terminated_string_end_iterator());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(const std::string & s) noexcept {
return ordered_match_2(s.c_str(), zero_terminated_string_end_iterator());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(const std::wstring & s) noexcept {
return ordered_match_2(s.c_str(), zero_terminated_string_end_iterator());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(std::string_view sv) noexcept {
return ordered_match(sv.begin(), sv.end());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(std::wstring_view sv) noexcept {
return ordered_match(sv.begin(), sv.end());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(std::u16string_view sv) noexcept {
return ordered_match(sv.begin(), sv.end());
}
static constexpr CTRE_FORCE_INLINE auto ordered_match(std::u32string_view sv) noexcept {
return ordered_match(sv.begin(), sv.end());
}
template <typename Iterator> constexpr CTRE_FORCE_INLINE static auto search(Iterator begin, Iterator end) noexcept {
return search_re(begin, end, RE());
}
Expand Down Expand Up @@ -94,4 +132,4 @@ template <typename RE> regular_expression(RE) -> regular_expression<RE>;

}

#endif
#endif
28 changes: 28 additions & 0 deletions test_ordering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <ctre.hpp>

#include <iostream>

std::ostream& operator<<(std::ostream& os, ctre::partial_ordering ord) {
switch (ord) {
case ctre::partial_ordering::less :
return os << "less";
case ctre::partial_ordering::greater :
return os << "greater";
case ctre::partial_ordering::equal :
return os << "equal";
case ctre::partial_ordering::unordered :
return os << "unordered";
default :
return os << "BUMM!";
}
}

int main(int argc, char ** argv) {
using namespace ctre::literals;
constexpr auto re = "x*+^[a-y]+"_ctre;

std::cout << ctre::partial_ordering(re.match(argv[1])) << std::endl;
std::cout << ctre::partial_ordering(re.ordered_match(argv[1])) << std::endl;

return 0;
}