Fix <version> inclusion and ambiguous constructors/assignments

libeigen/eigen!2945

diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index aaea6bb..1be77aa 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -95,7 +95,7 @@
    *
    * \callgraph
    */
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); }
+  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); }
 
   /** Default constructor.
    *
@@ -113,8 +113,8 @@
 #endif
   /** \brief Move constructor */
   EIGEN_DEVICE_FUNC constexpr Array(Array&&) = default;
-  EIGEN_DEVICE_FUNC Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) {
-    Base::operator=(std::move(other));
+  EIGEN_DEVICE_FUNC constexpr Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) {
+    this->m_storage = std::move(other.m_storage);
     return *this;
   }
 
@@ -244,9 +244,15 @@
 #ifdef EIGEN_ARRAY_PLUGIN
 #include EIGEN_ARRAY_PLUGIN
 #endif
+  template <typename OtherDerived>
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived>& other) {
+    return Base::operator=(other);
+  }
 
-  // NVHPC requires inherited assignment operators to be introduced after the local overloads.
-  using Base::operator=;
+  template <typename OtherDerived>
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const ReturnByValue<OtherDerived>& func) {
+    return Base::operator=(func);
+  }
 
  private:
   template <typename MatrixType, typename OtherDerived, bool SwapPointers>
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 09d0668..ee3f328 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -261,7 +261,7 @@
    */
   EIGEN_DEVICE_FUNC constexpr Matrix& operator=(Matrix&& other) noexcept(
       std::is_nothrow_move_assignable<Scalar>::value) {
-    Base::operator=(std::move(other));
+    this->m_storage = std::move(other.m_storage);
     return *this;
   }
 
diff --git a/Eigen/src/Core/util/ConfigureVectorization.h b/Eigen/src/Core/util/ConfigureVectorization.h
index f3b1fab..3f7612e 100644
--- a/Eigen/src/Core/util/ConfigureVectorization.h
+++ b/Eigen/src/Core/util/ConfigureVectorization.h
@@ -52,15 +52,9 @@
 #endif
 
 // Align to the boundary that avoids false sharing.
-//   https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size
-// There is a bug in android NDK < r26 where the macro is defined but std::hardware_destructive_interference_size
-// still does not exist.
-#if defined(__cpp_lib_hardware_interference_size) && __cpp_lib_hardware_interference_size >= 201603 && \
-    (!EIGEN_OS_ANDROID || __NDK_MAJOR__ + 0 >= 26)
-#include <new>
-#define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(std::hardware_destructive_interference_size)
-#else
-// Overalign for the cache line size of 128 bytes (Apple M1)
+// Pinned to 128 bytes to preserve a stable ABI across architectures and standard libraries
+// and avoid GCC -Winterference-size warnings.
+#ifndef EIGEN_ALIGN_TO_AVOID_FALSE_SHARING
 #define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(128)
 #endif
 
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index da0e157..d4a41c0 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -14,6 +14,11 @@
 // IWYU pragma: private
 #include "../InternalHeaderCheck.h"
 
+// for __cpp_lib feature test macros
+#if defined(__has_include) && __has_include(<version>)
+#include <version>
+#endif
+
 //------------------------------------------------------------------------------------------
 // Eigen version and basic defaults
 //------------------------------------------------------------------------------------------
diff --git a/test/constexpr.cpp b/test/constexpr.cpp
index 8a0a90c..98687aa 100644
--- a/test/constexpr.cpp
+++ b/test/constexpr.cpp
@@ -18,6 +18,20 @@
   Matrix<Scalar, Rows, Rows> A;
 };
 
+template <typename Scalar, int Rows>
+struct ConstexprArrayTest {
+  constexpr ConstexprArrayTest(const Array<Scalar, Rows, Rows>& B) { A = B; }
+
+  Array<Scalar, Rows, Rows> A;
+};
+
+template <typename Scalar, int Rows>
+struct ConstexprArrayMoveTest {
+  constexpr ConstexprArrayMoveTest(Array<Scalar, Rows, Rows> B) { A = std::move(B); }
+
+  Array<Scalar, Rows, Rows> A;
+};
+
 EIGEN_DECLARE_TEST(constexpr) {
   // Clang accepts (some of) this code when using C++14/C++17, but GCC does not like
   // the fact that `T array[Size]` inside Eigen::internal::plain_array is not initialized
@@ -53,6 +67,16 @@
   static_assert(obj2.A(0) == 1);
   static_assert(obj2.A.coeff(0, 1) == 2);
 
+  constexpr ConstexprArrayTest<double, 2> arr_obj1(Array22d({{1, 2}, {3, 4}}));
+  VERIFY_IS_EQUAL(arr_obj1.A.size(), 4);
+  static_assert(arr_obj1.A(0, 0) == 1);
+  static_assert(arr_obj1.A(0) == 1);
+  static_assert(arr_obj1.A.coeff(0, 1) == 2);
+
+  constexpr ConstexprArrayMoveTest<double, 2> arr_move_obj(Array22d({{1, 2}, {3, 4}}));
+  static_assert(arr_move_obj.A(0, 0) == 1);
+  static_assert(arr_move_obj.A.coeff(0, 1) == 2);
+
   // Also check dynamic size arrays/matrices with fixed-size storage (currently
   // only works if all elements are initialized, since otherwise the compiler
   // complains about uninitialized trailing elements.
diff --git a/test/initializer_list_construction.cpp b/test/initializer_list_construction.cpp
index cbc8451..54b9d42 100644
--- a/test/initializer_list_construction.cpp
+++ b/test/initializer_list_construction.cpp
@@ -227,6 +227,23 @@
     }
     VERIFY_IS_EQUAL(m, m2);
   }
