#pragma once #include "core-library/views/trim-view.h" namespace core { template requires requires(Range&& range) { range.empty(); trim_view{(*std::begin(range))}; } class trim_elements_view : public std::ranges::view_interface> { public: constexpr trim_elements_view(Range range) : m_range(std::move(range)) { } class iterator { public: using base_t = std::ranges::iterator_t; 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{}; }