From 0d0edbb5498f085a1d2de525b64e653918c7bfef Mon Sep 17 00:00:00 2001 From: szdytom Date: Wed, 19 Jul 2023 19:37:26 +0800 Subject: [PATCH] move mark object vmake::rng::require_unique -> vmake::require_unique --- libvmake/examples/random_numbers.cpp | 2 +- libvmake/vmake.hpp | 31 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libvmake/examples/random_numbers.cpp b/libvmake/examples/random_numbers.cpp index 4528fb7..403cbf4 100644 --- a/libvmake/examples/random_numbers.cpp +++ b/libvmake/examples/random_numbers.cpp @@ -4,7 +4,7 @@ using namespace std; int main() { vmake::outputln(cout, " ", vmake::take(vmake::rng::uniform_ints(1, 10), 15)); - vmake::outputln(cout, " ", vmake::take(vmake::rng::uniform_ints(vmake::rng::require_unique, 1, 20), 15)); + vmake::outputln(cout, " ", vmake::take(vmake::rng::uniform_ints(vmake::require_unique, 1, 20), 15)); vmake::outputln(cout, " ", vmake::take(vmake::rng::uniform_reals(1., 10.), 5)); return 0; } diff --git a/libvmake/vmake.hpp b/libvmake/vmake.hpp index a3c80a9..bbb3fc6 100644 --- a/libvmake/vmake.hpp +++ b/libvmake/vmake.hpp @@ -9,6 +9,8 @@ namespace vmake { +struct require_unique_t {} require_unique; + struct sequence_terminated_error : std::exception { virtual const char *what() const noexcept override final { return "iterating on a terminated sequence."; @@ -27,11 +29,10 @@ inline constexpr auto as_const_reference(typename as_const_reference_t::type return x; } -template #if __cplusplus >= 201703L -using optional = std::optional; +using std::optional; #else -using optional = nonstd::optional; +using nonstd::optional; #endif } // namespace polyfill @@ -138,16 +139,22 @@ struct ranged_iterator_extractor { using result = typename std::remove_reference())>::type; ContIt cur, end; + bool added; - ranged_iterator_extractor(const ContIt &begin, const ContIt &end) : cur(begin), end(end) {} + ranged_iterator_extractor(const ContIt &begin, const ContIt &end) : cur(begin) + , end(end), added(false) {} bool is_terminated() const noexcept { return cur == end; } auto operator()() { + // WARN: use for strange iterators such as std::istream_iterator + // do NOT try to optimize this into *it++ if (cur == end) throw sequence_terminated_error(); - return *cur++; + if (added) return *++cur; + added = true; + return *cur; } }; @@ -198,15 +205,13 @@ struct generator { Func g; - generator(Func &&g) : g(g) {} + generator(Func &&g) : g(std::forward(g)) {} generator(const Func &g) : g(g) {} - generator& operator=(generator &&y) = default; - generator& operator=(const generator &y) = default; generator(generator &&y) = default; generator(const generator &y) = default; - bool is_terminated() const noexcept { + constexpr bool is_terminated() const noexcept { return false; } @@ -403,11 +408,13 @@ inline filteror::type, typename std::decay::type> namespace details { +template +using tuple_cat_t = decltype(std::tuple_cat(std::declval()...)); + template struct repeat_tuple { static_assert(n > 0, ""); - using type = decltype(std::tuple_cat(std::declval>() - , std::declval::type>())); + using type = tuple_cat_t, typename repeat_tuple::type>; }; template @@ -517,8 +524,6 @@ inline auto uniform_ints(Tval &&l, Tval &&r) { }); } -struct require_unique_t {} require_unique; - namespace details { template