+  // Test braced-init-list assignment.
+  {
+    Matrix<Scalar, 4, 1> m;
+    m = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)};
+    VERIFY_IS_EQUAL(m(0), Scalar(11));
+    VERIFY_IS_EQUAL(m(1), Scalar(12));
+    VERIFY_IS_EQUAL(m(2), Scalar(13));
+    VERIFY_IS_EQUAL(m(3), Scalar(14));
+  }
+  {
+    Matrix<Scalar, 1, 4> m;
+    m = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)};
+    VERIFY_IS_EQUAL(m(0), Scalar(11));
+    VERIFY_IS_EQUAL(m(1), Scalar(12));
+    VERIFY_IS_EQUAL(m(2), Scalar(13));
+    VERIFY_IS_EQUAL(m(3), Scalar(14));
+  }
 }
 
 template <typename Scalar>
@@ -291,6 +308,23 @@
     }
     VERIFY_IS_APPROX(m, m2);
   }
+  // Test braced-init-list assignment.
+  {
+    Array<Scalar, 4, 1> a;
+    a = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)};
+    VERIFY_IS_EQUAL(a(0), Scalar(11));
+    VERIFY_IS_EQUAL(a(1), Scalar(12));
+    VERIFY_IS_EQUAL(a(2), Scalar(13));
+    VERIFY_IS_EQUAL(a(3), Scalar(14));
+  }
+  {
+    Array<Scalar, 1, 4> a;
+    a = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)};
+    VERIFY_IS_EQUAL(a(0), Scalar(11));
+    VERIFY_IS_EQUAL(a(1), Scalar(12));
+    VERIFY_IS_EQUAL(a(2), Scalar(13));
+    VERIFY_IS_EQUAL(a(3), Scalar(14));
+  }
 }
 
 template <typename Scalar>
diff --git a/test/preprocessor_directives.cpp b/test/preprocessor_directives.cpp
index d361457..3204187 100644
--- a/test/preprocessor_directives.cpp
+++ b/test/preprocessor_directives.cpp
@@ -21,6 +21,8 @@
 #define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
 #elif defined(EIGEN_TEST_PART_3)
 #define EIGEN_64BIT_BLAS
+#elif defined(EIGEN_TEST_PART_4)
+#define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(256)
 #endif
 
 #include "main.h"
@@ -45,6 +47,19 @@
                   EIGEN_DEFAULT_ALIGN_BYTES,
               "local_nested_eval_wrapper no longer follows EIGEN_DEFAULT_ALIGN_BYTES");
 
+// EIGEN_ALIGN_TO_AVOID_FALSE_SHARING must honor pre-existing definitions and stay pinned to 128 by default.
+struct AvoidFalseSharingAligned {
+  EIGEN_ALIGN_TO_AVOID_FALSE_SHARING char c;
+};
+
+#if defined(EIGEN_TEST_PART_4)
+static_assert(alignof(AvoidFalseSharingAligned) == 256,
+              "Pre-existing EIGEN_ALIGN_TO_AVOID_FALSE_SHARING definition was not preserved");
+#else
+static_assert(alignof(AvoidFalseSharingAligned) == 128,
+              "EIGEN_ALIGN_TO_AVOID_FALSE_SHARING should be pinned to 128 bytes by default");
+#endif
+
 // Per-part checks that the override actually took effect.
 #if defined(EIGEN_TEST_PART_2)
 static_assert(std::is_same<Eigen::Index, int>::value, "EIGEN_DEFAULT_DENSE_INDEX_TYPE was ignored");
@@ -67,8 +82,18 @@
 #endif
 }
 
+void check_false_sharing_alignment() {
+#if defined(EIGEN_TEST_PART_4)
+  VERIFY_IS_EQUAL(std::size_t(alignof(AvoidFalseSharingAligned)), std::size_t(256));
+#else
+  VERIFY_IS_EQUAL(std::size_t(alignof(AvoidFalseSharingAligned)), std::size_t(128));
+#endif
+}
+
 EIGEN_DECLARE_TEST(preprocessor_directives) {
   CALL_SUBTEST_1(check_index_type());
+  CALL_SUBTEST_1(check_false_sharing_alignment());
   CALL_SUBTEST_2(check_index_type());
   CALL_SUBTEST_3(check_blas_index());
+  CALL_SUBTEST_4(check_false_sharing_alignment());
 }