Last active
February 1, 2026 14:07
-
-
Save kerrytazi/df82b823c4488406ba19886f1df5a6d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| template < | |
| typename TResult, | |
| typename TState, | |
| typename TAdvance, | |
| typename TProjStateToResult = decltype([](const TState& state) -> TResult { return state; })> | |
| class simple_generator | |
| { | |
| public: | |
| constexpr simple_generator(TState&& initial_state, TAdvance&& advance_func) | |
| : initial_state_{ static_cast<TState&&>(initial_state) } | |
| , advance_func_{ static_cast<TAdvance&&>(advance_func) } | |
| { | |
| } | |
| constexpr explicit simple_generator(TAdvance&& advance_func) | |
| : simple_generator(TState{}, static_cast<TAdvance&&>(advance_func)) | |
| { | |
| } | |
| struct simple_iterator | |
| { | |
| simple_generator* gen; | |
| TState state; | |
| constexpr simple_iterator(simple_generator* _gen) | |
| : gen{ _gen } | |
| { | |
| if (gen) | |
| state = gen->initial_state_; | |
| } | |
| constexpr simple_iterator& operator++() | |
| { | |
| gen->advance_func_(state, [this]() { gen = nullptr; }); | |
| return *this; | |
| } | |
| constexpr bool operator==(const simple_iterator& other) const | |
| { | |
| if (gen != other.gen) | |
| return false; | |
| if (!gen) | |
| return true; | |
| return state == other.state; | |
| } | |
| constexpr TResult operator*() const | |
| { | |
| return gen->proj_state_to_result_(state); | |
| } | |
| }; | |
| constexpr simple_iterator begin() { return simple_iterator(this); } | |
| constexpr simple_iterator end() { return simple_iterator(nullptr); } | |
| private: | |
| [[no_unique_address]] TState initial_state_; | |
| [[no_unique_address]] TAdvance advance_func_; | |
| [[no_unique_address]] TProjStateToResult proj_state_to_result_; | |
| }; | |
| template <typename TResultState, typename TAdvance> | |
| constexpr auto make_simple_generator(TAdvance&& advance_func) | |
| { | |
| return simple_generator<TResultState, TResultState, TAdvance>(static_cast<TAdvance&&>(advance_func)); | |
| } | |
| template <typename TResultState, typename TAdvance> | |
| constexpr auto make_simple_generator(TResultState&& initial_state, TAdvance&& advance_func) | |
| { | |
| return simple_generator<TResultState, TResultState, TAdvance>(static_cast<TResultState&&>(initial_state), static_cast<TAdvance&&>(advance_func)); | |
| } | |
| template < | |
| typename TResult, | |
| typename TState, | |
| typename TProjStateToResult, | |
| typename TAdvance> | |
| constexpr auto make_simple_generator(TAdvance&& advance_func) | |
| { | |
| return simple_generator<TResult, TState, TAdvance, TProjStateToResult>(static_cast<TAdvance&&>(advance_func)); | |
| } | |
| template < | |
| typename TResult, | |
| typename TState, | |
| typename TProjStateToResult, | |
| typename TAdvance> | |
| constexpr auto make_simple_generator(TState&& initial_state, TAdvance&& advance_func) | |
| { | |
| return simple_generator<TResult, TState, TAdvance, TProjStateToResult>(static_cast<TState&&>(initial_state), static_cast<TAdvance&&>(advance_func)); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <type_traits> | |
| #include <iostream> | |
| constexpr auto gen1(int max) | |
| { | |
| return make_simple_generator<int>([max](auto& state, auto mark_done) { | |
| state++; | |
| if (state >= max) | |
| mark_done(); | |
| }); | |
| } | |
| template <int max> | |
| constexpr auto gen2() | |
| { | |
| return make_simple_generator<int>([](auto& state, auto mark_done) { | |
| state++; | |
| if (state >= max) | |
| mark_done(); | |
| }); | |
| } | |
| consteval int sum(int max) | |
| { | |
| int result = 0; | |
| for (auto v : gen1(10)) | |
| result += v; | |
| return result; | |
| } | |
| int main() | |
| { | |
| std::cout << "sizeof(gen1): " << sizeof(gen1(10)) << "\n"; | |
| for (auto v : gen1(10)) | |
| std::cout << v << " "; | |
| std::cout << "\n"; | |
| std::cout << "sizeof(gen2): " << sizeof(gen2<10>()) << "\n"; | |
| for (auto v : gen2<10>()) | |
| std::cout << v << " "; | |
| std::cout << "\n"; | |
| std::cout << sum(10) << "\n"; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment