3737
3838#include < umpire_cxx_allocator.hpp>
3939
40- #include < concepts>
41-
4240namespace TiledArray {
4341
4442namespace detail {
@@ -99,7 +97,7 @@ template <typename T, typename Allocator>
9997class Tensor {
10098 // meaningful error if T& is not assignable, see
10199 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48101
102- static_assert (std::is_assignable_v <std::add_lvalue_reference_t <T>, T>,
100+ static_assert (std::is_assignable <std::add_lvalue_reference_t <T>, T>::value ,
103101 " Tensor<T,Allocator>: T must be an assignable type (e.g. "
104102 " cannot be const)" );
105103 // default-constructible Allocator allows to reduce the size of default Tensor
@@ -185,7 +183,7 @@ class Tensor {
185183
186184 Tensor (const range_type& range, size_t nbatch, bool default_construct)
187185 : range_(range), nbatch_(nbatch) {
188- const size_t size = range_.volume () * nbatch;
186+ size_t size = range_.volume () * nbatch;
189187 allocator_type allocator;
190188 auto * ptr = allocator.allocate (size);
191189 // default construct elements of data only if can have any effect ...
@@ -312,7 +310,7 @@ class Tensor {
312310 // / on return \p other is in empty (null) but not
313311 // / necessarily default state
314312 // / \post `other.empty()`
315- Tensor (Tensor&& other) noexcept
313+ Tensor (Tensor&& other)
316314 : range_(std::move(other.range_)),
317315 nbatch_ (std::move(other.nbatch_)),
318316 data_(std::move(other.data_)) {
@@ -338,10 +336,12 @@ class Tensor {
338336 }
339337
340338 struct nbatches {
341- template <std::integral Int>
339+ template <typename Int,
340+ typename = std::enable_if_t <std::is_integral_v<Int>>>
342341 nbatches (Int n) : n(n) {}
343- template <std::integral Int>
344- void operator =(Int n) {
342+ template <typename Int,
343+ typename = std::enable_if_t <std::is_integral_v<Int>>>
344+ nbatches& operator =(Int n) {
345345 this ->n = n;
346346 }
347347
@@ -361,9 +361,10 @@ class Tensor {
361361
362362 // / \param range An array with the size of each dimension
363363 // / \param value The value of the tensor elements
364- template <typename Value,
365- std::enable_if_t <std::is_same_v<Value, value_type> &&
366- detail::is_tensor<Value>::value>* = nullptr >
364+ template <
365+ typename Value,
366+ typename std::enable_if<std::is_same<Value, value_type>::value &&
367+ detail::is_tensor<Value>::value>::type* = nullptr >
367368 Tensor (const range_type& range, const Value& value)
368369 : Tensor(range, 1 , default_construct{false }) {
369370 const auto n = this ->size ();
@@ -378,8 +379,9 @@ class Tensor {
378379 // / \param range An array with the size of each dimension
379380 // / \param value The value of the tensor elements
380381 template <typename Value,
381- std::enable_if_t <std::is_convertible_v<Value, value_type> &&
382- !detail::is_tensor<Value>::value>* = nullptr >
382+ typename std::enable_if<std::is_convertible_v<Value, value_type> &&
383+ !detail::is_tensor<Value>::value>::type* =
384+ nullptr >
383385 Tensor (const range_type& range, const Value& value)
384386 : Tensor(range, 1 , default_construct{false }) {
385387 detail::tensor_init ([value]() -> Value { return value; }, *this );
@@ -404,10 +406,10 @@ class Tensor {
404406 }
405407
406408 // / Construct an evaluated tensor
407- template <
408- typename InIter,
409- std:: enable_if_t < TiledArray::detail::is_input_iterator<InIter>::value &&
410- !std::is_pointer_v <InIter>> * = nullptr >
409+ template <typename InIter,
410+ typename std::enable_if<
411+ TiledArray::detail::is_input_iterator<InIter>::value &&
412+ !std::is_pointer <InIter>::value>::type * = nullptr >
411413 Tensor (const range_type& range, InIter it)
412414 : Tensor(range, 1 , default_construct{false }) {
413415 auto n = range.volume ();
@@ -437,10 +439,11 @@ class Tensor {
437439 // / if `T1` is a tensor of scalars the constructed tensor is
438440 // / independent of \p other, thus should apply clone to inner
439441 // / tensor nests to behave similarly for nested tensors
440- template <typename T1,
441- std::enable_if_t <
442- is_tensor<T1>::value && !std::is_same_v<T1, Tensor> &&
443- !detail::has_conversion_operator_v<T1, Tensor>>* = nullptr >
442+ template <
443+ typename T1,
444+ typename std::enable_if<
445+ is_tensor<T1>::value && !std::is_same<T1, Tensor>::value &&
446+ !detail::has_conversion_operator_v<T1, Tensor>>::type* = nullptr >
444447 explicit Tensor (const T1& other)
445448 : Tensor(detail::clone_range(other), 1, default_construct{false }) {
446449 detail::tensor_init (value_converter<typename T1::value_type>, *this , other);
@@ -458,9 +461,10 @@ class Tensor {
458461 // / if `T1` is a tensor of scalars the constructed tensor is
459462 // / independent of \p other, thus should apply clone to inner
460463 // / tensor nests to behave similarly for nested tensors
461- template <typename T1, typename Perm,
462- std::enable_if_t <detail::is_nested_tensor_v<T1> &&
463- detail::is_permutation_v<Perm>>* = nullptr >
464+ template <
465+ typename T1, typename Perm,
466+ typename std::enable_if<detail::is_nested_tensor_v<T1> &&
467+ detail::is_permutation_v<Perm>>::type* = nullptr >
464468 Tensor (const T1& other, const Perm& perm)
465469 : Tensor(outer(perm) * other.range(), other.nbatch(),
466470 default_construct{false }) {
@@ -499,10 +503,10 @@ class Tensor {
499503 // / \param other The tensor argument
500504 // / \param op Unary operation that can be invoked on elements of \p other ;
501505 // / if it is not, it will be "threaded" over \p other via `tensor_op`
502- template <
503- typename T1, typename Op,
504- std:: enable_if_t < is_tensor<T1>::value &&
505- !detail::is_permutation_v<std::decay_t <Op>>>* = nullptr >
506+ template <typename T1, typename Op,
507+ typename std:: enable_if_t <
508+ is_tensor<T1>::value &&
509+ !detail::is_permutation_v<std::decay_t <Op>>>* = nullptr >
506510 Tensor (const T1& other, Op&& op)
507511 : Tensor(detail::clone_range(other), 1 , default_construct{false }) {
508512 detail::tensor_init (op, *this , other);
@@ -565,9 +569,10 @@ class Tensor {
565569 // / \param op Binary operation that can be invoked as `op(left[i],right[i]))`;
566570 // / if it is not, it will be "threaded" over \p other via `tensor_op`
567571 // / \param perm The permutation that will be applied to the arguments
568- template <typename T1, typename T2, typename Op, typename Perm,
569- std::enable_if_t <detail::is_nested_tensor<T1, T2>::value &&
570- detail::is_permutation_v<Perm>>* = nullptr >
572+ template <
573+ typename T1, typename T2, typename Op, typename Perm,
574+ typename std::enable_if<detail::is_nested_tensor<T1, T2>::value &&
575+ detail::is_permutation_v<Perm>>::type* = nullptr >
571576 Tensor (const T1& left, const T2& right, Op&& op, const Perm& perm)
572577 : Tensor(outer(perm) * left.range(), 1 , default_construct{false }) {
573578 detail::tensor_init (op, outer (perm), *this , left, right);
@@ -769,7 +774,7 @@ class Tensor {
769774 // / \note This asserts (using TA_ASSERT) that this is not empty, \p ord is
770775 // / included in the range, and `nbatch()==1`
771776 template <typename Ordinal,
772- std::enable_if_t <std::is_integral_v <Ordinal>>* = nullptr >
777+ std::enable_if_t <std::is_integral <Ordinal>::value >* = nullptr >
773778 const_reference operator [](const Ordinal ord) const {
774779 TA_ASSERT (!this ->empty ());
775780 // can't distinguish between operator[](Index...) and operator[](ordinal)
@@ -811,7 +816,7 @@ class Tensor {
811816 // / \note This asserts (using TA_ASSERT) that this is not empty, \p ord is
812817 // / included in the range, and `nbatch()==1`
813818 template <typename Ordinal,
814- std::enable_if_t <std::is_integral_v <Ordinal>>* = nullptr >
819+ std::enable_if_t <std::is_integral <Ordinal>::value >* = nullptr >
815820 const_reference at_ordinal (const Ordinal ord) const {
816821 TA_ASSERT (!this ->empty ());
817822 TA_ASSERT (this ->nbatch () == 1 );
0 commit comments