1 // Copyright 2020 The Dawn Authors 2 // 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 #ifndef COMMON_UNDERLYINGTYPE_H_ 16 #define COMMON_UNDERLYINGTYPE_H_ 17 18 #include <type_traits> 19 20 // UnderlyingType is similar to std::underlying_type_t. It is a passthrough for already 21 // integer types which simplifies getting the underlying primitive type for an arbitrary 22 // template parameter. It includes a specialization for detail::TypedIntegerImpl which yields 23 // the wrapped integer type. 24 namespace detail { 25 template <typename T, typename Enable = void> 26 struct UnderlyingTypeImpl; 27 28 template <typename I> 29 struct UnderlyingTypeImpl<I, typename std::enable_if_t<std::is_integral<I>::value>> { 30 using type = I; 31 }; 32 33 template <typename E> 34 struct UnderlyingTypeImpl<E, typename std::enable_if_t<std::is_enum<E>::value>> { 35 using type = std::underlying_type_t<E>; 36 }; 37 38 // Forward declare the TypedInteger impl. 39 template <typename Tag, typename T> 40 class TypedIntegerImpl; 41 42 template <typename Tag, typename I> 43 struct UnderlyingTypeImpl<TypedIntegerImpl<Tag, I>> { 44 using type = typename UnderlyingTypeImpl<I>::type; 45 }; 46 } // namespace detail 47 48 template <typename T> 49 using UnderlyingType = typename detail::UnderlyingTypeImpl<T>::type; 50 51 #endif // COMMON_UNDERLYINGTYPE_H_ 52