• 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 LIBPANDABASE_CONCEPTS_H
17 #define LIBPANDABASE_CONCEPTS_H
18 
19 #include <iterator>
20 
21 namespace panda {
22 
23 /// Iterable concept
24 
25 template <typename T, typename = void>
26 struct is_iterable : public std::false_type {};  // NOLINT(readability-identifier-naming)
27 
28 template <typename T>
29 struct is_iterable<  // NOLINT(readability-identifier-naming)
30     T, std::void_t<typename T::iterator, decltype(std::declval<T>().begin()), decltype(std::declval<T>().end())>>
31     : public std::true_type {};
32 
33 template <typename T>
34 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
35 constexpr bool is_iterable_v = is_iterable<T>::value;
36 
37 /// Random access iterable concept
38 
39 template <typename T>
40 struct is_random_access_iterable  // NOLINT(readability-identifier-naming)
41     : public std::bool_constant<is_iterable_v<T> &&
42                                 std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category,
43                                                std::random_access_iterator_tag>> {};
44 
45 template <typename T>
46 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
47 constexpr bool is_random_access_iterable_v = is_random_access_iterable<T>::value;
48 
49 /// Forward iterable concept
50 
51 template <typename T>
52 struct is_forward_iterable  // NOLINT(readability-identifier-naming)
53     : public std::bool_constant<is_iterable_v<T> &&
54                                 std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category,
55                                                std::forward_iterator_tag>> {};
56 
57 template <typename T>
58 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
59 constexpr bool is_forward_iterable_v = is_forward_iterable<T>::value;
60 
61 /// Vectorable concept
62 
63 template <class V, typename = void>
64 struct is_vectorable : public std::false_type {};  // NOLINT(readability-identifier-naming)
65 
66 template <class V>
67 struct is_vectorable<  // NOLINT(readability-identifier-naming)
68     V, std::void_t<typename V::value_type, typename V::allocator_type, decltype(std::declval<V>().size()),
69                    decltype(std::declval<V>().data())>> : public std::bool_constant<is_random_access_iterable_v<V>> {};
70 
71 template <class V>
72 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
73 constexpr bool is_vectorable_v = is_vectorable<V>::value;
74 
75 /// Stringable concept
76 
77 template <class S, typename = void>
78 struct is_stringable : public std::false_type {};  // NOLINT(readability-identifier-naming)
79 
80 template <class S>
81 struct is_stringable<  // NOLINT(readability-identifier-naming)
82     S, std::void_t<typename S::value_type, typename S::allocator_type, typename S::traits_type,
83                    decltype(std::declval<S>().length()), decltype(std::declval<S>().data())>>
84     : public std::bool_constant<is_random_access_iterable_v<S>> {};
85 
86 template <class S>
87 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
88 constexpr bool is_stringable_v = is_stringable<S>::value;
89 
90 /// Hash mappable concept
91 
92 template <class HM, typename = void>
93 struct is_hash_mappable : public std::false_type {};  // NOLINT(readability-identifier-naming)
94 
95 template <class HM>
96 struct is_hash_mappable<  // NOLINT(readability-identifier-naming)
97     HM, std::void_t<typename HM::key_type, typename HM::mapped_type, typename HM::value_type, typename HM::hasher,
98                     typename HM::key_equal, typename HM::allocator_type, decltype(std::declval<HM>().size())>>
99     : public std::bool_constant<is_forward_iterable_v<HM>> {};
100 
101 template <class HM>
102 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
103 constexpr bool is_hash_mappable_v = is_hash_mappable<HM>::value;
104 
105 /**
106  *  Added in C++20
107  */
108 
109 /// Checks whether T is an array type of unknown bound
110 
111 template <class T>
112 // NOLINTNEXTLINE(readability-identifier-naming)
113 struct is_unbounded_array : public std::false_type {};
114 
115 template <class T>
116 // NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays)
117 struct is_unbounded_array<T[]> : public std::true_type {};
118 
119 template <class T>
120 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
121 constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
122 
123 /// Checks whether T is an array type of known bound
124 
125 template <class T>
126 // NOLINTNEXTLINE(readability-identifier-naming)
127 struct is_bounded_array : public std::false_type {};
128 
129 template <class T, size_t N>
130 // NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays)
131 struct is_bounded_array<T[N]> : public std::true_type {};
132 
133 template <class T>
134 // NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers)
135 constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
136 
137 }  // namespace panda
138 
139 #endif  // LIBPANDABASE_CONCEPTS_H
140