diff --git a/ostd/coroutine.hh b/ostd/coroutine.hh index 01c3484..189d980 100644 --- a/ostd/coroutine.hh +++ b/ostd/coroutine.hh @@ -1121,7 +1121,9 @@ public: /** Implements a minimal iterator just for range-based for loop. * Do not use directly. */ - detail::generator_iterator end() noexcept; + std::nullptr_t end() noexcept { + return nullptr; + } /** Swaps two generators' states. */ void swap(generator &other) noexcept { @@ -1239,7 +1241,9 @@ struct generator_range: input_range> { /** Implements a minimal iterator just for range-based for loop. * Do not use directly. */ - detail::generator_iterator end() noexcept; + std::nullptr_t end() noexcept { + return nullptr; + } private: generator *p_gen; @@ -1257,7 +1261,7 @@ namespace detail { generator_iterator() = delete; generator_iterator(generator &g): p_gen(&g) {} - bool operator!=(generator_iterator const &) noexcept { + bool operator!=(std::nullptr_t) noexcept { return !p_gen->empty(); } @@ -1280,21 +1284,11 @@ detail::generator_iterator generator::begin() noexcept { return detail::generator_iterator{*this}; } -template -detail::generator_iterator generator::end() noexcept { - return detail::generator_iterator{*this}; -} - template detail::generator_iterator generator_range::begin() noexcept { return detail::generator_iterator{*p_gen}; } -template -detail::generator_iterator generator_range::end() noexcept { - return detail::generator_iterator{*p_gen}; -} - /** @} */ } /* namespace ostd */ diff --git a/ostd/range.hh b/ostd/range.hh index ba36fa9..dbfc8ff 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -230,55 +230,23 @@ constexpr bool is_output_range = detail::is_output_range_base; namespace detail { // range iterator - template struct range_iterator { - range_iterator(): p_range(), p_init(false) {} - explicit range_iterator(T const &range): p_range(), p_init(true) { - ::new(&get_ref()) T(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() = delete; + explicit range_iterator(T const &range): p_range(range) {} + explicit range_iterator(T &&range): p_range(std::move(range)) {} range_iterator &operator++() { - get_ref().pop_front(); + p_range.pop_front(); return *this; } range_reference_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: - T &get_ref() { return *reinterpret_cast(&p_range); } - T const &get_ref() const { return *reinterpret_cast(&p_range); } - void destroy() { - if (p_init) { - get_ref().~T(); - p_init = false; - } - } - std::aligned_storage_t p_range; - bool p_init; + std::decay_t p_range; }; } @@ -553,8 +521,8 @@ struct input_range { detail::range_iterator begin() const { return detail::range_iterator(*static_cast(this)); } - detail::range_iterator end() const { - return detail::range_iterator(); + std::nullptr_t end() const { + return nullptr; } template