From d0da8b6fbb10fe06796750249f23b843c38637ce Mon Sep 17 00:00:00 2001 From: Pierre Delaunay Date: Thu, 16 May 2024 20:13:47 -0400 Subject: [PATCH] Fix GCC subpar constexpr handling --- src/utilities/magic.h | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/utilities/magic.h b/src/utilities/magic.h index fd97e0ea..555bd214 100644 --- a/src/utilities/magic.h +++ b/src/utilities/magic.h @@ -28,17 +28,20 @@ KW_IS_EXPR_VALID(ostream, std::declval() << std::declval()) // Helper output to anything but std::cout by default template void print(T const& obj, std::ostream& out = std::cout) { - if constexpr (has_str::value) { + constexpr bool impl_str = has_str::value; + constexpr bool impl_os = has_ostream::value; + + if constexpr (impl_str) { out << obj.__str__(); return; } - else if constexpr (has_ostream::value) { + else if constexpr (impl_os) { out << obj; return; - } else { - //static_assert(false, "Could not find a convert function"); - obj.print(out); - } + } + + static_assert(impl_str || impl_os, "Could not find a convert function"); + obj.print(out); } template @@ -49,17 +52,20 @@ void print(T* const& obj, std::ostream& out = std::cout) { // Helper Output to string template String str(T const& obj) { - if constexpr (has_str::value) { + constexpr bool impl_str = has_str::value; + constexpr bool impl_os = has_ostream::value; + + if constexpr (impl_str) { return obj.__str__(); } - else if constexpr (has_ostream::value) { + else if constexpr (impl_os) { // C++ operator StringStream ss; ss << obj; return ss.str(); - } else { - //static_assert(false, "Could not find a convert function"); - } + } + + static_assert(impl_str || impl_os, "Could not find a convert function"); } @@ -93,13 +99,16 @@ inline String str(String const& obj) { return obj; } // makes idx - 1 well defined template int len(T const& val) { - if constexpr (has_len::value) { + constexpr bool impl_len = has_len::value; + constexpr bool impl_sz = has_size::value; + + if constexpr (impl_len) { return IndexType(val.__len__()); - } else if constexpr (has_size::value) { + } else if constexpr (impl_sz) { return IndexType(val.size()); - } else { - //static_assert(false, "Object does not provide len method"); - } + } + + static_assert(impl_sz || impl_len, "Object does not provide len method"); } #define BINARY(X) \