• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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