From 9cf16a91fd8f31c39d7ebecedfd3c2b94ebb7640 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkovsky@mmg.fjfi.cvut.cz>
Date: Fri, 30 Aug 2019 13:31:08 +0200
Subject: [PATCH] Fixed HasConstexprGetSizeMethod trait class to work with
 scalar types

---
 src/TNL/TypeTraits.h | 49 ++++++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/src/TNL/TypeTraits.h b/src/TNL/TypeTraits.h
index efba05db89..d34f7d39fc 100644
--- a/src/TNL/TypeTraits.h
+++ b/src/TNL/TypeTraits.h
@@ -127,25 +127,35 @@ struct HasConstexprGetSizeMethod
 {
 private:
    // implementation adopted from here: https://stackoverflow.com/a/50169108
-
-// disable nvcc warning: invalid narrowing conversion from "unsigned int" to "int"
-// (the implementation is based on the conversion)
-#ifdef __NVCC__
-   #pragma push
-   #pragma diag_suppress 2361
-#endif
-   template< typename M, M method >
-   static constexpr std::true_type is_constexpr_impl( decltype(int{((*method)(), 0U)}) );
-#ifdef __NVCC__
-   #pragma pop
-#endif
-
-   template< typename M, M method >
-   static constexpr std::false_type is_constexpr_impl(...);
-
-   using type = decltype(is_constexpr_impl< decltype(&T::getSize), &T::getSize >(0));
-   // TODO: this does not work for integral types because T::getSize does not exist
-   // error #276: name followed by "::" must be a class or namespace name
+   template< bool hasGetSize = HasGetSizeMethod< T >::value, typename = void >
+   struct impl
+   {
+      // disable nvcc warning: invalid narrowing conversion from "unsigned int" to "int"
+      // (the implementation is based on the conversion)
+      #ifdef __NVCC__
+         #pragma push
+         #pragma diag_suppress 2361
+      #endif
+      template< typename M, M method >
+      static constexpr std::true_type is_constexpr_impl( decltype(int{((*method)(), 0U)}) );
+      #ifdef __NVCC__
+         #pragma pop
+      #endif
+
+      template< typename M, M method >
+      static constexpr std::false_type is_constexpr_impl(...);
+
+      using type = decltype(is_constexpr_impl< decltype(&T::getSize), &T::getSize >(0));
+   };
+
+   // specialization for types which don't have getSize() method at all
+   template< typename _ >
+   struct impl< false, _ >
+   {
+      using type = std::false_type;
+   };
+
+   using type = typename impl<>::type;
 
 public:
    static constexpr bool value = type::value;
@@ -160,7 +170,6 @@ public:
 template< typename T >
 struct IsStaticArrayType
 : public std::integral_constant< bool,
-            HasGetSizeMethod< T >::value &&
             HasConstexprGetSizeMethod< T >::value &&
             HasSubscriptOperator< T >::value >
 {};
-- 
GitLab