1 /* 2 * Copyright (c) 2024 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 META_BASE_TYPE_TRAITS_H 17 #define META_BASE_TYPE_TRAITS_H 18 19 #include <base/containers/type_traits.h> 20 21 #include <meta/base/namespace.h> 22 23 META_BEGIN_NAMESPACE() 24 25 template<typename... Types> 26 struct TypeList {}; 27 28 template<bool B> 29 struct BoolWrap { 30 constexpr static bool value = B; // NOLINT(readability-identifier-naming) 31 }; 32 33 // same concept as https://en.cppreference.com/w/cpp/experimental/is_detected but simplified for our needs 34 template<typename Void, template<class...> class Op, typename... Args> 35 struct IsDetected { 36 static constexpr bool value = false; // NOLINT(readability-identifier-naming) 37 using type = BoolWrap<false>; 38 }; 39 40 template<template<class...> class Op, typename... Args> 41 struct IsDetected<decltype(BASE_NS::declval<Op<Args...>>(), void()), Op, Args...> { 42 static constexpr bool value = true; // NOLINT(readability-identifier-naming) 43 using type = Op<Args...>; 44 }; 45 46 template<template<class...> class Op, typename... Args> 47 constexpr bool IsDetected_v = IsDetected<void, Op, Args...>::value; // NOLINT(readability-identifier-naming) 48 49 // NOLINTBEGIN(readability-identifier-naming) 50 template<template<class...> class Op, typename... Args> 51 constexpr bool IsDetectedWithValue_v = IsDetected<void, Op, Args...>::type::value; 52 // NOLINTEND(readability-identifier-naming) 53 54 template<typename T> 55 using PlainType_t = BASE_NS::remove_const_t<BASE_NS::remove_reference_t<T>>; // NOLINT(readability-identifier-naming) 56 57 template<size_t... Ints> 58 struct IndexSequence {}; 59 60 template<size_t Size, size_t... Ints> 61 struct MakeIndexSequenceImpl { 62 using type = typename MakeIndexSequenceImpl<Size - 1, Size - 1, Ints...>::type; 63 }; 64 65 template<size_t... Ints> 66 struct MakeIndexSequenceImpl<0, Ints...> { 67 using type = IndexSequence<Ints...>; 68 }; 69 70 template<typename... Args> 71 using MakeIndexSequenceFor = typename MakeIndexSequenceImpl<sizeof...(Args)>::type; 72 73 template<size_t Size> 74 using MakeIndexSequence = typename MakeIndexSequenceImpl<Size>::type; 75 76 template<typename Type> 77 struct NonDeduced { 78 using type = Type; 79 }; 80 template<typename Type> 81 using NonDeduced_t = typename NonDeduced<Type>::type; 82 83 template<typename T> 84 constexpr bool is_enum_v = __is_enum(T); // NOLINT(readability-identifier-naming) 85 86 template<typename T, bool = is_enum_v<T>> 87 struct RealType { 88 using type = T; 89 }; 90 91 template<typename T> 92 struct RealType<T, true> { 93 using type = BASE_NS::underlying_type_t<T>; 94 }; 95 96 template<typename T> 97 using RealType_t = typename RealType<T>::type; // NOLINT(readability-identifier-naming) 98 99 META_END_NAMESPACE() 100 101 /* 102 Description: 103 This can turn SFINAE failures into false values, allowing to construct constexpr bool variables 104 105 Example: 106 107 template<typename Type> 108 using KinfOfInterfaceCheck = BoolWrap<IsKindOfIInterface_v<typename Type::element_type*>>; 109 110 template<typename Type> 111 constexpr bool IsInterfacePtr_v = IsKindOfPointer_v<Type> && IsDetectedWithValue_v<KinfOfInterfaceCheck, Type>; 112 113 this cannot be written directly since Type::element_type fails to compile. 114 115 Or 116 117 template<typename Type> 118 using HasMyMember = decltype(BASE_NS::declval<Type>().MyMember()); 119 120 template<typename Type> 121 constexpr bool HasMyMember_v = IsDetected_v<HasMyMember, Type>; 122 */ 123 124 #endif 125