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 META_END_NAMESPACE() 87 88 /* 89 Description: 90 This can turn SFINAE failures into false values, allowing to construct constexpr bool variables 91 92 Example: 93 94 template<typename Type> 95 using KinfOfInterfaceCheck = BoolWrap<IsKindOfIInterface_v<typename Type::element_type*>>; 96 97 template<typename Type> 98 constexpr bool IsInterfacePtr_v = IsKindOfPointer_v<Type> && IsDetectedWithValue_v<KinfOfInterfaceCheck, Type>; 99 100 this cannot be written directly since Type::element_type fails to compile. 101 102 Or 103 104 template<typename Type> 105 using HasMyMember = decltype(BASE_NS::declval<Type>().MyMember()); 106 107 template<typename Type> 108 constexpr bool HasMyMember_v = IsDetected_v<HasMyMember, Type>; 109 */ 110 111 #endif 112