Template
56 lines
1.1 KiB
C++
56 lines
1.1 KiB
C++
#pragma once
|
|
#include "core-library/views/trim-view.h"
|
|
|
|
namespace core {
|
|
|
|
template<std::ranges::forward_range Range>
|
|
requires requires(Range&& range) {
|
|
(void)range.empty();
|
|
(void)trim_view{(*std::begin(range))};
|
|
}
|
|
class trim_elements_view : public std::ranges::view_interface<trim_elements_view<Range>>
|
|
{
|
|
public:
|
|
constexpr trim_elements_view(Range range)
|
|
: m_range(std::move(range))
|
|
{
|
|
}
|
|
|
|
class iterator
|
|
{
|
|
public:
|
|
using base_t = std::ranges::iterator_t<Range>;
|
|
|
|
constexpr iterator(base_t base, base_t end)
|
|
: m_base{base}
|
|
, m_end{end}
|
|
{
|
|
}
|
|
|
|
constexpr bool operator!=(iterator other) const { return m_base != other.m_base; }
|
|
constexpr auto operator*() const { return trim_view{*m_base}; }
|
|
|
|
constexpr iterator& operator++()
|
|
{
|
|
// Skip empty elements
|
|
while (++m_base != m_end && std::ranges::empty(**this)) {}
|
|
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
base_t m_base;
|
|
base_t m_end;
|
|
};
|
|
|
|
constexpr auto begin() { return iterator{std::begin(m_range), std::end(m_range)}; }
|
|
constexpr auto end() { return iterator{std::end(m_range), std::end(m_range)}; }
|
|
|
|
private:
|
|
Range m_range{};
|
|
};
|
|
|
|
constexpr view_closure<trim_elements_view> trim_elements{};
|
|
|
|
}
|