diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-04-29 19:07:11 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-04-29 19:07:11 +0100 |
commit | 5a0b3927a33807cca4c77c40eb873f8a3b51b0b0 (patch) | |
tree | 4af0585ee8f8f468ab10c0a4fe9994fb30b79599 /lib/stream_support.h | |
parent | Dunno how, but some DOS new lines got in here! (diff) | |
download | ilt-5a0b3927a33807cca4c77c40eb873f8a3b51b0b0.tar.bz2 ilt-5a0b3927a33807cca4c77c40eb873f8a3b51b0b0.tar.xz ilt-5a0b3927a33807cca4c77c40eb873f8a3b51b0b0.zip |
Drop .hpp for header only things
Half of them acquired a .cpp part anyway
Diffstat (limited to 'lib/stream_support.h')
-rw-r--r-- | lib/stream_support.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/stream_support.h b/lib/stream_support.h new file mode 100644 index 0000000..7fb256c --- /dev/null +++ b/lib/stream_support.h @@ -0,0 +1,86 @@ +#pragma once + +#include "enumDetails.h" +#include <glm/glm.hpp> +#include <iostream> +#include <maths.h> +#include <span> +#include <sstream> +#include <type_traits> + +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>; + +namespace std { + template<typename T, std::size_t L> + std::ostream & + operator<<(std::ostream & s, const span<T, L> v) + { + s << '('; + for (const auto & i : v) { + if (&i != &v.front()) { + s << ", "; + } + s << i; + } + return s << ')'; + } + + template<glm::length_t L, glm::length_t R, typename T, glm::qualifier Q> + std::ostream & + operator<<(std::ostream & s, const glm::mat<L, R, T, Q> & m) + { + return (s << std::span {&m[0], L}); + } + + template<glm::length_t L, typename T, glm::qualifier Q> + std::ostream & + operator<<(std::ostream & s, const glm::vec<L, T, Q> & v) + { + 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) + { + return (s << '(' << v.first << ", " << v.second << ')'); + } + + inline std::ostream & + operator<<(std::ostream & s, const Arc & arc) + { + return s << arc.first << " ↺ " << arc.second; + } + + template<typename E> + concept IsEnum = std::is_enum_v<E>; + + template<IsEnum E> + inline std::ostream & + operator<<(std::ostream & s, const E & e) + { + return s << EnumTypeDetails<E>::typeName << "::" << EnumDetails<E>::to_string(e).value(); + } +} + +template<typename T> +std::string +streamed_string(const T & v) +{ + std::stringstream ss; + ss << v; + return std::move(ss).str(); +} + +#define CLOG(x) std::cerr << __LINE__ << " : " #x " : " << x << "\n"; |