1fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/* 2fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Copyright (C) 2016 The Android Open Source Project 3fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 4fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 5fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * you may not use this file except in compliance with the License. 6fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * You may obtain a copy of the License at 7fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 8fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 9fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 10fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Unless required by applicable law or agreed to in writing, software 11fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 12fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * See the License for the specific language governing permissions and 14fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * limitations under the License. 15fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 16fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 17fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#ifndef STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_ 18fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#define STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_ 19fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 20fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#include <type_traits> 21fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 22fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarnamespace android { 23fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 24fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 25fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * std::is_signed, is_unsigned and is_integral does not consider enums even though the standard 26fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * considers them integral. Create modified versions of these here. Also create a wrapper around 27fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * std::underlying_type that does not require checking if the type is an enum. 28fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 29fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 30fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 31fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Type support utility class to check if a type is an integral type or an enum. 32fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 33fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<typename T> 34fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct is_integral_or_enum 35fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar : std::integral_constant<bool, std::is_integral<T>::value || std::is_enum<T>::value> { }; 36fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 37fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 38fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Type support utility class to get the underlying std::is_integral supported type for a type. 39fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * This returns the underlying type for enums, and the same type for types covered by 40fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * std::is_integral. 41fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 42fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * This is also used as a conditional to return an alternate type if the template param is not 43fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * an integral or enum type (as in underlying_integral_type<T, TypeIfNotEnumOrIntegral>::type). 44fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 45fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<typename T, 46fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typename U=typename std::enable_if<is_integral_or_enum<T>::value>::type, 47fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar bool=std::is_enum<T>::value, 48fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar bool=std::is_integral<T>::value> 49fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct underlying_integral_type { 50fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!std::is_enum<T>::value, "T should not be enum here"); 51fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!std::is_integral<T>::value, "T should not be integral here"); 52fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef U type; 53fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar}; 54fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 55fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** Specialization for enums. */ 56fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<typename T, typename U> 57fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct underlying_integral_type<T, U, true, false> { 58fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(std::is_enum<T>::value, "T should be enum here"); 59fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!std::is_integral<T>::value, "T should not be integral here"); 60fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef typename std::underlying_type<T>::type type; 61fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar}; 62fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 63fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** Specialization for non-enum std-integral types. */ 64fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<typename T, typename U> 65fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct underlying_integral_type<T, U, false, true> { 66fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!std::is_enum<T>::value, "T should not be enum here"); 67fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(std::is_integral<T>::value, "T should be integral here"); 68fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef T type; 69fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar}; 70fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 71fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 72fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Type support utility class to check if the underlying integral type is signed. 73fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 74fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<typename T> 75fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct is_signed_integral 76fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar : std::integral_constant<bool, std::is_signed< 77fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typename underlying_integral_type<T, unsigned>::type>::value> { }; 78fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 79fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 80fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Type support utility class to check if the underlying integral type is unsigned. 81fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 82fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<typename T> 83fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct is_unsigned_integral 84fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar : std::integral_constant<bool, std::is_unsigned< 85fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typename underlying_integral_type<T, signed>::type>::value> { 86fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar}; 87fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 88e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 89e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Type support relationship query template. 90e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * 91e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * If T occurs as one of the types in Us with the same const-volatile qualifications, provides the 92e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * member constant |value| equal to true. Otherwise value is false. 93e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 94e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T, typename ...Us> 95e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct is_one_of; 96e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 97e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \if 0 98e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 99e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when first type matches the searched type. 100e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 101e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T, typename ...Us> 102e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct is_one_of<T, T, Us...> : std::true_type {}; 103e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 104e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 105e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when first type does not match the searched type. 106e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 107e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T, typename U, typename ...Us> 108e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct is_one_of<T, U, Us...> : is_one_of<T, Us...> {}; 109e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 110e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 111e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when there are no types to search. 112e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 113e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T> 114e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct is_one_of<T> : std::false_type {}; 115e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \endif 116e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 117e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 118e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Type support relationship query template. 119e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * 120e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * If all types in Us are unique, provides the member constant |value| equal to true. 121e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Otherwise value is false. 122e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 123e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename ...Us> 124e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct are_unique; 125e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 126e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \if 0 127e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 128e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when there are no types. 129e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 130e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<> 131e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct are_unique<> : std::true_type {}; 132e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 133e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 134e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when there is at least one type to check. 135e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 136e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T, typename ...Us> 137e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct are_unique<T, Us...> 138e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar : std::integral_constant<bool, are_unique<Us...>::value && !is_one_of<T, Us...>::value> {}; 139e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \endif 140e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 141e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \if 0 142e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T, typename ...Us> 143e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_impl; 144e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 145e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 146e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when there are no types to search. 147e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 148e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T> 149e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_impl<Base, T> : std::integral_constant<size_t, 0> {}; 150e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 151e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 152e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when T is the first type in Us. 153e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 154e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T, typename ...Us> 155e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_impl<Base, T, T, Us...> : std::integral_constant<size_t, Base> {}; 156e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 157e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 158e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization when T is not the first type in Us. 159e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 160e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T, typename U, typename ...Us> 161e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_impl<Base, T, U, Us...> 162e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar : std::integral_constant<size_t, _find_first_impl<Base + 1, T, Us...>::value> {}; 163e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 164e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \endif 165e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 166e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 167e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Type support relationship query template. 168e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * 169e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * If T occurs in Us, index is the 1-based left-most index of T in Us. Otherwise, index is 0. 170e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 171e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T, typename ...Us> 172e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct find_first { 173e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar static constexpr size_t index = _find_first_impl<1, T, Us...>::value; 174e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar}; 175e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 176e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \if 0 177e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 178e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Helper class for find_first_convertible_to template. 179e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * 180e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Adds a base index. 181e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 182e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T, typename ...Us> 183e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_convertible_to_helper; 184e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 185e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 186e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization for when there are more types to consider 187e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 188e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T, typename U, typename ...Us> 189e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_convertible_to_helper<Base, T, U, Us...> { 190e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar static constexpr size_t index = 191e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar std::is_convertible<T, U>::value ? Base : 192e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar _find_first_convertible_to_helper<Base + 1, T, Us...>::index; 193e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar typedef typename std::conditional< 194e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar std::is_convertible<T, U>::value, U, 195e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar typename _find_first_convertible_to_helper<Base + 1, T, Us...>::type>::type type; 196e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar}; 197e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 198e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 199e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Template specialization for when there are no more types to consider 200e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 201e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<size_t Base, typename T> 202e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct _find_first_convertible_to_helper<Base, T> { 203e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar static constexpr size_t index = 0; 204e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar typedef void type; 205e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar}; 206e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 207e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/// \endif 208e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 209e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar/** 210e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Type support template that returns the type that T can be implicitly converted into, and its 211e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * index, from a list of other types (Us). 212e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * 213e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * Returns index of 0 and type of void if there are no convertible types. 214e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * 215e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * \param T type that is converted 216e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar * \param Us types into which the conversion is considered 217e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar */ 218e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnartemplate<typename T, typename ...Us> 219e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnarstruct find_first_convertible_to : public _find_first_convertible_to_helper<1, T, Us...> { }; 220e322cc51459b3fac11e7a080c3eb8ee1bfb36fc8Lajos Molnar 221fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar} // namespace android 222fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 223fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#endif // STAGEFRIGHT_FOUNDATION_TYPE_TRAITS_H_ 224fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 225