diff --git a/include/fmt/format.h b/include/fmt/format.h index ac2e8df1..17be15b4 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -46,10 +46,10 @@ #include "core.h" #ifndef FMT_USE_TEXT -# define FMT_USE_TEXT 0 +# define FMT_USE_TEXT 0 #endif #if FMT_USE_TEXT -# include +# include #endif #ifdef __clang__ @@ -922,30 +922,31 @@ inline size_t compute_width(basic_string_view s) { inline size_t compute_width(string_view s) { #if FMT_USE_TEXT basic_memory_buffer code_points; - for (auto cp: boost::text::make_to_utf32_range(s)) code_points.push_back(cp); + for (auto cp : boost::text::make_to_utf32_range(s)) code_points.push_back(cp); size_t width = 0; - for (auto g: boost::text::graphemes(code_points)) { - auto cp = *g.begin(); + for (auto it = code_points.begin(), end = code_points.end(); it != end; + it = boost::text::next_grapheme_break(it, end)) { + auto cp = *it; // Based on http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c by Markus Kuhn. - width += 1 + - (cp >= 0x1100 && - (cp <= 0x115f || // Hangul Jamo init. consonants - cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET〈 - cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET 〉 - // CJK ... Yi except Unicode Character “〿”: - (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || - (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables - (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs - (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms - (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms - (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms - (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms - (cp >= 0x20000 && cp <= 0x2fffd) || // CJK - (cp >= 0x30000 && cp <= 0x3fffd) || - // Miscellaneous Symbols and Pictographs + Emoticons: - (cp >= 0x1f300 && cp <= 0x1f64f) || - // Supplemental Symbols and Pictographs: - (cp >= 0x1f900 && cp <= 0x1f9ff))); + width += + 1 + (cp >= 0x1100 && + (cp <= 0x115f || // Hangul Jamo init. consonants + cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET〈 + cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET 〉 + // CJK ... Yi except Unicode Character “〿”: + (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) || + (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables + (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs + (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms + (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms + (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms + (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms + (cp >= 0x20000 && cp <= 0x2fffd) || // CJK + (cp >= 0x30000 && cp <= 0x3fffd) || + // Miscellaneous Symbols and Pictographs + Emoticons: + (cp >= 0x1f300 && cp <= 0x1f64f) || + // Supplemental Symbols and Pictographs: + (cp >= 0x1f900 && cp <= 0x1f9ff))); } return width; #else @@ -955,8 +956,8 @@ inline size_t compute_width(string_view s) { inline size_t compute_width(basic_string_view s) { #if FMT_USE_TEXT - return compute_width(string_view( - reinterpret_cast(s.data(), s.size()))); + return compute_width( + string_view(reinterpret_cast(s.data(), s.size()))); #else return count_code_points(s); #endif // FMT_USE_TEXT diff --git a/src/text/boost/text/grapheme_break.hpp b/src/text/boost/text/grapheme_break.hpp index 884d16e0..ebf4b14e 100644 --- a/src/text/boost/text/grapheme_break.hpp +++ b/src/text/boost/text/grapheme_break.hpp @@ -2,7 +2,6 @@ #define BOOST_TEXT_GRAPHEME_BREAK_HPP #include -#include #include #include @@ -366,117 +365,6 @@ constexpr std::array, 15> grapheme_breaks = {{ }; } -#if 0 - /** Returns the bounds of the grapheme that `it` lies within. */ - template - cp_range grapheme(CPIter first, CPIter it, Sentinel last) noexcept - { - first = prev_grapheme_break(first, it, last); - return cp_range{first, next_grapheme_break(first, last)}; - } -#endif - -#ifdef BOOST_TEXT_DOXYGEN - -#if 0 - /** Returns the bounds of the grapheme that `it` lies within, - as a cp_range. */ - template - detail::undefined grapheme(CPRange & range, CPIter it) noexcept; -#endif - - /** Returns a lazy range of the code point ranges delimiting graphemes in - `[first, last)`. */ - template - detail::undefined graphemes(CPIter first, Sentinel last) noexcept; - - /** Returns a lazy range of the code point ranges delimiting graphemes in - `range`. */ - template - detail::undefined graphemes(CPRange & range) noexcept; - - /** Returns a lazy range of the code point ranges delimiting graphemes in - `[first, last)`, in reverse. */ - template - detail::undefined reversed_graphemes(CPIter first, CPIter last) noexcept; - - /** Returns a lazy range of the code point ranges delimiting graphemes in - `range`, in reverse. */ - template - detail::undefined reversed_graphemes(CPRange & range) noexcept; - -#else - -#if 0 - template - auto grapheme(CPRange & range, CPIter it) noexcept - -> cp_range> - { - auto first = - prev_grapheme_break(std::begin(range), it, std::end(range)); - return cp_range{first, next_grapheme_break(first, range.end())}; - } -#endif - - template - lazy_segment_range< - CPIter, - Sentinel, - detail::next_grapheme_callable> - graphemes(CPIter first, Sentinel last) noexcept - { - detail::next_grapheme_callable next; - return {std::move(next), {first, last}, {last}}; - } - - template - auto graphemes(CPRange & range) noexcept -> lazy_segment_range< - detail::iterator_t, - detail::sentinel_t, - detail::next_grapheme_callable< - detail::iterator_t, - detail::sentinel_t>> - { - detail::next_grapheme_callable< - detail::iterator_t, - detail::sentinel_t> - next; - return {std::move(next), - {std::begin(range), std::end(range)}, - {std::end(range)}}; - } - - template - lazy_segment_range< - CPIter, - CPIter, - detail::prev_grapheme_callable, - cp_range, - detail::const_reverse_lazy_segment_iterator, - true> - reversed_graphemes(CPIter first, CPIter last) noexcept - { - detail::prev_grapheme_callable prev; - return {std::move(prev), {first, last, last}, {first, first, last}}; - } - - template - auto reversed_graphemes(CPRange & range) noexcept -> lazy_segment_range< - detail::iterator_t, - detail::sentinel_t, - detail::prev_grapheme_callable>, - cp_range>, - detail::const_reverse_lazy_segment_iterator, - true> - { - detail::prev_grapheme_callable> prev; - return {std::move(prev), - {std::begin(range), std::end(range), std::end(range)}, - {std::begin(range), std::begin(range), std::end(range)}}; - } - -#endif - }} #endif diff --git a/src/text/boost/text/lazy_segment_range.hpp b/src/text/boost/text/lazy_segment_range.hpp deleted file mode 100755 index fa958c08..00000000 --- a/src/text/boost/text/lazy_segment_range.hpp +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef BOOST_TEXT_LAZY_SEGMENT_RANGE_HPP -#define BOOST_TEXT_LAZY_SEGMENT_RANGE_HPP - -#include - - -namespace boost { namespace text { - - namespace detail { - template - struct segment_arrow_proxy - { - explicit segment_arrow_proxy(CPRange value) : value_(value) {} - - CPRange * operator->() const noexcept - { - return &value_; - } - - private: - CPRange value_; - }; - - template< - typename CPIter, - typename Sentinel, - typename NextFunc, - typename CPRange> - struct const_lazy_segment_iterator - { - private: - NextFunc * next_func_; - CPIter prev_; - CPIter it_; - Sentinel last_; - - public: - using value_type = CPRange; - using pointer = detail::segment_arrow_proxy; - using reference = value_type; - using difference_type = std::ptrdiff_t; - using iterator_category = std::forward_iterator_tag; - - const_lazy_segment_iterator() noexcept : - next_func_(), - prev_(), - it_(), - last_() - {} - - const_lazy_segment_iterator(CPIter it, Sentinel last) noexcept : - next_func_(), - prev_(it), - it_(), - last_(last) - {} - - const_lazy_segment_iterator(Sentinel last) noexcept : - next_func_(), - prev_(), - it_(), - last_(last) - {} - - reference operator*() const noexcept - { - return value_type{prev_, it_}; - } - - pointer operator->() const noexcept { return pointer(**this); } - - const_lazy_segment_iterator & operator++() noexcept - { - auto const next_it = (*next_func_)(it_, last_); - prev_ = it_; - it_ = next_it; - return *this; - } - - void set_next_func(NextFunc * next_func) noexcept - { - next_func_ = next_func; - it_ = (*next_func_)(prev_, last_); - } - - friend bool operator==( - const_lazy_segment_iterator lhs, - const_lazy_segment_iterator rhs) noexcept - { - return lhs.prev_ == rhs.last_; - } - friend bool operator!=( - const_lazy_segment_iterator lhs, - const_lazy_segment_iterator rhs) noexcept - { - return !(lhs == rhs); - } - }; - - template - struct const_reverse_lazy_segment_iterator - { - private: - PrevFunc * prev_func_; - CPIter first_; - CPIter it_; - CPIter next_; - - public: - using value_type = CPRange; - using pointer = detail::segment_arrow_proxy; - using reference = value_type; - using difference_type = std::ptrdiff_t; - using iterator_category = std::forward_iterator_tag; - - const_reverse_lazy_segment_iterator() noexcept : - prev_func_(), - first_(), - it_(), - next_() - {} - - const_reverse_lazy_segment_iterator( - CPIter first, CPIter it, CPIter last) noexcept : - prev_func_(), - first_(first), - it_(it), - next_(last) - {} - - reference operator*() const noexcept - { - return value_type{it_, next_}; - } - - pointer operator->() const noexcept { return pointer(**this); } - - const_reverse_lazy_segment_iterator & operator++() noexcept - { - if (it_ == first_) { - next_ = first_; - return *this; - } - auto const prev_it = - (*prev_func_)(first_, std::prev(it_), next_); - next_ = it_; - it_ = prev_it; - return *this; - } - - void set_next_func(PrevFunc * prev_func) noexcept - { - prev_func_ = prev_func; - ++*this; - } - - friend bool operator==( - const_reverse_lazy_segment_iterator lhs, - const_reverse_lazy_segment_iterator rhs) noexcept - { - return lhs.next_ == rhs.first_; - } - friend bool operator!=( - const_reverse_lazy_segment_iterator lhs, - const_reverse_lazy_segment_iterator rhs) noexcept - { - return !(lhs == rhs); - } - }; - } - - /** Represents a range of non-overlapping subranges. Each subrange - represents some semantically significant segment, the semantics of - which are controlled by the `NextFunc` template parameter. For - instance, if `NextFunc` is next_paragraph_break, the subranges - produced by lazy_segment_range will be paragraphs. Each subrange is - lazily produced; an output subrange is not produced until a lazy range - iterator is dereferenced. */ - template< - typename CPIter, - typename Sentinel, - typename NextFunc, - typename CPRange = cp_range, - template class IteratorTemplate = - detail::const_lazy_segment_iterator, - bool Reverse = false> - struct lazy_segment_range - { - using iterator = IteratorTemplate; - - lazy_segment_range() noexcept {} - lazy_segment_range( - NextFunc next_func, iterator first, iterator last) noexcept : - next_func_(std::move(next_func)), - first_(first), - last_(last) - {} - - iterator begin() const noexcept - { - const_cast(first_).set_next_func( - const_cast(&next_func_)); - return first_; - } - iterator end() const noexcept { return last_; } - - /** Moves the contained `NextFunc` out of *this. */ - NextFunc && next_func() && noexcept { return std::move(next_func_); } - - private: - NextFunc next_func_; - iterator first_; - iterator last_; - }; - -}} - -#endif