From 63d21bcb1fc4576fdd31172e69c20d80172f2317 Mon Sep 17 00:00:00 2001 From: szdytom Date: Tue, 18 Jul 2023 19:45:41 +0800 Subject: [PATCH] refactor: sort codes --- libvmake/vmake.hpp | 284 ++++++++++++++++++++++++--------------------- 1 file changed, 150 insertions(+), 134 deletions(-) diff --git a/libvmake/vmake.hpp b/libvmake/vmake.hpp index f7559ec..6bee903 100644 --- a/libvmake/vmake.hpp +++ b/libvmake/vmake.hpp @@ -12,6 +12,23 @@ struct sequence_terminated_error : std::exception { } }; +namespace polyfill { + +template +struct as_const_reference_t { + using type = const typename std::remove_reference::type&; +}; + +template +inline constexpr auto as_const_reference(typename as_const_reference_t::type x) noexcept { + return x; +} + +template +using optional = nonstd::optional; + +} // namespace polyfill + namespace details { template @@ -98,6 +115,15 @@ struct empty_sequence { } }; +} // namespace details + +template +inline auto nothing() { + return details::empty_sequence(); +} + +namespace details { + template struct ranged_iterator_extractor { using result = typename std::remove_reference())>::type; @@ -180,6 +206,20 @@ struct generator { } }; +} // namespace details + +template +inline auto make_generator(Args ...args) { + return details::generator(std::move(Func(args...))); +} + +template +inline constexpr auto generate(Func &&f) { + return details::generator(std::forward(f)); +} + +namespace details { + template struct limitor { using core = Gen; @@ -201,21 +241,122 @@ struct limitor { } }; -} - -template -inline auto nothing() { - return details::empty_sequence(); -} +} // namespace details template inline auto take(Gen &&g, size_t lim) { return details::limitor::type>(std::move(g), lim); }; -template -inline auto make_generator(Args ...args) { - return details::generator(std::move(Func(args...))); +namespace details { + +template +struct concator { + using result = typename Gen1::result; + using core = Gen1; + using core2 = Gen2; + + Gen1 g1; + Gen2 g2; + + concator(Gen1 &&g1, Gen2 &&g2) : g1(std::move(g1)), g2(std::move(g2)) {} + concator(concator &&c) = default; + concator(const concator &c) = default; +// concator& operator=(concator &&c) = default; + + bool is_terminated() const noexcept { + return g1.is_terminated() && g2.is_terminated(); + } + + auto operator()() { + if (g1.is_terminated()) return g2(); + return g1(); + } +}; + +} // namespace details + +template +inline constexpr auto concat(Gen1 &&x, Gen2 &&y) noexcept { + return details::concator(std::move(x), std::move(y)); +} + +namespace details { + +template +struct transformer { + using result = typename std::result_of::type; + using core = Gen; + + Gen g; + Func f; + + transformer(Gen &&g, Func &&gf) : g(std::move(g)), f(std::move(f)) {} + transformer(transformer &&c) = default; + transformer(const transformer &c) = default; +// transformer& operator=(transformer &&c) = default; + + bool is_terminated() const noexcept { + return g.is_terminated(); + } + + auto operator()() { + return f(g()); + } +}; + +} // namespace details + +template +inline auto transform(Gen &&g, Func &&f) { + return details::transformer(std::move(g), std::move(f)); +} + +template +struct filteror { + using result = typename Gen::result; + using core = Gen; + + filteror(filteror &&) = default; + filteror(const filteror &) = default; + + mutable Gen g; + Pred p; + mutable polyfill::optional preview; + + filteror(Gen &&g, Pred &&p) : g(std::forward(g)), p(std::forward(p)), preview() { + _find_next(); + }; + + bool is_terminated() const noexcept { + if (g.is_terminated() && !preview.has_value()) return true; + if (!preview.has_value()) _find_next(); + return !preview.has_value(); + } + + auto operator()() { + if (is_terminated()) throw sequence_terminated_error(); + result res = std::move(*preview); + preview.reset(); + return res; + } + +private: + void _find_next() const { + preview.reset(); + do { + if (g.is_terminated()) { + preview.reset(); + return; + } + preview.emplace(std::move(g())); + } while (!p(polyfill::as_const_reference(*preview))); + } +}; + +template +inline filteror::type, typename std::decay::type> filter(Gen &&g, Pred &&p) { + return {std::forward(g), std::forward(p)}; } namespace rng { @@ -277,62 +418,6 @@ inline OutputIt copy_n(OutputIt it, size_t n, Gen&& g) { return it; } -template -struct concator { - using result = typename Gen1::result; - using core = Gen1; - using core2 = Gen2; - - Gen1 g1; - Gen2 g2; - - concator(Gen1 &&g1, Gen2 &&g2) : g1(std::move(g1)), g2(std::move(g2)) {} - concator(concator &&c) = default; - concator(const concator &c) = default; -// concator& operator=(concator &&c) = default; - - bool is_terminated() const noexcept { - return g1.is_terminated() && g2.is_terminated(); - } - - auto operator()() { - if (g1.is_terminated()) return g2(); - return g1(); - } -}; - -template -inline constexpr auto concat(Gen1 &&x, Gen2 &&y) noexcept { - return concator(std::move(x), std::move(y)); -} - -template -struct transformer { - using result = typename std::result_of::type; - using core = Gen; - - Gen g; - Func f; - - transformer(Gen &&g, Func &&gf) : g(std::move(g)), f(std::move(f)) {} - transformer(transformer &&c) = default; - transformer(const transformer &c) = default; -// transformer& operator=(transformer &&c) = default; - - bool is_terminated() const noexcept { - return g.is_terminated(); - } - - auto operator()() { - return f(g()); - } -}; - -template -inline auto transform(Gen &&g, Func &&f) { - return transformer(std::move(g), std::move(f)); -} - template inline auto output(OutputStream& out, const char *delim, Gen &&g) { return copy(std::ostream_iterator::type::result>(out, delim), std::move(g)); @@ -353,75 +438,6 @@ inline auto output_n(OutputStream& out, size_t n, Gen &&g) { return copy_n(std::ostream_iterator::type::result>(out), n, std::move(g)); } -template -inline constexpr auto generate(Func &&f) { - return details::generator(std::forward(f)); -} - -namespace polyfill { - -template -struct as_const_reference_t { - using type = const typename std::remove_reference::type&; -}; - -template -inline constexpr auto as_const_reference(typename as_const_reference_t::type x) noexcept { - return x; -} - -template -using optional = nonstd::optional; - -} - -template -struct filteror { - using result = typename Gen::result; - using core = Gen; - - filteror(filteror &&) = default; - filteror(const filteror &) = default; - - mutable Gen g; - Pred p; - mutable polyfill::optional preview; - - filteror(Gen &&g, Pred &&p) : g(std::forward(g)), p(std::forward(p)), preview() { - _find_next(); - }; - - bool is_terminated() const noexcept { - if (g.is_terminated() && !preview.has_value()) return true; - if (!preview.has_value()) _find_next(); - return !preview.has_value(); - } - - auto operator()() { - if (is_terminated()) throw sequence_terminated_error(); - result res = std::move(*preview); - preview.reset(); - return res; - } - -private: - void _find_next() const { - preview.reset(); - do { - if (g.is_terminated()) { - preview.reset(); - return; - } - preview.emplace(std::move(g())); - } while (!p(polyfill::as_const_reference(*preview))); - } -}; - -template -inline filteror::type, typename std::decay::type> filter(Gen &&g, Pred &&p) { - return {std::forward(g), std::forward(p)}; -} - } #endif