diff options
-rw-r--r-- | lib/stream_support.cpp | 11 | ||||
-rw-r--r-- | lib/stream_support.hpp | 18 |
2 files changed, 19 insertions, 10 deletions
diff --git a/lib/stream_support.cpp b/lib/stream_support.cpp new file mode 100644 index 0000000..2054873 --- /dev/null +++ b/lib/stream_support.cpp @@ -0,0 +1,11 @@ +#include "stream_support.hpp" + +#include <array> +#include <vector> + +static_assert(spanable<std::vector<int>>); +// static_assert(spanable<std::vector<char>>); +static_assert(spanable<std::array<int, 1>>); +// static_assert(spanable<std::array<char, 1>>); +static_assert(!spanable<std::string>); +static_assert(!spanable<std::string_view>); diff --git a/lib/stream_support.hpp b/lib/stream_support.hpp index 0552b9d..3f0165c 100644 --- a/lib/stream_support.hpp +++ b/lib/stream_support.hpp @@ -5,6 +5,11 @@ #include <maths.h> #include <span> #include <sstream> +#include <type_traits> + +template<typename T> +concept spanable = std::is_constructible_v<std::span<const typename T::value_type>, T> && !std::is_same_v<char, + std::decay_t<typename T::value_type>>; namespace std { template<typename T, std::size_t L> @@ -34,16 +39,9 @@ namespace std { return (s << std::span {&v[0], L}); } - template<typename T, std::size_t L> - std::ostream & - operator<<(std::ostream & s, const array<T, L> & v) - { - return (s << std::span {v}); - } - - template<typename T> + template<spanable T> std::ostream & - operator<<(std::ostream & s, const vector<T> & v) + operator<<(std::ostream & s, const T & v) { return (s << std::span {v}); } @@ -61,7 +59,7 @@ streamed_string(const T & v) { std::stringstream ss; ss << v; - return ss.str(); + return std::move(ss).str(); } #define CLOG(x) std::cerr << #x " : " << x << "\n"; |