forked from OctaForge/libostd
simplify range-for-only iterators using relaxed c++17 rules
parent
049c4b8c47
commit
32110bcb9f
|
@ -1121,7 +1121,9 @@ public:
|
||||||
/** Implements a minimal iterator just for range-based for loop.
|
/** Implements a minimal iterator just for range-based for loop.
|
||||||
* Do not use directly.
|
* Do not use directly.
|
||||||
*/
|
*/
|
||||||
detail::generator_iterator<T> end() noexcept;
|
std::nullptr_t end() noexcept {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/** Swaps two generators' states. */
|
/** Swaps two generators' states. */
|
||||||
void swap(generator &other) noexcept {
|
void swap(generator &other) noexcept {
|
||||||
|
@ -1239,7 +1241,9 @@ struct generator_range: input_range<generator_range<T>> {
|
||||||
/** Implements a minimal iterator just for range-based for loop.
|
/** Implements a minimal iterator just for range-based for loop.
|
||||||
* Do not use directly.
|
* Do not use directly.
|
||||||
*/
|
*/
|
||||||
detail::generator_iterator<T> end() noexcept;
|
std::nullptr_t end() noexcept {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
generator<T> *p_gen;
|
generator<T> *p_gen;
|
||||||
|
@ -1257,7 +1261,7 @@ namespace detail {
|
||||||
generator_iterator() = delete;
|
generator_iterator() = delete;
|
||||||
generator_iterator(generator<T> &g): p_gen(&g) {}
|
generator_iterator(generator<T> &g): p_gen(&g) {}
|
||||||
|
|
||||||
bool operator!=(generator_iterator const &) noexcept {
|
bool operator!=(std::nullptr_t) noexcept {
|
||||||
return !p_gen->empty();
|
return !p_gen->empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1280,21 +1284,11 @@ detail::generator_iterator<T> generator<T>::begin() noexcept {
|
||||||
return detail::generator_iterator<T>{*this};
|
return detail::generator_iterator<T>{*this};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
detail::generator_iterator<T> generator<T>::end() noexcept {
|
|
||||||
return detail::generator_iterator<T>{*this};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
detail::generator_iterator<T> generator_range<T>::begin() noexcept {
|
detail::generator_iterator<T> generator_range<T>::begin() noexcept {
|
||||||
return detail::generator_iterator<T>{*p_gen};
|
return detail::generator_iterator<T>{*p_gen};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
detail::generator_iterator<T> generator_range<T>::end() noexcept {
|
|
||||||
return detail::generator_iterator<T>{*p_gen};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
} /* namespace ostd */
|
} /* namespace ostd */
|
||||||
|
|
|
@ -230,55 +230,23 @@ constexpr bool is_output_range = detail::is_output_range_base<T>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
// range iterator
|
// range iterator
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct range_iterator {
|
struct range_iterator {
|
||||||
range_iterator(): p_range(), p_init(false) {}
|
range_iterator() = delete;
|
||||||
explicit range_iterator(T const &range): p_range(), p_init(true) {
|
explicit range_iterator(T const &range): p_range(range) {}
|
||||||
::new(&get_ref()) T(range);
|
explicit range_iterator(T &&range): p_range(std::move(range)) {}
|
||||||
}
|
|
||||||
explicit range_iterator(T &&range): p_range(), p_init(true) {
|
|
||||||
::new(&get_ref()) T(std::move(range));
|
|
||||||
}
|
|
||||||
range_iterator(const range_iterator &v): p_range(), p_init(true) {
|
|
||||||
::new(&get_ref()) T(v.get_ref());
|
|
||||||
}
|
|
||||||
range_iterator(range_iterator &&v): p_range(), p_init(true) {
|
|
||||||
::new(&get_ref()) T(std::move(v.get_ref()));
|
|
||||||
}
|
|
||||||
range_iterator &operator=(const range_iterator &v) {
|
|
||||||
destroy();
|
|
||||||
::new(&get_ref()) T(v.get_ref());
|
|
||||||
p_init = true;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
range_iterator &operator=(range_iterator &&v) {
|
|
||||||
destroy();
|
|
||||||
swap(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~range_iterator() {
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
range_iterator &operator++() {
|
range_iterator &operator++() {
|
||||||
get_ref().pop_front();
|
p_range.pop_front();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
range_reference_t<T> operator*() const {
|
range_reference_t<T> operator*() const {
|
||||||
return get_ref().front();
|
return p_range.front();
|
||||||
|
}
|
||||||
|
bool operator!=(std::nullptr_t) const {
|
||||||
|
return !p_range.empty();
|
||||||
}
|
}
|
||||||
bool operator!=(range_iterator) const { return !get_ref().empty(); }
|
|
||||||
private:
|
private:
|
||||||
T &get_ref() { return *reinterpret_cast<T *>(&p_range); }
|
std::decay_t<T> p_range;
|
||||||
T const &get_ref() const { return *reinterpret_cast<T const *>(&p_range); }
|
|
||||||
void destroy() {
|
|
||||||
if (p_init) {
|
|
||||||
get_ref().~T();
|
|
||||||
p_init = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::aligned_storage_t<sizeof(T), alignof(T)> p_range;
|
|
||||||
bool p_init;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,8 +521,8 @@ struct input_range {
|
||||||
detail::range_iterator<B> begin() const {
|
detail::range_iterator<B> begin() const {
|
||||||
return detail::range_iterator<B>(*static_cast<B const *>(this));
|
return detail::range_iterator<B>(*static_cast<B const *>(this));
|
||||||
}
|
}
|
||||||
detail::range_iterator<B> end() const {
|
std::nullptr_t end() const {
|
||||||
return detail::range_iterator<B>();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Size>
|
template<typename Size>
|
||||||
|
|
Loading…
Reference in New Issue