build: work around compile failure under g++-9

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<user_var>’:
/usr/include/c++/9/variant:1023:10:   required from ‘struct std::__detail::__variant::__gen_vtable<true, void, user_var::operator++(int)::<lambda(auto:22&&)>&&, 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)::<lambda(auto:22&&)>; _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)::<lambda(auto:22&&)>; _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<user_var>’ 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.
This commit is contained in:
Jan Engelhardt 2024-09-18 22:01:09 +02:00
parent 7282af9cd8
commit 85f640d0bb

View File

@ -18,14 +18,17 @@ class user_var : public std::variant<float, int32_t> {
self = static_cast<int32_t>(v);
}
template<typename T> void set_type() noexcept { static_cast<VarT &>(*this) = T{}; }
void operator++(int) noexcept { std::visit([](auto &&uv) { ++uv; }, *this); }
void operator--(int) noexcept { std::visit([](auto &&uv) { ++uv; }, *this); }
template<typename T> void operator+=(T &&r) noexcept { std::visit([&](auto &&uv) { uv += std::forward<T>(r); }, *this); }
template<typename T> void operator-=(T &&r) noexcept { std::visit([&](auto &&uv) { uv -= std::forward<T>(r); }, *this); }
template<typename T> bool operator==(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv == std::forward<T>(r); }, *this); }
template<typename T> bool operator!=(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv != std::forward<T>(r); }, *this); }
template<typename T> bool operator<(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv < std::forward<T>(r); }, *this); }
template<typename T> bool operator>(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv > std::forward<T>(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<VarT &>(*this)); }
void operator--(int) noexcept { std::visit([](auto &&uv) { ++uv; }, static_cast<VarT &>(*this)); }
template<typename T> void operator+=(T &&r) noexcept { std::visit([&](auto &&uv) { uv += std::forward<T>(r); }, static_cast<VarT &>(*this)); }
template<typename T> void operator-=(T &&r) noexcept { std::visit([&](auto &&uv) { uv -= std::forward<T>(r); }, static_cast<VarT &>(*this)); }
template<typename T> bool operator==(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv == std::forward<T>(r); }, static_cast<VarT &>(*this)); }
template<typename T> bool operator!=(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv != std::forward<T>(r); }, static_cast<VarT &>(*this)); }
template<typename T> bool operator<(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv < std::forward<T>(r); }, static_cast<VarT &>(*this)); }
template<typename T> bool operator>(T &&r) noexcept { return std::visit([&](auto &&uv) { return uv > std::forward<T>(r); }, static_cast<VarT &>(*this)); }
};
#define MAX_USER_VARS 25 // make sure this value matches the USERTYPE definition