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