--- /dev/null
+/*
+ * 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
#include <utility>
#include <vector>
+#include "gromacs/compat/utility.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/exceptions.h"
}
/*! \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
*
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();
{
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());
// 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.
* 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;
// 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)
{
}
*
* 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())
{
}
* 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;
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;
}
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>;
* 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);
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
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()));
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_
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)));
}
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)));
}
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(). */
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);
}
/*! \} */