diff options
-rw-r--r-- | lib/stream_support.h | 16 | ||||
-rw-r--r-- | test/test-static-stream_support.cpp | 21 |
2 files changed, 19 insertions, 18 deletions
diff --git a/lib/stream_support.h b/lib/stream_support.h index fa536f1..57d82a1 100644 --- a/lib/stream_support.h +++ b/lib/stream_support.h @@ -11,17 +11,16 @@ template<typename S> concept stringlike = requires(const S & s) { s.substr(0); }; template<typename T> -concept spanable = std::is_constructible_v<std::span<const typename T::value_type>, T> && !stringlike<T> - && !std::is_same_v<std::span<typename T::value_type>, T>; +concept NonStringIterableCollection + = std::is_same_v<decltype(std::declval<T>().begin()), decltype(std::declval<T>().end())> && !stringlike<T>; namespace std { - template<typename T, std::size_t L> std::ostream & - operator<<(std::ostream & s, const span<T, L> v) + operator<<(std::ostream & s, const NonStringIterableCollection auto & v) { s << '('; for (const auto & i : v) { - if (&i != &v.front()) { + if (&i != &*v.begin()) { s << ", "; } s << i; @@ -43,13 +42,6 @@ namespace std { return (s << std::span {&v[0], L}); } - template<spanable T> - std::ostream & - operator<<(std::ostream & s, const T & v) - { - return (s << std::span {v}); - } - template<typename First, typename Second> std::ostream & operator<<(std::ostream & s, const std::pair<First, Second> & v) diff --git a/test/test-static-stream_support.cpp b/test/test-static-stream_support.cpp index 3002ccc..6bf9ea4 100644 --- a/test/test-static-stream_support.cpp +++ b/test/test-static-stream_support.cpp @@ -1,11 +1,20 @@ #include "stream_support.h" #include <array> +#include <map> +#include <set> #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>); +static_assert(NonStringIterableCollection<std::vector<int>>); +static_assert(NonStringIterableCollection<std::set<int>>); +static_assert(NonStringIterableCollection<std::map<int, int>>); +static_assert(NonStringIterableCollection<std::vector<char>>); +static_assert(NonStringIterableCollection<std::array<int, 1>>); +static_assert(NonStringIterableCollection<std::array<char, 1>>); +static_assert(!NonStringIterableCollection<std::string>); +static_assert(!NonStringIterableCollection<std::string_view>); + +static_assert(requires(std::vector<int> i, std::ostream & o) { o << i; }); +static_assert(requires(std::array<int, 10> i, std::ostream & o) { o << i; }); +static_assert(requires(std::set<int> i, std::ostream & o) { o << i; }); +static_assert(requires(std::map<int, int> i, std::ostream & o) { o << i; }); |