mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Remove pre-C++14 workarounds from unsupported/ tensor code
libeigen/eigen!2218 Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
@@ -231,37 +231,20 @@ template <typename T, std::size_t N>
|
|||||||
using array = std::array<T, N>;
|
using array = std::array<T, N>;
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
/* std::get is only constexpr in C++14, not yet in C++11
|
|
||||||
* - libstdc++ from version 4.7 onwards has it nevertheless,
|
|
||||||
* so use that
|
|
||||||
* - libstdc++ older versions: use _M_instance directly
|
|
||||||
* - libc++ all versions so far: use __elems_ directly
|
|
||||||
* - all other libs: use std::get to be portable, but
|
|
||||||
* this may not be constexpr
|
|
||||||
*/
|
|
||||||
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
|
|
||||||
#define STD_GET_ARR_HACK a._M_instance[I_]
|
|
||||||
#elif defined(_LIBCPP_VERSION)
|
|
||||||
#define STD_GET_ARR_HACK a.__elems_[I_]
|
|
||||||
#else
|
|
||||||
#define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <std::size_t I_, class T, std::size_t N>
|
template <std::size_t I_, class T, std::size_t N>
|
||||||
constexpr T& array_get(std::array<T, N>& a) {
|
constexpr T& array_get(std::array<T, N>& a) {
|
||||||
return (T&)STD_GET_ARR_HACK;
|
return std::get<I_>(a);
|
||||||
}
|
}
|
||||||
template <std::size_t I_, class T, std::size_t N>
|
template <std::size_t I_, class T, std::size_t N>
|
||||||
constexpr T&& array_get(std::array<T, N>&& a) {
|
constexpr T&& array_get(std::array<T, N>&& a) {
|
||||||
return (T&&)STD_GET_ARR_HACK;
|
return std::get<I_>(std::move(a));
|
||||||
}
|
}
|
||||||
template <std::size_t I_, class T, std::size_t N>
|
template <std::size_t I_, class T, std::size_t N>
|
||||||
constexpr T const& array_get(std::array<T, N> const& a) {
|
constexpr T const& array_get(std::array<T, N> const& a) {
|
||||||
return (T const&)STD_GET_ARR_HACK;
|
return std::get<I_>(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef STD_GET_ARR_HACK
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
|||||||
@@ -150,8 +150,8 @@ struct tensor_static_symgroup_do_apply<internal::type_list<first, next...>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <EIGEN_TPL_PP_SPEC_HACK_DEF(typename, empty)>
|
template <>
|
||||||
struct tensor_static_symgroup_do_apply<internal::type_list<EIGEN_TPL_PP_SPEC_HACK_USE(empty)>> {
|
struct tensor_static_symgroup_do_apply<internal::type_list<>> {
|
||||||
template <typename Op, typename RV, std::size_t SGNumIndices, typename Index, std::size_t NumIndices,
|
template <typename Op, typename RV, std::size_t SGNumIndices, typename Index, std::size_t NumIndices,
|
||||||
typename... Args>
|
typename... Args>
|
||||||
static inline RV run(const std::array<Index, NumIndices>&, RV initial, Args&&...) {
|
static inline RV run(const std::array<Index, NumIndices>&, RV initial, Args&&...) {
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ struct strip_identities<Equality, id, type_list<t, ts...>> {
|
|||||||
Equality<id, t>::global_flags | strip_identities<Equality, id, type_list<ts...>>::global_flags;
|
Equality<id, t>::global_flags | strip_identities<Equality, id, type_list<ts...>>::global_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <template <typename, typename> class Equality, typename id EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, ts)>
|
template <template <typename, typename> class Equality, typename id>
|
||||||
struct strip_identities<Equality, id, type_list<EIGEN_TPL_PP_SPEC_HACK_USE(ts)>> {
|
struct strip_identities<Equality, id, type_list<>> {
|
||||||
typedef type_list<> type;
|
typedef type_list<> type;
|
||||||
constexpr static int global_flags = 0;
|
constexpr static int global_flags = 0;
|
||||||
};
|
};
|
||||||
@@ -278,10 +278,9 @@ struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, ele
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
|
template <template <typename, typename> class Multiply, template <typename, typename> class Equality, typename id,
|
||||||
typename sub_group_elements, typename elements EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, empty),
|
typename sub_group_elements, typename elements, typename rep_element, int sub_group_size>
|
||||||
typename rep_element, int sub_group_size>
|
struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements, type_list<>, rep_element,
|
||||||
struct dimino_add_cosets_for_rep<Multiply, Equality, id, sub_group_elements, elements,
|
sub_group_size> {
|
||||||
type_list<EIGEN_TPL_PP_SPEC_HACK_USE(empty)>, rep_element, sub_group_size> {
|
|
||||||
typedef elements type;
|
typedef elements type;
|
||||||
constexpr static int global_flags = 0;
|
constexpr static int global_flags = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,29 +10,11 @@
|
|||||||
#ifndef EIGEN_CXX11WORKAROUNDS_H
|
#ifndef EIGEN_CXX11WORKAROUNDS_H
|
||||||
#define EIGEN_CXX11WORKAROUNDS_H
|
#define EIGEN_CXX11WORKAROUNDS_H
|
||||||
|
|
||||||
/* COMPATIBILITY CHECKS
|
|
||||||
* (so users of compilers that are too old get some realistic error messages)
|
|
||||||
*/
|
|
||||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER < 1310)
|
|
||||||
#error Intel Compiler only supports required C++ features since version 13.1.
|
|
||||||
// note that most stuff in principle works with 13.0 but when combining
|
|
||||||
// some features, at some point 13.0 will just fail with an internal assertion
|
|
||||||
#elif defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && \
|
|
||||||
(__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6))
|
|
||||||
// G++ < 4.6 by default will continue processing the source files - even if we use #error to make
|
|
||||||
// it error out. For this reason, we use the pragma to make sure G++ aborts at the first error
|
|
||||||
// it sees. Unfortunately, that is still not our #error directive, but at least the output is
|
|
||||||
// short enough the user has a chance to see that the compiler version is not sufficient for
|
|
||||||
// the funky template mojo we use.
|
|
||||||
#pragma GCC diagnostic error "-Wfatal-errors"
|
|
||||||
#error GNU C++ Compiler (g++) only supports required C++ features since version 4.6.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
/* std::get is only constexpr in C++14, not yet in C++11
|
/* array_get overloads for std::vector, used by tensor code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <std::size_t I_, class T>
|
template <std::size_t I_, class T>
|
||||||
@@ -48,32 +30,6 @@ constexpr T const& array_get(std::vector<T> const& a) {
|
|||||||
return a[I_];
|
return a[I_];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Suppose you have a template of the form
|
|
||||||
* template<typename T> struct X;
|
|
||||||
* And you want to specialize it in such a way:
|
|
||||||
* template<typename S1, typename... SN> struct X<Foo<S1, SN...>> { ::: };
|
|
||||||
* template<> struct X<Foo<>> { ::: };
|
|
||||||
* This will work in Intel's compiler 13.0, but only to some extent in g++ 4.6, since
|
|
||||||
* g++ can only match templates called with parameter packs if the number of template
|
|
||||||
* arguments is not a fixed size (so inside the first specialization, referencing
|
|
||||||
* X<Foo<Sn...>> will fail in g++). On the other hand, g++ will accept the following:
|
|
||||||
* template<typename S...> struct X<Foo<S...>> { ::: }:
|
|
||||||
* as an additional (!) specialization, which will then only match the empty case.
|
|
||||||
* But Intel's compiler 13.0 won't accept that, it will only accept the empty syntax,
|
|
||||||
* so we have to create a workaround for this.
|
|
||||||
*/
|
|
||||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_DEF(mt, n) mt... n
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_DEFC(mt, n) , EIGEN_TPL_PP_SPEC_HACK_DEF(mt, n)
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_USE(n) n...
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_USEC(n) , n...
|
|
||||||
#else
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_DEF(mt, n)
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_DEFC(mt, n)
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_USE(n)
|
|
||||||
#define EIGEN_TPL_PP_SPEC_HACK_USEC(n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ ei_add_test(cxx11_tensor_thread_local "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
|||||||
ei_add_test(cxx11_tensor_thread_pool "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
ei_add_test(cxx11_tensor_thread_pool "-pthread" "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
ei_add_test(cxx11_tensor_trace)
|
ei_add_test(cxx11_tensor_trace)
|
||||||
ei_add_test(cxx11_tensor_volume_patch)
|
ei_add_test(cxx11_tensor_volume_patch)
|
||||||
# ei_add_test(cxx11_tensor_symmetry)
|
ei_add_test(cxx11_tensor_symmetry)
|
||||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
# This test requires __uint128_t which is only available on 64bit systems
|
# This test requires __uint128_t which is only available on 64bit systems
|
||||||
ei_add_test(cxx11_tensor_uint128)
|
ei_add_test(cxx11_tensor_uint128)
|
||||||
|
|||||||
Reference in New Issue
Block a user