Commit 07fb8cc8 authored by Michael Tesch's avatar Michael Tesch
Browse files

Fix MSVC 19.44 (VS 2022) build of multidual

parent 745d9d20
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#
cmake_minimum_required (VERSION 3.14)
project (cppduals
  VERSION 0.8.4
  VERSION 0.8.5
  LANGUAGES C CXX
  )
include (GNUInstallDirs)
+5 −0
Original line number Diff line number Diff line
@@ -339,6 +339,11 @@ also licensed under MPL-2.0.
ChangeLog
=========

v0.8.5
------

- fix MSVC 19.44 (VS 2022) build of `duals/multidual`: replace fold expression in `partials<T,N>` SFINAE with `std::conjunction_v`, and use explicit construction in the `_ef`/`_e`/`_el` user-defined literals.

v0.8.4
------

+12 −7
Original line number Diff line number Diff line
@@ -84,9 +84,11 @@ struct partials {
  constexpr partials(T v) : data{v} {}

  /// N>1: construct from exactly N values.
  // Use std::conjunction_v instead of a fold expression so MSVC's older
  // SFINAE parser (notably MSVC 19.44 in VS 2022) accepts this template.
  template<class... Args,
           std::enable_if_t<(sizeof...(Args) == N) && (N > 1) &&
                            (std::is_convertible<Args, T>::value && ...), int> = 0>
                            std::conjunction_v<std::is_convertible<Args, T>...>, int> = 0>
  constexpr partials(Args... args) : data{T(args)...} {}

  constexpr T  operator[](int i) const { return data[i]; }
@@ -731,18 +733,21 @@ template <typename T> int sgn(T val) {
inline namespace literals
{
using duals::dual;
// Construct dual<T> explicitly (rather than via brace-init in the return
// statement) so MSVC performs the float->partials<T,1> implicit conversion
// reliably — MSVC 19.44 (VS 2022) rejects the brace-init form with C2440.
constexpr dual<float> operator""_ef(long double du)
{ return { 0.0f, static_cast<float>(du) }; }
{ return dual<float>(0.0f, partials<float,1>(static_cast<float>(du))); }
constexpr dual<float> operator""_ef(unsigned long long du)
{ return { 0.0f, static_cast<float>(du) }; }
{ return dual<float>(0.0f, partials<float,1>(static_cast<float>(du))); }
constexpr dual<double> operator""_e(long double du)
{ return { 0.0, static_cast<double>(du) }; }
{ return dual<double>(0.0, partials<double,1>(static_cast<double>(du))); }
constexpr dual<double> operator""_e(unsigned long long du)
{ return { 0.0, static_cast<double>(du) }; }
{ return dual<double>(0.0, partials<double,1>(static_cast<double>(du))); }
constexpr dual<long double> operator""_el(long double du)
{ return { 0.0l, du }; }
{ return dual<long double>(0.0l, partials<long double,1>(du)); }
constexpr dual<long double> operator""_el(unsigned long long du)
{ return { 0.0l, static_cast<long double>(du) }; }
{ return dual<long double>(0.0l, partials<long double,1>(static_cast<long double>(du))); }
} // namespace literals

// shortcut type names