From 85f640d0bbdccfb09eb6c37d7b5096962c2543ef Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 18 Sep 2024 22:01:09 +0200 Subject: [PATCH] build: work around compile failure under g++-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under gcc-9 (e.g. used by Ubuntu 20.04), compilation fails with: ``` /usr/include/c++/9/variant: In instantiation of ‘constexpr const size_t std::variant_size_v’: /usr/include/c++/9/variant:1023:10: required from ‘struct std::__detail::__variant::__gen_vtable&&, user_var&>’ /usr/include/c++/9/variant:1656:23: required from ‘constexpr decltype(auto) std::__do_visit(_Visitor&&, _Variants&& ...) [with bool __use_index = false; bool __same_return_types = true; _Visitor = user_var::operator++(int)::; _Variants = {user_var&}]’ /usr/include/c++/9/variant:1672:29: required from ‘constexpr std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = user_var::operator++(int)::; _Variants = {user_var&}; std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> = void]’ scripts/DallasFuncs.h:21:75: required from here /usr/include/c++/9/variant:94:29: error: incomplete type ‘std::variant_size’ used in nested name specifier 94 | inline constexpr size_t variant_size_v = variant_size<_Variant>::value; ``` Judging from the date of P2162, calling std::visit with std::variant derivatives is only specified for C++20 and onwards. But Descent3 only asks for C++17. Since ``class user_var`` does not have any members that need would need to be accessed via std::visit, we can "add a hint" and explicitly specify the base type. --- scripts/DallasFuncs.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/DallasFuncs.h b/scripts/DallasFuncs.h index ab5e504c..50bfbe69 100644 --- a/scripts/DallasFuncs.h +++ b/scripts/DallasFuncs.h @@ -18,14 +18,17 @@ class user_var : public std::variant { self = static_cast(v); } template void set_type() noexcept { static_cast(*this) = T{}; } - void operator++(int) noexcept { std::visit([](auto &&uv) { ++uv; }, *this); } - void operator--(int) noexcept { std::visit([](auto &&uv) { ++uv; }, *this); } - template void operator+=(T &&r) noexcept { std::visit([&](auto &&uv) { uv += std::forward(r); }, *this); } - template void operator-=(T &&r) noexcept { std::visit([&](auto &&uv) { uv -= std::forward(r); }, *this); } - template bool operator==(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv == std::forward(r); }, *this); } - template bool operator!=(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv != std::forward(r); }, *this); } - template bool operator<(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv < std::forward(r); }, *this); } - template bool operator>(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv > std::forward(r); }, *this); } + + // The explicit cast to base type is for the sake of older compilers + // like GCC 9 which is missing a deduction guide or so (cf. P2162R2). + void operator++(int) noexcept { std::visit([](auto &&uv) { ++uv; }, static_cast(*this)); } + void operator--(int) noexcept { std::visit([](auto &&uv) { ++uv; }, static_cast(*this)); } + template void operator+=(T &&r) noexcept { std::visit([&](auto &&uv) { uv += std::forward(r); }, static_cast(*this)); } + template void operator-=(T &&r) noexcept { std::visit([&](auto &&uv) { uv -= std::forward(r); }, static_cast(*this)); } + template bool operator==(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv == std::forward(r); }, static_cast(*this)); } + template bool operator!=(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv != std::forward(r); }, static_cast(*this)); } + template bool operator<(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv < std::forward(r); }, static_cast(*this)); } + template bool operator>(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv > std::forward(r); }, static_cast(*this)); } }; #define MAX_USER_VARS 25 // make sure this value matches the USERTYPE definition