xerus
a general purpose tensor library
sfinae.h
Go to the documentation of this file.
1 // Xerus - A General Purpose Tensor Library
2 // Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf.
3 //
4 // Xerus is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // Xerus is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with Xerus. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // For further information on Xerus visit https://libXerus.org
18 // or contact us at contact@libXerus.org.
19 
25 #pragma once
26 
27 #include <type_traits>
28 
33 #define XERUS_ADD_MOVE(newTypeName, ...) class newTypeName, typename std::enable_if<std::is_base_of<__VA_ARGS__, typename std::decay<newTypeName>::type>::value, int>::type = 0
34 
35 
40 #if __GNUC__ > 4 || defined(__clang__)
41  // template void
42  template<class...> using void_t = void;
43 
44 
45  #define XERUS_GENERATE_HAS_FUNCTION(function)\
46  namespace sfinae {\
47  template<class, class, class = void>\
48  struct has_##function : std::false_type {};\
49  \
50  template<class clas, class arg>\
51  struct has_##function<clas, arg, void_t<decltype(std::declval<clas>().function(std::declval<arg>()))>> : std::true_type {};\
52  }\
53  \
54 
55 
56  // TODO Gives a false positive if a function can be called by implicit casting!
57  #define XERUS_GENERATE_EXISTS_FUNCTION(function)\
58  namespace sfinae {\
59  template<class, class = void>\
60  struct exists_##function : std::false_type {};\
61  \
62  template<class arg>\
63  struct exists_##function<arg, void_t<decltype(function(std::declval<arg>()))>> : std::true_type {};\
64  }\
65  \
66 
67 #else
68  #define XERUS_GENERATE_HAS_MEMBER(member) \
69  \
70  template < class T > \
71  class HasMember_##member \
72  { \
73  public: \
74  typedef char (& yes)[1]; \
75  typedef char (& no)[2]; \
76  \
77  template <typename C> static yes check(decltype(&C::member)); \
78  template <typename> static no check(...); \
79  \
80  static constexpr bool RESULT = sizeof(check<T>(0)) == sizeof(yes); \
81  }; \
82  \
83  template < class T > \
84  struct has_member_##member \
85  : public std::integral_constant<bool, HasMember_##member<T>::RESULT> \
86  { }; \
87 
88 #endif