From 3a82495a4c8845aaaf8e2285249bdfbc535645df Mon Sep 17 00:00:00 2001 From: q66 Date: Sun, 19 Feb 2017 18:46:43 +0100 Subject: [PATCH] cleanups and optimizations --- ostd/io.hh | 16 ++++++++++++++++ ostd/string.hh | 39 ++++++++++++--------------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/ostd/io.hh b/ostd/io.hh index 5ea534b..1fc7c72 100644 --- a/ostd/io.hh +++ b/ostd/io.hh @@ -193,6 +193,22 @@ namespace detail { } } }; + + template + inline void range_put_all(stdout_range &r, R range) { + if constexpr( + is_contiguous_range && + std::is_same_v>, char> + ) { + if (fwrite(range.data(), 1, range.size(), stdout) != range.size()) { + throw io_error{"stdout write error"}; + } + } else { + for (; !range.empty(); range.pop_front()) { + r.put(range.front()); + } + } + } } template diff --git a/ostd/string.hh b/ostd/string.hh index 10227eb..0c977f2 100644 --- a/ostd/string.hh +++ b/ostd/string.hh @@ -431,30 +431,7 @@ inline namespace string_literals { } } -namespace detail { - template< - typename T, bool = std::is_convertible_v, - bool = std::is_convertible_v - > - struct ConcatPut; - - template - struct ConcatPut { - template - static void put(R &sink, string_range v) { - range_put_all(sink, v); - } - }; - - template - struct ConcatPut { - template - static void put(R &sink, char v) { - sink.put(v); - } - }; -} - +/* TODO: redesign this */ template R &&concat(R &&sink, T const &v, string_range sep, F func) { auto range = ostd::iter(v); @@ -462,9 +439,17 @@ R &&concat(R &&sink, T const &v, string_range sep, F func) { return std::forward(sink); } for (;;) { - detail::ConcatPut< - decltype(func(range.front())) - >::put(sink, func(range.front())); + using VT = decltype(func(range.front())); + static_assert( + std::is_convertible_v || + std::is_convertible_v, + "range value must be convertible to string range or char" + ); + if constexpr(std::is_convertible_v) { + range_put_all(sink, string_range{func(range.front())}); + } else { + sink.put(func(range.front())); + } range.pop_front(); if (range.empty()) { break;