#pragma once #include #include #include #include #include #include template concept spanable = std::is_constructible_v, T> && ! std::is_same_v>; namespace std { template std::ostream & operator<<(std::ostream & s, const span v) { s << '('; for (const auto & i : v) { if (&i != &v.front()) s << ", "; s << i; } return s << ')'; } template std::ostream & operator<<(std::ostream & s, const glm::mat & m) { return (s << std::span {&m[0], L}); } template std::ostream & operator<<(std::ostream & s, const glm::vec & v) { return (s << std::span {&v[0], L}); } template std::ostream & operator<<(std::ostream & s, const T & v) { return (s << std::span {v}); } inline std::ostream & operator<<(std::ostream & s, const Arc & arc) { return s << arc.first << " ↺ " << arc.second; } } template std::string streamed_string(const T & v) { std::stringstream ss; ss << v; return std::move(ss).str(); } #define CLOG(x) std::cerr << #x " : " << x << "\n";