From 5f68ad764a2d16a199bbd5df0539609bcd69f898 Mon Sep 17 00:00:00 2001 From: Recolic Keghart <root@recolic.net> Date: Tue, 17 Mar 2020 08:29:19 -0700 Subject: [PATCH] add printable_iter --- stdio.hpp | 79 ++++++++++++++++------------------------------ test/src/common.cc | 11 +++++++ 2 files changed, 39 insertions(+), 51 deletions(-) diff --git a/stdio.hpp b/stdio.hpp index 80d6e6b..6cca73b 100644 --- a/stdio.hpp +++ b/stdio.hpp @@ -80,14 +80,6 @@ namespace rlib { void println(); template <typename... Args> void print(Args... args); - template <typename Iterable, typename Printable> - void print_iter(Iterable arg, Printable spliter); - template <typename Iterable, typename Printable> - void println_iter(Iterable arg, Printable spliter); - template <typename Iterable> - void print_iter(Iterable arg); - template <typename Iterable> - void println_iter(Iterable arg); template <typename... Args> size_t printf(const std::string &fmt, Args... args); template <typename... Args> @@ -100,6 +92,23 @@ namespace rlib { static bool instance = true; return instance; } + + template <typename Iterable, typename Printable> + struct _printable_iterable : private std::pair<Iterable, Printable> { + using std::pair<Iterable, Printable>::pair; + const Iterable &arg() const {return std::pair<Iterable, Printable>::first;} + const Printable &spliter() const {return std::pair<Iterable, Printable>::second;} + }; + } + + // 2 more interfaces... + template <typename Iterable, typename Printable> + const impl::_printable_iterable<Iterable, Printable> printable_iter(Iterable arg, Printable spliter) { + return impl::_printable_iterable<Iterable, Printable>(arg, spliter); + } + template <typename Iterable> + const impl::_printable_iterable<Iterable, char> printable_iter(Iterable arg) { + return impl::_printable_iterable<Iterable, char>(arg, ' '); } inline bool sync_with_stdio(bool sync = true) noexcept { @@ -122,18 +131,18 @@ namespace rlib { template <typename PrintFinalT> void print(std::ostream &os, PrintFinalT reqArg) { - os << reqArg; + os << std::forward<PrintFinalT>(reqArg); } template <typename Required, typename... Optional> void print(std::ostream &os, Required reqArgs, Optional... optiArgs) { os << reqArgs << ' '; - print(os, optiArgs ...); + print(os, std::forward<Optional>(optiArgs) ...); } template <typename... Optional> void println(std::ostream &os, Optional... optiArgs) { - print(os, optiArgs ...); + print(os, std::forward<Optional>(optiArgs) ...); println(os); } template <> @@ -142,29 +151,6 @@ namespace rlib { os << rlib::endl; } - template <typename Iterable, typename Printable> - void print_iter(std::ostream &os, Iterable arg, Printable spliter) - { - for(const auto & i : arg) - os << i << spliter; - } - template <typename Iterable, typename Printable> - void println_iter(std::ostream &os, Iterable arg, Printable spliter) - { - print_iter(os, arg, spliter); - println(os); - } - template <typename Iterable> - void print_iter(std::ostream &os, Iterable arg) - { - print_iter(os, arg, ' '); - } - template <typename Iterable> - void println_iter(std::ostream &os, Iterable arg) - { - println_iter(os, arg, ' '); - } - template <typename... Args> size_t printf(std::ostream &os, const std::string &fmt, Args... args) { @@ -195,22 +181,6 @@ namespace rlib { void print(Args... args) { return print(std::cout, std::forward<Args>(args) ...); } - template <typename Iterable, typename Printable> - void print_iter(Iterable arg, Printable spliter) { - return print_iter(std::cout, std::forward<Iterable>(arg), spliter); - } - template <typename Iterable, typename Printable> - void println_iter(Iterable arg, Printable spliter) { - return println_iter(std::cout, std::forward<Iterable>(arg), spliter); - } - template <typename Iterable> - void print_iter(Iterable arg) { - return print_iter(std::cout, std::forward<Iterable>(arg)); - } - template <typename Iterable> - void println_iter(Iterable arg) { - return println_iter(std::cout, std::forward<Iterable>(arg)); - } template <typename... Args> size_t printf(const std::string &fmt, Args... args) { return printf(std::cout, fmt, std::forward<Args>(args) ...); @@ -237,7 +207,14 @@ namespace rlib { std::ostream &, impl::print_wrapper<StreamType>>::type; return print(static_cast<ostream_or_data>(os), std::forward<Args>(args) ...); } -} +} // end namespace rlib +template <typename Iterable, typename Printable> +std::ostream& operator<< (std::ostream& stream, const rlib::impl::_printable_iterable<Iterable, Printable> &p) { + for(auto val : p.arg()) { + stream << val << p.spliter(); + } + return stream; +} #endif diff --git a/test/src/common.cc b/test/src/common.cc index e038767..c17ab4f 100644 --- a/test/src/common.cc +++ b/test/src/common.cc @@ -62,6 +62,10 @@ struct rlib_test_printable { return stream; } }; +struct rlib_test_iterable : public std::vector<float> { + using std::vector<float>::vector; +}; + TEST_CASE("stdio.hpp") { std::stringstream test_ss; rlib::print(test_ss, '>'); @@ -72,6 +76,13 @@ TEST_CASE("stdio.hpp") { rlib::printfln(test_ss, "hello, {}.", "godaddy"); REQUIRE(rlib::scanln(test_ss) == ">a b 123 0.25 2"); REQUIRE(rlib::scanln(test_ss) == "1hello, godaddy."); + + rlib_test_iterable v{1.2, 6.666, 12, -11.11}; + std::string answer = "1.21.2 6.666 12 -11.11 6.6661.2 6.666 12 -11.11 121.2 6.666 12 -11.11 -11.111.2 6.666 12 -11.11 "; + std::stringstream ss1, ss2; + rlib::println(ss1, rlib::printable_iter(v, rlib::printable_iter(v))); + rlib::print(ss2, rlib::printable_iter(v, rlib::printable_iter(v))); + rlib::println(ss1.str() == answer + '\n', ss2.str() == answer); } -- GitLab