diff --git a/single-header/ctre-unicode.hpp b/single-header/ctre-unicode.hpp index da1db898..1206360a 100644 --- a/single-header/ctre-unicode.hpp +++ b/single-header/ctre-unicode.hpp @@ -239,6 +239,7 @@ Software. #include #include #include +#include #include namespace ctll { @@ -271,11 +272,16 @@ constexpr length_value_t length_and_value_of_utf16_code_point(uint16_t first_uni else return {first_unit, 1}; } +struct construct_from_pointer_t { }; + +constexpr auto construct_from_pointer = construct_from_pointer_t{}; + template struct fixed_string { char32_t content[N] = {}; size_t real_size{0}; bool correct_flag{true}; - template constexpr fixed_string(const T (&input)[N+1]) noexcept { + + template constexpr fixed_string(construct_from_pointer_t, const T * input) noexcept { if constexpr (std::is_same_v) { #ifdef CTRE_STRING_IS_UTF8 size_t out{0}; @@ -373,6 +379,10 @@ template struct fixed_string { } } } + + template constexpr fixed_string(const std::array & in) noexcept: fixed_string{construct_from_pointer, in.data()} { } + template constexpr fixed_string(const T (&input)[N+1]) noexcept: fixed_string{construct_from_pointer, input} { } + constexpr fixed_string(const fixed_string & other) noexcept { for (size_t i{0}; i < N; ++i) { content[i] = other.content[i]; @@ -440,6 +450,8 @@ template <> class fixed_string<0> { }; template fixed_string(const CharT (&)[N]) -> fixed_string; +template fixed_string(const std::array &) -> fixed_string; + template fixed_string(fixed_string) -> fixed_string; } @@ -3051,7 +3063,7 @@ struct utf8_iterator { struct sentinel { // this is here only because I want to support std::make_reverse_iterator - using self_type = utf8_iterator; + using self_type = sentinel; using value_type = char8_t; using reference = char8_t &; using pointer = const char8_t *; @@ -3069,6 +3081,20 @@ struct utf8_iterator { friend constexpr auto operator==(self_type, const char8_t * other_ptr) noexcept { return *other_ptr == char8_t{0}; } + + friend constexpr auto operator!=(self_type, const char8_t * other_ptr) noexcept { + return *other_ptr != char8_t{0}; + } + +#if __cpp_impl_three_way_comparison < 201907L + friend constexpr auto operator==(const char8_t * other_ptr, self_type) noexcept { + return *other_ptr == char8_t{0}; + } + + friend constexpr auto operator!=(const char8_t * other_ptr, self_type) noexcept { + return *other_ptr != char8_t{0}; + } +#endif }; const char8_t * ptr{nullptr}; @@ -3078,8 +3104,8 @@ struct utf8_iterator { return lhs.ptr < lhs.end; } - constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) { - return rhs.ptr < rhs.end; + constexpr friend bool operator!=(const utf8_iterator & lhs, const char8_t * rhs) { + return lhs.ptr != rhs; } constexpr friend bool operator!=(const utf8_iterator & lhs, const utf8_iterator & rhs) { @@ -3090,10 +3116,33 @@ struct utf8_iterator { return lhs.ptr >= lhs.end; } + constexpr friend bool operator==(const utf8_iterator & lhs, const char8_t * rhs) { + return lhs.ptr == rhs; + } + + constexpr friend bool operator==(const utf8_iterator & lhs, const utf8_iterator & rhs) { + return lhs.ptr == rhs.ptr; + } + +#if __cpp_impl_three_way_comparison < 201907L + constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) { + return rhs.ptr < rhs.end; + } + + constexpr friend bool operator!=(const char8_t * lhs, const utf8_iterator & rhs) { + return lhs == rhs.ptr; + } + constexpr friend bool operator==(sentinel, const utf8_iterator & rhs) { return rhs.ptr >= rhs.end; } + constexpr friend bool operator==(const char8_t * lhs, const utf8_iterator & rhs) { + return lhs == rhs.ptr; + } +#endif + + constexpr utf8_iterator & operator=(const char8_t * rhs) { ptr = rhs; return *this; @@ -3874,6 +3923,12 @@ constexpr auto first(ctll::list l, ctll::list, Tail return first(l, ctll::list{}); } +// atomic group +template +constexpr auto first(ctll::list l, ctll::list, Tail...>) noexcept { + return first(l, ctll::list{}); +} + // plus template constexpr auto first(ctll::list l, ctll::list, Tail...>) noexcept { @@ -4858,6 +4913,19 @@ constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator curre } } +template constexpr auto dependent_false = false; + +// atomic (unsupported for now) +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { + (void)begin; + (void)current; + (void)last; + (void)f; + (void)captures; + static_assert(dependent_false, "Atomic groups are not supported (yet)"); +} + // switching modes template constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { diff --git a/single-header/ctre.hpp b/single-header/ctre.hpp index 41750e34..8aafdbcc 100644 --- a/single-header/ctre.hpp +++ b/single-header/ctre.hpp @@ -236,6 +236,7 @@ Software. #include #include #include +#include #include namespace ctll { @@ -268,11 +269,16 @@ constexpr length_value_t length_and_value_of_utf16_code_point(uint16_t first_uni else return {first_unit, 1}; } +struct construct_from_pointer_t { }; + +constexpr auto construct_from_pointer = construct_from_pointer_t{}; + template struct fixed_string { char32_t content[N] = {}; size_t real_size{0}; bool correct_flag{true}; - template constexpr fixed_string(const T (&input)[N+1]) noexcept { + + template constexpr fixed_string(construct_from_pointer_t, const T * input) noexcept { if constexpr (std::is_same_v) { #ifdef CTRE_STRING_IS_UTF8 size_t out{0}; @@ -370,6 +376,10 @@ template struct fixed_string { } } } + + template constexpr fixed_string(const std::array & in) noexcept: fixed_string{construct_from_pointer, in.data()} { } + template constexpr fixed_string(const T (&input)[N+1]) noexcept: fixed_string{construct_from_pointer, input} { } + constexpr fixed_string(const fixed_string & other) noexcept { for (size_t i{0}; i < N; ++i) { content[i] = other.content[i]; @@ -437,6 +447,8 @@ template <> class fixed_string<0> { }; template fixed_string(const CharT (&)[N]) -> fixed_string; +template fixed_string(const std::array &) -> fixed_string; + template fixed_string(fixed_string) -> fixed_string; } @@ -3048,7 +3060,7 @@ struct utf8_iterator { struct sentinel { // this is here only because I want to support std::make_reverse_iterator - using self_type = utf8_iterator; + using self_type = sentinel; using value_type = char8_t; using reference = char8_t &; using pointer = const char8_t *; @@ -3066,6 +3078,20 @@ struct utf8_iterator { friend constexpr auto operator==(self_type, const char8_t * other_ptr) noexcept { return *other_ptr == char8_t{0}; } + + friend constexpr auto operator!=(self_type, const char8_t * other_ptr) noexcept { + return *other_ptr != char8_t{0}; + } + +#if __cpp_impl_three_way_comparison < 201907L + friend constexpr auto operator==(const char8_t * other_ptr, self_type) noexcept { + return *other_ptr == char8_t{0}; + } + + friend constexpr auto operator!=(const char8_t * other_ptr, self_type) noexcept { + return *other_ptr != char8_t{0}; + } +#endif }; const char8_t * ptr{nullptr}; @@ -3075,8 +3101,8 @@ struct utf8_iterator { return lhs.ptr < lhs.end; } - constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) { - return rhs.ptr < rhs.end; + constexpr friend bool operator!=(const utf8_iterator & lhs, const char8_t * rhs) { + return lhs.ptr != rhs; } constexpr friend bool operator!=(const utf8_iterator & lhs, const utf8_iterator & rhs) { @@ -3087,10 +3113,33 @@ struct utf8_iterator { return lhs.ptr >= lhs.end; } + constexpr friend bool operator==(const utf8_iterator & lhs, const char8_t * rhs) { + return lhs.ptr == rhs; + } + + constexpr friend bool operator==(const utf8_iterator & lhs, const utf8_iterator & rhs) { + return lhs.ptr == rhs.ptr; + } + +#if __cpp_impl_three_way_comparison < 201907L + constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) { + return rhs.ptr < rhs.end; + } + + constexpr friend bool operator!=(const char8_t * lhs, const utf8_iterator & rhs) { + return lhs == rhs.ptr; + } + constexpr friend bool operator==(sentinel, const utf8_iterator & rhs) { return rhs.ptr >= rhs.end; } + constexpr friend bool operator==(const char8_t * lhs, const utf8_iterator & rhs) { + return lhs == rhs.ptr; + } +#endif + + constexpr utf8_iterator & operator=(const char8_t * rhs) { ptr = rhs; return *this; @@ -3871,6 +3920,12 @@ constexpr auto first(ctll::list l, ctll::list, Tail return first(l, ctll::list{}); } +// atomic group +template +constexpr auto first(ctll::list l, ctll::list, Tail...>) noexcept { + return first(l, ctll::list{}); +} + // plus template constexpr auto first(ctll::list l, ctll::list, Tail...>) noexcept { @@ -4855,6 +4910,19 @@ constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator curre } } +template constexpr auto dependent_false = false; + +// atomic (unsupported for now) +template +constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept { + (void)begin; + (void)current; + (void)last; + (void)f; + (void)captures; + static_assert(dependent_false, "Atomic groups are not supported (yet)"); +} + // switching modes template constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list, Tail...>) noexcept {