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