Commit 160bcb72 authored by Victor Zverovich's avatar Victor Zverovich

Remove lazy_segment_range

parent c7ea093c
......@@ -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 <boost/text/grapheme_break.hpp>
# include <boost/text/grapheme_break.hpp>
#endif
#ifdef __clang__
......@@ -922,30 +922,31 @@ inline size_t compute_width(basic_string_view<Char> s) {
inline size_t compute_width(string_view s) {
#if FMT_USE_TEXT
basic_memory_buffer<uint32_t> 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<char8_t> s) {
#if FMT_USE_TEXT
return compute_width(string_view(
reinterpret_cast<const char*>(s.data(), s.size())));
return compute_width(
string_view(reinterpret_cast<const char*>(s.data(), s.size())));
#else
return count_code_points(s);
#endif // FMT_USE_TEXT
......
......@@ -2,7 +2,6 @@
#define BOOST_TEXT_GRAPHEME_BREAK_HPP
#include <boost/text/algorithm.hpp>
#include <boost/text/lazy_segment_range.hpp>
#include <boost/text/utility.hpp>
#include <boost/assert.hpp>
......@@ -366,117 +365,6 @@ constexpr std::array<std::array<bool, 15>, 15> grapheme_breaks = {{
};
}
#if 0
/** Returns the bounds of the grapheme that `it` lies within. */
template<typename CPIter, typename Sentinel>
cp_range<CPIter> grapheme(CPIter first, CPIter it, Sentinel last) noexcept
{
first = prev_grapheme_break(first, it, last);
return cp_range<CPIter>{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<typename CPRange, typename CPIter>
detail::undefined grapheme(CPRange & range, CPIter it) noexcept;
#endif
/** Returns a lazy range of the code point ranges delimiting graphemes in
`[first, last)`. */
template<typename CPIter, typename Sentinel>
detail::undefined graphemes(CPIter first, Sentinel last) noexcept;
/** Returns a lazy range of the code point ranges delimiting graphemes in
`range`. */
template<typename CPRange>
detail::undefined graphemes(CPRange & range) noexcept;
/** Returns a lazy range of the code point ranges delimiting graphemes in
`[first, last)`, in reverse. */
template<typename CPIter>
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<typename CPRange>
detail::undefined reversed_graphemes(CPRange & range) noexcept;
#else
#if 0
template<typename CPRange, typename CPIter>
auto grapheme(CPRange & range, CPIter it) noexcept
-> cp_range<detail::iterator_t<CPRange>>
{
auto first =
prev_grapheme_break(std::begin(range), it, std::end(range));
return cp_range<CPIter>{first, next_grapheme_break(first, range.end())};
}
#endif
template<typename CPIter, typename Sentinel>
lazy_segment_range<
CPIter,
Sentinel,
detail::next_grapheme_callable<CPIter, Sentinel>>
graphemes(CPIter first, Sentinel last) noexcept
{
detail::next_grapheme_callable<CPIter, Sentinel> next;
return {std::move(next), {first, last}, {last}};
}
template<typename CPRange>
auto graphemes(CPRange & range) noexcept -> lazy_segment_range<
detail::iterator_t<CPRange>,
detail::sentinel_t<CPRange>,
detail::next_grapheme_callable<
detail::iterator_t<CPRange>,
detail::sentinel_t<CPRange>>>
{
detail::next_grapheme_callable<
detail::iterator_t<CPRange>,
detail::sentinel_t<CPRange>>
next;
return {std::move(next),
{std::begin(range), std::end(range)},
{std::end(range)}};
}
template<typename CPIter>
lazy_segment_range<
CPIter,
CPIter,
detail::prev_grapheme_callable<CPIter>,
cp_range<CPIter>,
detail::const_reverse_lazy_segment_iterator,
true>
reversed_graphemes(CPIter first, CPIter last) noexcept
{
detail::prev_grapheme_callable<CPIter> prev;
return {std::move(prev), {first, last, last}, {first, first, last}};
}
template<typename CPRange>
auto reversed_graphemes(CPRange & range) noexcept -> lazy_segment_range<
detail::iterator_t<CPRange>,
detail::sentinel_t<CPRange>,
detail::prev_grapheme_callable<detail::iterator_t<CPRange>>,
cp_range<detail::iterator_t<CPRange>>,
detail::const_reverse_lazy_segment_iterator,
true>
{
detail::prev_grapheme_callable<detail::iterator_t<CPRange>> 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
#ifndef BOOST_TEXT_LAZY_SEGMENT_RANGE_HPP
#define BOOST_TEXT_LAZY_SEGMENT_RANGE_HPP
#include <boost/text/utility.hpp>
namespace boost { namespace text {
namespace detail {
template<typename CPIter, typename CPRange>
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<CPIter, CPRange>;
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<typename CPIter, typename, typename PrevFunc, typename CPRange>
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<CPIter, CPRange>;
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<CPIter>,
template<class, class, class, class> class IteratorTemplate =
detail::const_lazy_segment_iterator,
bool Reverse = false>
struct lazy_segment_range
{
using iterator = IteratorTemplate<CPIter, Sentinel, NextFunc, CPRange>;
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<iterator &>(first_).set_next_func(
const_cast<NextFunc *>(&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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment