Akonadi

aktraits.h
1 /*
2  Copyright (C) 2019 Daniel Vrátil <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #ifndef AKONADI_AKTRAITS_H_
21 #define AKONADI_AKTRAITS_H_
22 
23 #include <type_traits>
24 #include <utility>
25 
26 namespace AkTraits {
27 
28 namespace detail {
29 
30  template<typename ...>
31  struct conjunction : std::true_type {};
32  template<typename T>
33  struct conjunction<T> : T {};
34  template<typename T, typename ... Ts>
35  struct conjunction<T, Ts...> : std::conditional_t<bool(T::value), conjunction<Ts...>, T> {};
36 
37  #define DECLARE_HAS_MEBER_TYPE(type_name) \
38  template<typename T, typename U = std::void_t<>> \
39  struct hasMember_##type_name { \
40  static constexpr bool value = false; \
41  }; \
42  \
43  template<typename T> \
44  struct hasMember_##type_name<T, std::void_t<typename T:: type_name>> : std::true_type {};
45 
46  DECLARE_HAS_MEBER_TYPE(value_type)
47 
48 
49  #define DECLARE_HAS_METHOD_GENERIC_IMPL(name, fun, sign) \
50  template<typename T, typename F = sign> \
51  struct hasMethod_##name { \
52  public: \
53  template<typename UType, UType> \
54  struct helperClass; \
55  \
56  using True = char; \
57  using False = struct { char dummy_[2]; }; \
58  \
59  template<typename U> \
60  static True helper(helperClass<F, &U::fun>*);\
61  template<typename> \
62  static False helper(...); \
63  public: \
64  static constexpr bool value = sizeof(helper<T>(nullptr)) == sizeof(True); \
65  };
66 
67  #define DECLARE_HAS_METHOD_GENERIC_CONST(fun, R, ...) \
68  DECLARE_HAS_METHOD_GENERIC_IMPL(fun##_const, fun, R(T::*)(__VA_ARGS__) const)
69 
70  #define DECLARE_HAS_METHOD_GENERIC(fun, R, ...) \
71  DECLARE_HAS_METHOD_GENERIC_IMPL(fun, fun, R(T::*)(__VA_ARGS__))
72 
73  DECLARE_HAS_METHOD_GENERIC_CONST(size, int, void)
74  DECLARE_HAS_METHOD_GENERIC(push_back, void, const typename T::value_type &)
75  DECLARE_HAS_METHOD_GENERIC(insert, typename T::iterator, const typename T::value_type &)
76  DECLARE_HAS_METHOD_GENERIC(reserve, void, int)
77 
78  #define DECLARE_HAS_FUNCTION(name, fun) \
79  template<typename T> \
80  struct has_##name { \
81  template<typename U> \
82  struct helperClass; \
83  \
84  using True = char; \
85  using False = struct { char dummy_[2]; }; \
86  \
87  template<typename U> \
88  static True helper(helperClass<decltype(fun(std::declval<T>()))>*); \
89  template<typename> \
90  static False helper(...); \
91  public: \
92  static constexpr bool value = sizeof(helper<T>(nullptr)) == sizeof(True); \
93  };
94 
95  // For some obscure reason QVector::begin() actually has a default
96  // argument, but QList::begin() does not, thus a regular hasMethod_* check
97  // won't cut it here. Instead we check whether the container object can be
98  // used with std::begin() and std::end() helpers.
99  // Check for constness can be performed by passing "const T" to the type.
100  DECLARE_HAS_FUNCTION(begin, std::begin)
101  DECLARE_HAS_FUNCTION(end, std::end)
102 
106  template<typename T>
107  struct isContainer : conjunction<
108  std::is_constructible<T>,
109  hasMember_value_type<T>,
110  has_begin<T>,
111  has_begin<const T>,
112  has_end<T>,
113  has_end<const T>,
114  hasMethod_size_const<T>
115  > {};
116 
118  template<typename T>
119  struct isAppendable : conjunction<
120  isContainer<T>,
121  hasMethod_push_back<T>
122  > {};
123 
125  template<typename T>
126  struct isInsertable : conjunction<
127  isContainer<T>,
128  hasMethod_insert<T>
129  > {};
130 
132  template<typename T>
133  struct isReservable : conjunction<
134  isContainer<T>,
135  hasMethod_reserve<T>
136  > {};
137 }
138 
139 template<typename T>
141 
142 template<typename T>
144 
145 template<typename T>
147 
148 } // namespace AkTraits
149 
150 #define AK_PP_CAT_(X, Y) X ## Y
151 #define AK_PP_CAT(X, Y) AK_PP_CAT_(X, Y)
152 
153 #define AK_REQUIRES(...) \
154  bool AK_PP_CAT(_ak_requires_, __LINE__) = false, \
155  std::enable_if_t< \
156  AK_PP_CAT(_ak_requires_, __LINE__) || (__VA_ARGS__) \
157  >* = nullptr
158 
159 #endif
This is a very incomplete set of Container named requirement, but I&#39;m too lazy to implement all of th...
Definition: aktraits.h:107
Matches anything that is a container and has push_back() method.
Definition: aktraits.h:119
A glue between Qt and the standard library.
Matches anything that is a container and has insert() method.
Definition: aktraits.h:126
Matches anything that is a container and has reserve() method.
Definition: aktraits.h:133
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:53 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.