Revert c++-17 features that are not supported by CUDA build
authorArtem Zhmurov <zhmurov@gmail.com>
Wed, 29 Jul 2020 03:46:11 +0000 (03:46 +0000)
committerRoland Schulz <roland.schulz@intel.com>
Wed, 29 Jul 2020 03:46:11 +0000 (03:46 +0000)
C++-17 is fully supported only starting from CUDA 11, which is not
required currently. This rolls back some of the changes made in
2f876de263efdf08daf160e7791434cd760ccd9b and
106b2d8ded04dbc51031022e9b11d147dccb76a3 that broke the CUDA build.
The change should be reverted once c++17 is fully supported.

Fixes #3608
Refs #3609

13 files changed:
src/gromacs/compat/utility.h [new file with mode: 0644]
src/gromacs/domdec/hashedmap.h
src/gromacs/math/arrayrefwithpadding.h
src/gromacs/math/paddedvector.h
src/gromacs/math/vectypes.h
src/gromacs/utility/allocator.h
src/gromacs/utility/arrayref.h
src/gromacs/utility/defaultinitializationallocator.h
src/gromacs/utility/enumerationhelpers.h
src/gromacs/utility/exceptions.h
src/gromacs/utility/listoflists.h
src/gromacs/utility/range.h
src/gromacs/utility/smalloc.h

diff --git a/src/gromacs/compat/utility.h b/src/gromacs/compat/utility.h
new file mode 100644 (file)
index 0000000..705b6a7
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \libinternal \file
+ * \brief Provides backported functions/classes from utility
+ *
+ * \todo Remove when CUDA 11 is a requirement.
+ *
+ * \author Roland Schulz <roland.schulz@intel.com>
+ * \ingroup module_compat
+ * \inlibraryapi
+ */
+#ifndef GMX_COMPAT_UTILITY_H
+#define GMX_COMPAT_UTILITY_H
+namespace gmx
+{
+namespace compat
+{
+//! Forms lvalue reference to const type of t
+template<class T>
+constexpr const T& as_const(T& t) noexcept
+{
+    return t;
+}
+} // namespace compat
+} // namespace gmx
+#endif
index 4ef845b6013053fe3c2db2074df706f0a9243045..00f37fc81a5d674e023a49d499476a602f70f7aa 100644 (file)
@@ -53,6 +53,7 @@
 #include <utility>
 #include <vector>
 
+#include "gromacs/compat/utility.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/exceptions.h"
 
@@ -256,11 +257,13 @@ public:
     }
 
     /*! \brief Returns a pointer to the value for the given key or nullptr when not present
+     *
+     * \todo Use std::as_const when CUDA 11 is a requirement.
      *
      * \param[in] key  The key
      * \return a pointer to value for the given key or nullptr when not present
      */
