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 21namespace panda { 22 23/// Iterable concept 24 25template <typename T, typename = void> 26struct is_iterable : public std::false_type {}; // NOLINT(readability-identifier-naming) 27 28template <typename T> 29struct 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 33template <typename T> 34// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 35constexpr bool is_iterable_v = is_iterable<T>::value; 36 37/// Random access iterable concept 38 39template <typename T> 40struct 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 45template <typename T> 46// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 47constexpr bool is_random_access_iterable_v = is_random_access_iterable<T>::value; 48 49/// Forward iterable concept 50 51template <typename T> 52struct 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 57template <typename T> 58// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 59constexpr bool is_forward_iterable_v = is_forward_iterable<T>::value; 60 61/// Vectorable concept 62 63template <class V, typename = void> 64struct is_vectorable : public std::false_type {}; // NOLINT(readability-identifier-naming) 65 66template <class V> 67struct 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 71template <class V> 72// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 73constexpr bool is_vectorable_v = is_vectorable<V>::value; 74 75/// Stringable concept 76 77template <class S, typename = void> 78struct is_stringable : public std::false_type {}; // NOLINT(readability-identifier-naming) 79 80template <class S> 81struct 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 86template <class S> 87// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 88constexpr bool is_stringable_v = is_stringable<S>::value; 89 90/// Hash mappable concept 91 92template <class HM, typename = void> 93struct is_hash_mappable : public std::false_type {}; // NOLINT(readability-identifier-naming) 94 95template <class HM> 96struct 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 101template <class HM> 102// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 103constexpr 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 111template <class T> 112// NOLINTNEXTLINE(readability-identifier-naming) 113struct is_unbounded_array : public std::false_type {}; 114 115template <class T> 116// NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays) 117struct is_unbounded_array<T[]> : public std::true_type {}; 118 119template <class T> 120// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 121constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value; 122 123/// Checks whether T is an array type of known bound 124 125template <class T> 126// NOLINTNEXTLINE(readability-identifier-naming) 127struct is_bounded_array : public std::false_type {}; 128 129template <class T, size_t N> 130// NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays) 131struct is_bounded_array<T[N]> : public std::true_type {}; 132 133template <class T> 134// NOLINTNEXTLINE(readability-identifier-naming, misc-definitions-in-headers) 135constexpr bool is_bounded_array_v = is_bounded_array<T>::value; 136 137} // namespace panda 138 139#endif // LIBPANDABASE_CONCEPTS_H 140