-
-
Notifications
You must be signed in to change notification settings - Fork 125
Enable clojure.string-test.reverse
#882
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
Changes from 9 commits
27a28e6
cd041cf
07c682f
5511d81
98ec15e
f21aa03
0b832db
3b6ed41
07bfa38
867a6ce
4038c59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| #include <jtl/immutable_string.hpp> | ||
|
|
||
| namespace jtl | ||
| { | ||
| struct utf8_iterator | ||
| { | ||
| using iterator_category = std::bidirectional_iterator_tag; | ||
| using difference_type = std::ptrdiff_t; | ||
| using value_type = immutable_string; | ||
| using reference = value_type const &; | ||
|
|
||
| utf8_iterator() = default; | ||
| utf8_iterator(immutable_string const &s); | ||
| utf8_iterator(immutable_string const &s, value_type::size_type const position); | ||
|
|
||
| value_type operator*() const; | ||
| utf8_iterator &operator++(); | ||
| utf8_iterator operator++(int); | ||
| utf8_iterator &operator--(); | ||
| utf8_iterator operator--(int); | ||
| bool operator==(utf8_iterator const &it) const; | ||
|
|
||
| utf8_iterator begin() const; | ||
| utf8_iterator end() const; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Iterators do not have
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Below, when you use this with a reverse view, what we actually want is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for all the code churn. I'm still learning about iterators + range based for loops. I think I finally landed in a good place. Initially we talked about having two separate iterators forwards/reverse, but it felt better if we could have one iterator that could go forwards and backwards. |
||
|
|
||
| value_type data; | ||
| value_type::size_type i{}; | ||
| value_type::size_type n{}; | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| #include <jtl/utf8.hpp> | ||
|
|
||
| namespace jtl | ||
| { | ||
| using value_type = utf8_iterator::value_type; | ||
| using size_type = value_type::size_type; | ||
|
|
||
| static size_type next_char_size(immutable_string const &s, size_type const i) | ||
| { | ||
| auto const c(s[i]); | ||
| if(c <= 0x7f) | ||
| { | ||
| return 1; | ||
| } | ||
| else if((c & 0xE0) == 0xC0) | ||
| { | ||
| return 2; | ||
| } | ||
| else if((c & 0xF0) == 0xE0) | ||
| { | ||
| return 3; | ||
| } | ||
| else if((c & 0xF8) == 0xF0) | ||
| { | ||
| return 4; | ||
| } | ||
| else | ||
| { | ||
| throw std::runtime_error{ "Invalid UTF-8 string." }; | ||
| } | ||
| } | ||
|
|
||
| static bool is_continuation_byte(immutable_string const &s, size_type const i) | ||
| { | ||
| if(i == immutable_string::npos) | ||
| { | ||
| throw std::runtime_error{ "Invalid UTF-8 string." }; | ||
| } | ||
|
|
||
| return (s[i] & 0xC0) == 0x80; | ||
| } | ||
|
|
||
| static size_type prev_char_size(immutable_string const &data, size_type const i) | ||
| { | ||
| if(!is_continuation_byte(data, i - 1)) | ||
| { | ||
| return 1; | ||
| } | ||
| else if(!is_continuation_byte(data, i - 2)) | ||
| { | ||
| return 2; | ||
| } | ||
| else if(!is_continuation_byte(data, i - 3)) | ||
| { | ||
| return 3; | ||
| } | ||
| else if(!is_continuation_byte(data, i - 4)) | ||
| { | ||
| return 4; | ||
| } | ||
| else | ||
| { | ||
| throw std::runtime_error{ "Invalid UTF-8 string." }; | ||
| } | ||
| } | ||
|
|
||
| utf8_iterator::utf8_iterator(immutable_string const &s) | ||
| : data{ s } | ||
| , i{ s.empty() ? value_type::npos : 0 } | ||
| , n{ i == value_type::npos ? 0 : next_char_size(s, i) } | ||
| { | ||
| } | ||
|
|
||
| utf8_iterator::utf8_iterator(immutable_string const &s, value_type::size_type const position) | ||
| : data{ s } | ||
| , i{ s.empty() ? value_type::npos : position } | ||
| , n{ i == value_type::npos ? 0 : next_char_size(s, i) } | ||
| { | ||
| } | ||
|
|
||
| value_type utf8_iterator::operator*() const | ||
| { | ||
| return data.substr(i, n); | ||
| } | ||
|
|
||
| utf8_iterator &utf8_iterator::operator++() | ||
| { | ||
| if(i == value_type::npos) | ||
| { | ||
| i = 0; | ||
| n = next_char_size(data, i); | ||
| } | ||
| else | ||
| { | ||
| i += n; | ||
| if(i >= data.size()) | ||
| { | ||
| i = value_type::npos; | ||
| n = 0; | ||
| } | ||
| else | ||
| { | ||
| n = next_char_size(data, i); | ||
| } | ||
| } | ||
|
|
||
| return *this; | ||
| } | ||
|
|
||
| utf8_iterator utf8_iterator::operator++(int) | ||
| { | ||
| auto tmp{ *this }; | ||
| ++*this; | ||
| return tmp; | ||
| } | ||
|
|
||
| utf8_iterator &utf8_iterator::operator--() | ||
| { | ||
| if(i == 0) | ||
| { | ||
| i = value_type::npos; | ||
| n = 0; | ||
| } | ||
| else if(i == value_type::npos) | ||
| { | ||
| auto const size(data.size()); | ||
| n = prev_char_size(data, size); | ||
| i = size - n; | ||
| } | ||
| else | ||
| { | ||
| n = prev_char_size(data, i); | ||
| i -= n; | ||
| } | ||
| return *this; | ||
| } | ||
|
|
||
| utf8_iterator utf8_iterator::operator--(int) | ||
| { | ||
| auto tmp{ *this }; | ||
| --*this; | ||
| return tmp; | ||
| } | ||
|
|
||
| bool utf8_iterator::operator==(utf8_iterator const &it) const | ||
| { | ||
| return i == it.i && (data.data() == it.data.data() || data == it.data); | ||
| } | ||
|
|
||
| utf8_iterator utf8_iterator::begin() const | ||
| { | ||
| return { data, 0 }; | ||
| } | ||
|
|
||
| utf8_iterator utf8_iterator::end() const | ||
| { | ||
| return { data, value_type::npos }; | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.