-    T* find(int key) { return const_cast<T*>(std::as_const(*this).find(key)); }
+    T* find(int key) { return const_cast<T*>(gmx::compat::as_const(*this).find(key)); }
 
     /*! \brief Returns a pointer to the value for the given key or nullptr when not present
      *
index 7a8a2b632f45b3cf84849ff61b65b95aaaed53bd..b6489475c30a5a131978750827b4732b29a0a199 100644 (file)
@@ -120,8 +120,11 @@ public:
         paddedEnd_(std::move(o.paddedEnd_))
     {
     }
-    //! Convenience overload constructor to make an ArrayRefWithPadding<const T> from a non-const one.
-    template<typename U, typename = std::enable_if_t<std::is_same_v<value_type, const typename std::remove_reference_t<U>::value_type>>>
+    /*! \brief Convenience overload constructor to make an ArrayRefWithPadding<const T> from a non-const one.
+     *
+     * \todo Use std::is_same_v when CUDA 11 is a requirement.
+     */
+    template<typename U, typename = std::enable_if_t<std::is_same<value_type, const typename std::remove_reference_t<U>::value_type>::value>>
     ArrayRefWithPadding(U&& o)
     {
         auto constArrayRefWithPadding = o.constArrayRefWithPadding();
index 6a1d2e12b210a856a3b4e99714399a2cb8222203..6c199bc03e5c71d2126750836c8c800fdbd2c3a2 100644 (file)
@@ -372,14 +372,20 @@ public:
     {
         return ArrayRefWithPadding<const T>(data(), data() + size(), data() + paddedSize());
     }
-    //! Returns an rvec * pointer for containers of RVec, for use with legacy code.
-    template<typename AlsoT = T, typename = typename std::enable_if<std::is_same_v<AlsoT, RVec>>>
+    /*! \brief Returns an rvec * pointer for containers of RVec, for use with legacy code.
+     *
+     * \todo Use std::is_same_v when CUDA 11 is a requirement.
+     */
+    template<typename AlsoT = T, typename = typename std::enable_if<std::is_same<AlsoT, RVec>::value>>
     rvec* rvec_array()
     {
         return as_rvec_array(data());
     }
-    //! Returns a const rvec * pointer for containers of RVec, for use with legacy code.
-    template<typename AlsoT = T, typename = typename std::enable_if<std::is_same_v<AlsoT, RVec>>>
+    /*! \brief Returns a const rvec * pointer for containers of RVec, for use with legacy code.
+     *
+     * \todo Use std::is_same_v when CUDA 11 is a requirement.
+     */
+    template<typename AlsoT = T, typename = typename std::enable_if<std::is_same<AlsoT, RVec>::value>>
     const rvec* rvec_array() const
     {
         return as_rvec_array(data());
index a4f3fe25a00f5e17b91524693158358ed64dda9d..7db36cee58bae9956af6a359173d1ca03188bcc5 100644 (file)
@@ -94,7 +94,9 @@ public:
     // of pointers, the implementation will be different enough that the whole
     // template class should have a separate partial specialization. We try to avoid
     // accidental matching to pointers, but this assertion is a no-cost extra check.
-    static_assert(!std::is_pointer_v<std::remove_cv_t<ValueType>>,
+    //
+    // TODO: Use std::is_pointer_v when CUDA 11 is a requirement.
+    static_assert(!std::is_pointer<std::remove_cv_t<ValueType>>::value,
                   "BasicVector value type must not be a pointer.");
 
     //! Constructs default (uninitialized) vector.
index 2bda1d6dab7b8aa7f84094711a499c30c782c10a..74ec200324e9c0f60497eb77136e4f4ee5e4d9ba 100644 (file)
@@ -152,8 +152,10 @@ public:
      * This is a member function of the left-hand-side allocator.
      * Always true for stateless polcies. Has to be defined in the policy for stateful policies.
      * FUTURE: Can be removed with C++17 (is_always_equal)
+     *
+     * \todo Use std::is_empty_v when CUDA 11 is a requirement.
      */
-    template<class T2, class A = AllocationPolicy, typename = std::enable_if_t<std::is_empty_v<A>>>
+    template<class T2, class A = AllocationPolicy, typename = std::enable_if_t<std::is_empty<A>::value>>
     bool operator==(const Allocator<T2, AllocationPolicy>& /*unused*/) const
     {
         return true;
index d70527b230c8a9ce7368d075d8efd02137450f92..419450c5c3f1ca5460ebde17b3b2f82b0a2cb94c 100644 (file)
@@ -73,7 +73,8 @@ struct ArrayRefIter :
     // This default constructor does not initialize it_
     constexpr ArrayRefIter() noexcept {}
     constexpr explicit ArrayRefIter(T* it) noexcept : it_(it) {}
-    template<class T2 = T, class = std::enable_if_t<std::is_const_v<T2>>>
+    // TODO: Use std::is_const_v when CUDA 11 is a requirement.
+    template<class T2 = T, class = std::enable_if_t<std::is_const<T2>::value>>
     constexpr ArrayRefIter(ArrayRefIter<std::remove_const_t<T2>> it) noexcept : it_(&*it)
     {
     }
@@ -175,8 +176,10 @@ public:
      *
      * This constructor is not explicit to allow directly passing
      * a container to a method that takes ArrayRef.
+     *
+     * \todo Use std::is_convertible_v when CUDA 11 is a requirement.
      */
-    template<typename U, typename = std::enable_if_t<std::is_convertible_v<typename std::remove_reference_t<U>::pointer, pointer>>>
+    template<typename U, typename = std::enable_if_t<std::is_convertible<typename std::remove_reference_t<U>::pointer, pointer>::value>>
     ArrayRef(U&& o) : begin_(o.data()), end_(o.data() + o.size())
     {
     }
@@ -311,9 +314,11 @@ ArrayRef<const T> constArrayRefFromArray(const T* begin, size_t size)
  * Create ArrayRef from container with type deduction
  *
  * \see ArrayRef
+ *
+ * \todo Use std::is_const_v when CUDA 11 is a requirement.
  */
 template<typename T>
-ArrayRef<std::conditional_t<std::is_const_v<T>, const typename T::value_type, typename T::value_type>>
+ArrayRef<std::conditional_t<std::is_const<T>::value, const typename T::value_type, typename T::value_type>>
 makeArrayRef(T& c)
 {
     return c;
index 54321b3bbb04c96782b6eedf5f25b9e4ef21e337..205b1231cbba220f17fdc3af274f8098b9148c61 100644 (file)
@@ -68,9 +68,12 @@ public:
 
     using A::A;
 
-    /*! \brief Constructs an object and default initializes */
+    /*! \brief Constructs an object and default initializes
+     *
+     * \todo Use std::is_nothrow_default_constructible_v when CUDA 11 is a requirement.
+     */
     template<typename U>
-    void construct(U* ptr) noexcept(std::is_nothrow_default_constructible_v<U>)
+    void construct(U* ptr) noexcept(std::is_nothrow_default_constructible<U>::value)
     {
         ::new (static_cast<void*>(ptr)) U;
     }
index 33cc0d2a09a5af98f739893a10cfcd49a500564f..c74866f9a8ad78f0fc35d8d7177594d8c31a7e54 100644 (file)
@@ -117,7 +117,8 @@ class EnumerationIterator final :
     public boost::stl_interfaces::iterator_interface<EnumerationIterator<EnumType, Last, Step>, std::random_access_iterator_tag, EnumType>
 {
 public:
-    static_assert(std::is_enum_v<EnumType>, "Enumeration iterator must be over an enum type.");
+    // TODO: Use std::is_enum_v when CUDA 11 is a requirement.
+    static_assert(std::is_enum<EnumType>::value, "Enumeration iterator must be over an enum type.");
     //! Convenience alias
     using IntegerType = std::underlying_type_t<EnumType>;
 
index 50413977c0484c371e6ab04885885df0cf048ed1..8d7b62d6017b6454582c24721e8ba69ff74f4535 100644 (file)
@@ -377,9 +377,11 @@ private:
  * other overloads of `operator<<` for ExceptionInfo objects, in case someone
  * would like to declare those.  But currently we do not have such overloads, so
  * if the enable_if causes problems with some compilers, it can be removed.
+ *
+ * \todo Use std::is_base_of_v when CUDA 11 is a requirement.
  */
 template<class Exception, class Tag, class T>
-inline std::enable_if_t<std::is_base_of_v<GromacsException, Exception>, Exception>
+inline std::enable_if_t<std::is_base_of<GromacsException, Exception>::value, Exception>
 operator<<(Exception ex, const ExceptionInfo<Tag, T>& item)
 {
     ex.setInfo(item);
index e9baa98b4ddbe1b6804f2ca1d25dd407a4084d14..8d707a0957b3d8d87bd6d0e05b621b09afa89de8 100644 (file)
@@ -77,7 +77,8 @@ namespace gmx
 template<typename T>
 class ListOfLists
 {
-    static_assert(std::is_arithmetic_v<T>, "This class is limited to arithmetic types");
+    // TODO: Use std::is_arithmetic_v when CUDA 11 is a requirement.
+    static_assert(std::is_arithmetic<T>::value, "This class is limited to arithmetic types");
 
 public:
     //! Constructs an empty list of lists
@@ -133,7 +134,8 @@ public:
     void pushBackListOfSize(int numElements)
     {
         // With arithmetic types enforced, this assertion is always true
-        static_assert(std::is_default_constructible_v<T>,
+        // TODO: Use std::is_default_constructible_v when CUDA 11 is a requirement.
+        static_assert(std::is_default_constructible<T>::value,
                       "pushBackListOfSize should only be called with default constructable types");
         elements_.resize(elements_.size() + numElements);
         listRanges_.push_back(int(elements_.size()));
index 5871eb4e746acd61b9839ecbbabf0728cbc5e8b4..01d13705c41f11852b393244ce235eb0b116df73 100644 (file)
@@ -63,7 +63,8 @@ namespace gmx
 template<typename T>
 class Range
 {
-    static_assert(std::is_integral_v<T>, "Range can only be used with integral types");
+    // TODO: Use std::is_integral_v when CUDA 11 is a requirement.
+    static_assert(std::is_integral<T>::value, "Range can only be used with integral types");
 
     // Note: This class has as invariant: begin_ <= end_
 
index cb9fb4a73931e06f1f8fd47e28424ff6980d6003..f68de025d347e350bb597075b73eb22b980dd644 100644 (file)
@@ -202,7 +202,8 @@ void save_free_aligned(const char* name, const char* file, int line, void* ptr);
 template<typename T>
 static inline void gmx_snew_impl(const char* name, const char* file, int line, T*& ptr, size_t nelem)
 {
-    static_assert(std::is_pod_v<T>, "snew() called on C++ type");
+    // TODO: Use std::is_pod_v when CUDA 11 is a requirement.
+    static_assert(std::is_pod<T>::value, "snew() called on C++ type");
     // NOLINTNEXTLINE bugprone-sizeof-expression
     ptr = static_cast<T*>(save_calloc(name, file, line, nelem, sizeof(T)));
 }
@@ -210,7 +211,8 @@ static inline void gmx_snew_impl(const char* name, const char* file, int line, T
 template<typename T>
 static inline void gmx_srenew_impl(const char* name, const char* file, int line, T*& ptr, size_t nelem)
 {
-    static_assert(std::is_pod_v<T>, "srenew() called on C++ type");
+    // TODO: Use std::is_pod_v when CUDA 11 is a requirement.
+    static_assert(std::is_pod<T>::value, "srenew() called on C++ type");
     // NOLINTNEXTLINE bugprone-sizeof-expression
     ptr = static_cast<T*>(save_realloc(name, file, line, ptr, nelem, sizeof(T)));
 }
@@ -218,7 +220,8 @@ static inline void gmx_srenew_impl(const char* name, const char* file, int line,
 template<typename T>
 static inline void gmx_smalloc_impl(const char* name, const char* file, int line, T*& ptr, size_t size)
 {
-    static_assert(std::is_pod_v<T>, "smalloc() called on C++ type");
+    // TODO: Use std::is_pod_v when CUDA 11 is a requirement.
+    static_assert(std::is_pod<T>::value, "smalloc() called on C++ type");
     ptr = static_cast<T*>(save_malloc(name, file, line, size));
 }
 /** C++ helper for snew_aligned(). */
@@ -226,21 +229,25 @@ template<typename T>
 static inline void
 gmx_snew_aligned_impl(const char* name, const char* file, int line, T*& ptr, size_t nelem, size_t alignment)
 {
-    static_assert(std::is_pod_v<T>, "snew_aligned() called on C++ type");
+    // TODO: Use std::is_pod_v when CUDA 11 is a requirement.
+    static_assert(std::is_pod<T>::value, "snew_aligned() called on C++ type");
     ptr = static_cast<T*>(save_calloc_aligned(name, file, line, nelem, sizeof(T), alignment));
 }
 /** C++ helper for sfree(). */
 template<typename T>
 static inline void gmx_sfree_impl(const char* name, const char* file, int line, T* ptr)
 {
-    static_assert(std::is_pod_v<T> || std::is_void_v<T>, "sfree() called on C++ type");
+    // TODO: Use std::is_pod_v and std::is_void_v when CUDA 11 is a requirement.
+    static_assert(std::is_pod<T>::value || std::is_void<T>::value, "sfree() called on C++ type");
     save_free(name, file, line, ptr);
 }
 /** C++ helper for sfree_aligned(). */
 template<typename T>
 static inline void gmx_sfree_aligned_impl(const char* name, const char* file, int line, T* ptr)
 {
-    static_assert(std::is_pod_v<T> || std::is_void_v<T>, "sfree_aligned() called on C++ type");
+    // TODO: Use std::is_pod_v and std::is_void_v when CUDA 11 is a requirement.
+    static_assert(std::is_pod<T>::value || std::is_void<T>::value,
+                  "sfree_aligned() called on C++ type");
     save_free_aligned(name, file, line, ptr);
 }
 /*! \} */