Make partial_range_t inherit from ranges::subrange
Delegate work to the standard library where possible.
This commit is contained in:
parent
932c8370d5
commit
3f1aa85ad6
|
@ -100,8 +100,9 @@ struct partial_range_error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename range_iterator, typename range_index_type>
|
template <typename range_iterator, typename range_index_type>
|
||||||
class partial_range_t
|
class partial_range_t : ranges::subrange<range_iterator>
|
||||||
{
|
{
|
||||||
|
using base_type = ranges::subrange<range_iterator>;
|
||||||
public:
|
public:
|
||||||
static_assert(!std::is_reference<range_iterator>::value);
|
static_assert(!std::is_reference<range_iterator>::value);
|
||||||
using iterator = range_iterator;
|
using iterator = range_iterator;
|
||||||
|
@ -119,58 +120,23 @@ public:
|
||||||
using partial_range_error =
|
using partial_range_error =
|
||||||
#endif
|
#endif
|
||||||
struct partial_range_error;
|
struct partial_range_error;
|
||||||
iterator m_begin, m_end;
|
using base_type::base_type;
|
||||||
partial_range_t(iterator b, iterator e) :
|
|
||||||
m_begin(b), m_end(e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
partial_range_t(const partial_range_t &) = default;
|
partial_range_t(const partial_range_t &) = default;
|
||||||
partial_range_t(partial_range_t &&) = default;
|
partial_range_t(partial_range_t &&) = default;
|
||||||
partial_range_t &operator=(const partial_range_t &) = default;
|
partial_range_t &operator=(const partial_range_t &) = default;
|
||||||
template <typename T>
|
using base_type::begin;
|
||||||
/* If `T &&`, after reference collapsing, is an lvalue
|
using base_type::end;
|
||||||
* reference, then the object referenced by `t` will remain in
|
using base_type::empty;
|
||||||
* scope after the statement that called this constructor, and
|
using base_type::size;
|
||||||
* there is no need to check whether the object `t` owns the
|
|
||||||
* iterated range.
|
|
||||||
*
|
|
||||||
* Otherwise, if `t` is an rvalue reference, require that `t` is
|
|
||||||
* a view onto a range, rather than owning the range. A `t`
|
|
||||||
* that owns the storage would leave the iterators dangling.
|
|
||||||
*
|
|
||||||
* These checks are not precise. It is possible to have a type
|
|
||||||
* T that remains in scope, but frees its storage early, and
|
|
||||||
* leaves the range dangling. It is possible to have a type T
|
|
||||||
* that owns the storage, and is not destroyed after the
|
|
||||||
* containing statement terminates. Neither are good designs,
|
|
||||||
* and neither can be handled here. These checks attempt to
|
|
||||||
* catch obvious mistakes.
|
|
||||||
*/
|
|
||||||
requires(std::ranges::borrowed_range<T>)
|
|
||||||
partial_range_t(T &&t) :
|
|
||||||
m_begin(std::ranges::begin(t)), m_end(std::ranges::end(t))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
[[nodiscard]]
|
|
||||||
iterator begin() const { return m_begin; }
|
|
||||||
[[nodiscard]]
|
|
||||||
iterator end() const { return m_end; }
|
|
||||||
[[nodiscard]]
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return m_begin == m_end;
|
|
||||||
}
|
|
||||||
[[nodiscard]]
|
|
||||||
std::size_t size() const { return std::distance(m_begin, m_end); }
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
std::reverse_iterator<iterator> rbegin() const
|
std::reverse_iterator<iterator> rbegin() const
|
||||||
{
|
{
|
||||||
return std::reverse_iterator<iterator>{m_end};
|
return std::reverse_iterator<iterator>{end()};
|
||||||
}
|
}
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
std::reverse_iterator<iterator> rend() const
|
std::reverse_iterator<iterator> rend() const
|
||||||
{
|
{
|
||||||
return std::reverse_iterator<iterator>{m_begin};
|
return std::reverse_iterator<iterator>{begin()};
|
||||||
}
|
}
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
partial_range_t<std::reverse_iterator<iterator>, index_type> reversed() const
|
partial_range_t<std::reverse_iterator<iterator>, index_type> reversed() const
|
||||||
|
@ -180,7 +146,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename range_iterator, typename range_index_type>
|
template <typename range_iterator, typename range_index_type>
|
||||||
inline constexpr bool std::ranges::enable_borrowed_range<partial_range_t<range_iterator, range_index_type>> = true;
|
inline constexpr bool std::ranges::enable_borrowed_range<partial_range_t<range_iterator, range_index_type>> = std::ranges::enable_borrowed_range<::ranges::subrange<range_iterator>>;
|
||||||
|
|
||||||
#if DXX_PARTIAL_RANGE_MINIMIZE_ERROR_TYPE
|
#if DXX_PARTIAL_RANGE_MINIMIZE_ERROR_TYPE
|
||||||
struct partial_range_error
|
struct partial_range_error
|
||||||
|
|
|
@ -62,6 +62,10 @@ public:
|
||||||
{
|
{
|
||||||
return std::distance(b, e);
|
return std::distance(b, e);
|
||||||
}
|
}
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return b == e;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
subrange(auto &r) -> subrange<decltype(std::ranges::begin(r)), decltype(std::ranges::end(r))>;
|
subrange(auto &r) -> subrange<decltype(std::ranges::begin(r)), decltype(std::ranges::end(r))>;
|
||||||
|
|
|
@ -590,18 +590,16 @@ void med_combine_duplicate_vertices(enumerated_array<uint8_t, MAX_VERTICES, vert
|
||||||
auto &vcvertptridx = Vertices.vcptridx;
|
auto &vcvertptridx = Vertices.vcptridx;
|
||||||
const auto &&range = make_range(vcvertptridx);
|
const auto &&range = make_range(vcvertptridx);
|
||||||
// Note: ok to do to <, rather than <= because w for loop starts at v+1
|
// Note: ok to do to <, rather than <= because w for loop starts at v+1
|
||||||
if (range.m_begin == range.m_end)
|
if (range.empty())
|
||||||
return;
|
return;
|
||||||
for (auto i = range.m_begin;;)
|
for (auto i = range.begin();;)
|
||||||
{
|
{
|
||||||
const auto &&v = *i;
|
const auto &&v = *i;
|
||||||
if (++i == range.m_end)
|
if (++i == range.end())
|
||||||
return;
|
return;
|
||||||
if (vlp[v]) {
|
if (vlp[v]) {
|
||||||
auto &vvp = *v;
|
auto &vvp = *v;
|
||||||
auto subrange = range;
|
for (auto &&w : ranges::subrange(i, range.end()))
|
||||||
subrange.m_begin = i;
|
|
||||||
range_for (auto &&w, subrange)
|
|
||||||
if (vlp[w]) { // used to be Vertex_active[w]
|
if (vlp[w]) { // used to be Vertex_active[w]
|
||||||
if (vnear(vvp, *w)) {
|
if (vnear(vvp, *w)) {
|
||||||
change_vertex_occurrences(vmsegptr, v, w);
|
change_vertex_occurrences(vmsegptr, v, w);
|
||||||
|
|
Loading…
Reference in a new issue