diff --git a/include/pmtv/meson.build b/include/pmtv/meson.build index d882c88..9edb38e 100644 --- a/include/pmtv/meson.build +++ b/include/pmtv/meson.build @@ -1,13 +1,8 @@ files = [ 'pmt.hpp', 'rva_variant.hpp', -<<<<<<< HEAD - 'version.hpp', - 'type_helpers.hpp' -======= 'type_helpers.hpp', 'version.hpp' ->>>>>>> base/main ] install_headers(files, subdir : 'pmtv') diff --git a/include/pmtv/pmt.hpp b/include/pmtv/pmt.hpp index 73ce0c6..982449f 100644 --- a/include/pmtv/pmt.hpp +++ b/include/pmtv/pmt.hpp @@ -528,7 +528,7 @@ T cast(const P& value) return std::visit( [](const auto& arg) -> T { using U = std::decay_t; - if constexpr (std::constructible_from) { + if constexpr (std::convertible_to) { if constexpr(Complex) { if constexpr (std::integral || std::floating_point) { return std::complex(static_cast(arg)); @@ -593,67 +593,24 @@ struct formatter

template auto format(const P& value, FormatContext& ctx) const { - // Due to an issue with the c++ spec that has since been resolved, we have to do something - // funky here. See - // https://stackoverflow.com/questions/37526366/nested-constexpr-function-calls-before-definition-in-a-constant-expression-con - // This problem only appears to occur in gcc 11 in certain optimization modes. The problem - // occurs when we want to format a vector. Ideally, we can write something like: - // return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", ")); - // It looks like the issue effects clang 14/15 as well. - // However, due to the above issue, it fails to compile. So we have to do the equivalent - // ourselves. We can't recursively call the formatter, but we can recursively call a lambda - // function that does the formatting. - // It gets more complicated, because we need to pass the function into the lambda. We can't - // pass in the lamdba as it is defined, so we create a nested lambda. Which accepts a function - // as a argument. - // Because we are calling std::visit, we can't pass non-variant arguments to the visitor, so we - // have to create a new nested lambda every time we format a vector to ensure that it works. using namespace pmtv; using ret_type = decltype(fmt::format_to(ctx.out(), "")); - auto format_func = [&ctx](const auto format_arg) { - auto function_main = [&ctx](const auto arg, auto function) -> ret_type { + return std::visit([&ctx](const auto arg) -> ret_type { using namespace pmtv; using T = std::decay_t; - if constexpr (Scalar || Complex) - return fmt::format_to(ctx.out(), "{}", arg); - else if constexpr (std::same_as) - return fmt::format_to(ctx.out(), "{}", arg); - else if constexpr (UniformVector || UniformStringVector) - return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", ")); - else if constexpr (std::same_as>) { - fmt::format_to(ctx.out(), "["); - auto new_func = [&function](const auto new_arg) -> ret_type { return function(new_arg, function); }; - for (auto& a: std::span(arg).first(arg.size()-1)) { - std::visit(new_func, a); - fmt::format_to(ctx.out(), ", "); + if constexpr(std::ranges::range && !std::same_as) { + if constexpr(PmtMap) { + return fmt::format_to(ctx.out(), "{{{}}}", fmt::join(arg, ", ")); } - std::visit(new_func, arg[arg.size()-1]); - return fmt::format_to(ctx.out(), "]"); - // When we drop support for gcc11/clang15, get rid of the nested lambda and replace - // the above with this line. - //return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", ")); - } else if constexpr (PmtMap) { - fmt::format_to(ctx.out(), "{{"); - auto new_func = [&function](const auto new_arg) -> ret_type { return function(new_arg, function); }; - size_t i = 0; - for (auto& [k, v]: arg) { - fmt::format_to(ctx.out(), "{}: ", k); - std::visit(new_func, v); - if (i++ < arg.size() - 1) - fmt::format_to(ctx.out(), ", "); + else { + return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", ")); } - return fmt::format_to(ctx.out(), "}}"); - // When we drop support for gcc11/clang15, get rid of the nested lambda and replace - // the above with this line. - //return fmt::format_to(ctx.out(), "{{{}}}", fmt::join(arg, ", ")); - } else if constexpr (std::same_as) + } else if constexpr(std::same_as) { return fmt::format_to(ctx.out(), "null"); - return fmt::format_to(ctx.out(), "unknown type {}", typeid(T).name()); - }; - return function_main(format_arg, function_main); - }; - return std::visit(format_func, value); - + } else { + return fmt::format_to(ctx.out(), "{}", arg); + } + }, value); } };