diff --git a/libvmake/examples/repeating.cpp b/libvmake/examples/repeating.cpp new file mode 100644 index 0000000..4dd0b14 --- /dev/null +++ b/libvmake/examples/repeating.cpp @@ -0,0 +1,8 @@ +#include "../vmake.hpp" +using namespace std; + +int main() { + vmake::outputln(cout, " ", vmake::repeat_n("hello", 5)); + vmake::outputln_n(cout, 5, " ", vmake::repeat("world")); + return 0; +} diff --git a/libvmake/vmake.hpp b/libvmake/vmake.hpp index 8f64387..a5d1037 100644 --- a/libvmake/vmake.hpp +++ b/libvmake/vmake.hpp @@ -93,18 +93,20 @@ struct ranged_step_sequence { } // namespace details template -inline auto iota(const Val &start) { - return details::iota_sequence(start); +inline auto iota(Val &&start) { + return details::iota_sequence::type>(std::forward(start)); } template -inline auto range(const Val &start, const Val &end) { - return details::ranged_sequence(start, end); +inline auto range(Val &&start, Val &&end) { + return details::ranged_sequence::type>(std::forward(start) + , std::forward(end)); } template -inline auto range(const Val &start, const Val &end, const Val &step) { - return details::ranged_step_sequence(start, end, step); +inline auto range(Val &&start, Val &&end, Val &&step) { + return details::ranged_step_sequence::type>(std::forward(start) + , std::forward(end), std::forward(step)); } namespace details { @@ -216,13 +218,13 @@ struct generator { } // namespace details template -inline auto make_generator(Args ...args) { - return details::generator(std::move(Func(args...))); +inline auto make_generator(Args&&... args) { + return details::generator(std::move(Func(std::forward(args)...))); } template inline constexpr auto generate(Func &&f) { - return details::generator(std::forward(f)); + return details::generator::type>(std::forward(f)); } namespace details { @@ -252,11 +254,43 @@ struct limitor { template inline auto take(Gen &&g, size_t lim) { - return details::limitor::type>(std::move(g), lim); + return details::limitor::type>(std::forward(g), lim); }; namespace details { +template +struct repeater { + using result = Tval; + + Tval x; + repeater(Tval &&x) : x(std::forward(x)) {}; + repeater(const repeater&) = default; + repeater(repeater &&) = default; + + constexpr bool is_terminated() const noexcept { + return false; + } + + Tval operator()() const { + return x; + } +}; + +} // namespace details + +template +inline auto repeat(Tval &&x) { + return details::repeater::type>(std::forward(x)); +} + +template +inline auto repeat_n(Tval &&x, size_t n) { + return take(repeat(std::forward(x)), n); +} + +namespace details { + template struct concator { using result = typename Gen1::result; @@ -285,7 +319,8 @@ struct concator { template inline constexpr auto concat(Gen1 &&x, Gen2 &&y) noexcept { - return details::concator(std::move(x), std::move(y)); + return details::concator::type + , typename std::decay::type>(std::forward(x), std::forward(y)); } namespace details { @@ -301,7 +336,6 @@ struct transformer { 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(); @@ -316,7 +350,8 @@ struct transformer { template inline auto transform(Gen &&g, Func &&f) { - return details::transformer(std::move(g), std::move(f)); + return details::transformer::type + , typename std::decay::type>(std::forward(g), std::forward(f)); } template @@ -409,22 +444,26 @@ inline auto cstyle() { return details::cstyle_rng(); } -inline auto cstyle(int seed) { +inline auto cstyle(unsigned seed) { std::srand(seed); std::rand(); return details::cstyle_rng(); } template -inline auto uniform_ints(Tval l, Tval r) { - return generate([rng = Engine(make_seed()), dis = std::uniform_int_distribution(l, r)]() mutable { +inline auto uniform_ints(Tval &&l, Tval &&r) { + return generate([rng = Engine(make_seed()) + , dis = std::uniform_int_distribution::type>( + std::forward(l), std::forward(r))]() mutable { return dis(rng); }); } template -inline auto uniform_reals(Tval l, Tval r) { - return generate([rng = Engine(make_seed()), dis = std::uniform_real_distribution(l, r)]() mutable { +inline auto uniform_reals(Tval &&l, Tval &&r) { + return generate([rng = Engine(make_seed()) + , dis = std::uniform_real_distribution::type>( + std::forward(l), std::forward(r))]() mutable { return dis(rng); }); }