@@ -239,6 +239,7 @@ Software.
239239#include <utility>
240240#include <cstddef>
241241#include <string_view>
242+ #include <array>
242243#include <cstdint>
243244
244245namespace ctll {
@@ -271,11 +272,16 @@ constexpr length_value_t length_and_value_of_utf16_code_point(uint16_t first_uni
271272 else return {first_unit, 1};
272273}
273274
275+ struct construct_from_pointer_t { };
276+
277+ constexpr auto construct_from_pointer = construct_from_pointer_t{};
278+
274279template <size_t N> struct fixed_string {
275280 char32_t content[N] = {};
276281 size_t real_size{0};
277282 bool correct_flag{true};
278- template <typename T> constexpr fixed_string(const T (&input)[N+1]) noexcept {
283+
284+ template <typename T> constexpr fixed_string(construct_from_pointer_t, const T * input) noexcept {
279285 if constexpr (std::is_same_v<T, char>) {
280286 #ifdef CTRE_STRING_IS_UTF8
281287 size_t out{0};
@@ -373,6 +379,10 @@ template <size_t N> struct fixed_string {
373379 }
374380 }
375381 }
382+
383+ template <typename T> constexpr fixed_string(const std::array<T, N> & in) noexcept: fixed_string{construct_from_pointer, in.data()} { }
384+ template <typename T> constexpr fixed_string(const T (&input)[N+1]) noexcept: fixed_string{construct_from_pointer, input} { }
385+
376386 constexpr fixed_string(const fixed_string & other) noexcept {
377387 for (size_t i{0}; i < N; ++i) {
378388 content[i] = other.content[i];
@@ -440,6 +450,8 @@ template <> class fixed_string<0> {
440450};
441451
442452template <typename CharT, size_t N> fixed_string(const CharT (&)[N]) -> fixed_string<N-1>;
453+ template <typename CharT, size_t N> fixed_string(const std::array<CharT,N> &) -> fixed_string<N>;
454+
443455template <size_t N> fixed_string(fixed_string<N>) -> fixed_string<N>;
444456
445457}
@@ -3051,7 +3063,7 @@ struct utf8_iterator {
30513063
30523064 struct sentinel {
30533065 // this is here only because I want to support std::make_reverse_iterator
3054- using self_type = utf8_iterator ;
3066+ using self_type = sentinel ;
30553067 using value_type = char8_t;
30563068 using reference = char8_t &;
30573069 using pointer = const char8_t *;
@@ -3069,6 +3081,20 @@ struct utf8_iterator {
30693081 friend constexpr auto operator==(self_type, const char8_t * other_ptr) noexcept {
30703082 return *other_ptr == char8_t{0};
30713083 }
3084+
3085+ friend constexpr auto operator!=(self_type, const char8_t * other_ptr) noexcept {
3086+ return *other_ptr != char8_t{0};
3087+ }
3088+
3089+ #if __cpp_impl_three_way_comparison < 201907L
3090+ friend constexpr auto operator==(const char8_t * other_ptr, self_type) noexcept {
3091+ return *other_ptr == char8_t{0};
3092+ }
3093+
3094+ friend constexpr auto operator!=(const char8_t * other_ptr, self_type) noexcept {
3095+ return *other_ptr != char8_t{0};
3096+ }
3097+ #endif
30723098 };
30733099
30743100 const char8_t * ptr{nullptr};
@@ -3078,8 +3104,8 @@ struct utf8_iterator {
30783104 return lhs.ptr < lhs.end;
30793105 }
30803106
3081- constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) {
3082- return rhs .ptr < rhs.end ;
3107+ constexpr friend bool operator!=(const utf8_iterator & lhs, const char8_t * rhs) {
3108+ return lhs .ptr != rhs;
30833109 }
30843110
30853111 constexpr friend bool operator!=(const utf8_iterator & lhs, const utf8_iterator & rhs) {
@@ -3090,10 +3116,33 @@ struct utf8_iterator {
30903116 return lhs.ptr >= lhs.end;
30913117 }
30923118
3119+ constexpr friend bool operator==(const utf8_iterator & lhs, const char8_t * rhs) {
3120+ return lhs.ptr == rhs;
3121+ }
3122+
3123+ constexpr friend bool operator==(const utf8_iterator & lhs, const utf8_iterator & rhs) {
3124+ return lhs.ptr == rhs.ptr;
3125+ }
3126+
3127+ #if __cpp_impl_three_way_comparison < 201907L
3128+ constexpr friend bool operator!=(sentinel, const utf8_iterator & rhs) {
3129+ return rhs.ptr < rhs.end;
3130+ }
3131+
3132+ constexpr friend bool operator!=(const char8_t * lhs, const utf8_iterator & rhs) {
3133+ return lhs == rhs.ptr;
3134+ }
3135+
30933136 constexpr friend bool operator==(sentinel, const utf8_iterator & rhs) {
30943137 return rhs.ptr >= rhs.end;
30953138 }
30963139
3140+ constexpr friend bool operator==(const char8_t * lhs, const utf8_iterator & rhs) {
3141+ return lhs == rhs.ptr;
3142+ }
3143+ #endif
3144+
3145+
30973146 constexpr utf8_iterator & operator=(const char8_t * rhs) {
30983147 ptr = rhs;
30993148 return *this;
@@ -3874,6 +3923,12 @@ constexpr auto first(ctll::list<Content...> l, ctll::list<sequence<Seq...>, Tail
38743923 return first(l, ctll::list<Seq..., Tail...>{});
38753924}
38763925
3926+ // atomic group
3927+ template <typename... Content, typename... Seq, typename... Tail>
3928+ constexpr auto first(ctll::list<Content...> l, ctll::list<atomic_group<Seq...>, Tail...>) noexcept {
3929+ return first(l, ctll::list<Seq..., Tail...>{});
3930+ }
3931+
38773932// plus
38783933template <typename... Content, typename... Seq, typename... Tail>
38793934constexpr auto first(ctll::list<Content...> l, ctll::list<plus<Seq...>, Tail...>) noexcept {
@@ -4858,6 +4913,19 @@ constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator curre
48584913 }
48594914}
48604915
4916+ template <typename...> constexpr auto dependent_false = false;
4917+
4918+ // atomic (unsupported for now)
4919+ template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename... Content, typename... Tail>
4920+ constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<atomic_group<Content...>, Tail...>) noexcept {
4921+ (void)begin;
4922+ (void)current;
4923+ (void)last;
4924+ (void)f;
4925+ (void)captures;
4926+ static_assert(dependent_false<Content...>, "Atomic groups are not supported (yet)");
4927+ }
4928+
48614929// switching modes
48624930template <typename R, typename BeginIterator, typename Iterator, typename EndIterator, typename Mode, typename... Tail>
48634931constexpr CTRE_FORCE_INLINE R evaluate(const BeginIterator begin, Iterator current, const EndIterator last, const flags & f, R captures, ctll::list<mode_switch<Mode>, Tail...>) noexcept {
0 commit comments