• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PANDA_LIBPANDABASE_CONCEPTS_H
17 #define PANDA_LIBPANDABASE_CONCEPTS_H
18 
19 #include <iterator>
20 
21 namespace panda {
22 
23 /// Iterable concept
24 
25 // NOLINTBEGIN(readability-identifier-naming)
26 template <typename T, typename = void>
27 struct is_iterable : public std::false_type {
28 };
29 
30 template <typename T>
31 struct is_iterable<
32     T, std::void_t<typename T::iterator, decltype(std::declval<T>().begin()), decltype(std::declval<T>().end())>>
33     : public std::true_type {
34 };
35 
36 template <typename T>
37 // NOLINTNEXTLINE(misc-definitions-in-headers)
38 constexpr bool is_iterable_v = is_iterable<T>::value;
39 
40 /// Random access iterable concept
41 
42 template <typename T>
43 struct is_random_access_iterable
44     : public std::bool_constant<is_iterable_v<T> &&
45                                 std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category,
46                                                std::random_access_iterator_tag>> {
47 };
48 
49 template <typename T>
50 // NOLINTNEXTLINE(misc-definitions-in-headers)
51 constexpr bool is_random_access_iterable_v = is_random_access_iterable<T>::value;
52 
53 /// Forward iterable concept
54 
55 template <typename T>
56 struct is_forward_iterable
57     : public std::bool_constant<is_iterable_v<T> &&
58                                 std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category,
59                                                std::forward_iterator_tag>> {
60 };
61 
62 template <typename T>
63 // NOLINTNEXTLINE(misc-definitions-in-headers)
64 constexpr bool is_forward_iterable_v = is_forward_iterable<T>::value;
65 
66 /// Vectorable concept
67 
68 template <class V, typename = void>
69 struct is_vectorable : public std::false_type {
70 };
71 
72 template <class V>
73 struct is_vectorable<V, std::void_t<typename V::value_type, typename V::allocator_type,
74                                     decltype(std::declval<V>().size()), decltype(std::declval<V>().data())>>
75     : public std::bool_constant<is_random_access_iterable_v<V>> {
76 };
77 
78 template <class V>
79 // NOLINTNEXTLINE(misc-definitions-in-headers)
80 constexpr bool is_vectorable_v = is_vectorable<V>::value;
81 
82 /// Stringable concept
83 
84 template <class S, typename = void>
85 struct is_stringable : public std::false_type {
86 };
87 
88 template <class S>
89 struct is_stringable<S, std::void_t<typename S::value_type, typename S::allocator_type, typename S::traits_type,
90                                     decltype(std::declval<S>().length()), decltype(std::declval<S>().data())>>
91     : public std::bool_constant<is_random_access_iterable_v<S>> {
92 };
93 
94 template <class S>
95 // NOLINTNEXTLINE(misc-definitions-in-headers)
96 constexpr bool is_stringable_v = is_stringable<S>::value;
97 
98 /// Hash mappable concept
99 
100 template <class HM, typename = void>
101 struct is_hash_mappable : public std::false_type {
102 };
103 
104 template <class HM>
105 struct is_hash_mappable<
106     HM, std::void_t<typename HM::key_type, typename HM::mapped_type, typename HM::value_type, typename HM::hasher,
107                     typename HM::key_equal, typename HM::allocator_type, decltype(std::declval<HM>().size())>>
108     : public std::bool_constant<is_forward_iterable_v<HM>> {
109 };
110 
111 template <class HM>
112 // NOLINTNEXTLINE(misc-definitions-in-headers)
113 constexpr bool is_hash_mappable_v = is_hash_mappable<HM>::value;
114 
115 /**
116  *  Added in C++20
117  *  Checks whether T is an array type of unknown bound
118  */
119 
120 template <class T>
121 struct is_unbounded_array : public std::false_type {
122 };
123 
124 template <class T>
125 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
126 struct is_unbounded_array<T[]> : public std::true_type {
127 };
128 
129 template <class T>
130 // NOLINTNEXTLINE(misc-definitions-in-headers)
131 constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
132 
133 /// Checks whether T is an array type of known bound
134 
135 template <class T>
136 struct is_bounded_array : public std::false_type {
137 };
138 
139 template <class T, size_t N>
140 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
141 struct is_bounded_array<T[N]> : public std::true_type {
142 };
143 
144 template <class T>
145 // NOLINTNEXTLINE(misc-definitions-in-headers)
146 constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
147 
148 }  // namespace panda
149 
150 // NOLINTEND(readability-identifier-naming)
151 
152 #endif  // PANDA_LIBPANDABASE_CONCEPTS_H
153