1 //  underlying_type.hpp  ---------------------------------------------------------//
2 
3 //  Copyright Beman Dawes, 2009
4 //  Copyright (C) 2011-2012 Vicente J. Botet Escriba
5 //  Copyright (C) 2012 Anthony Williams
6 //  Copyright (C) 2014 Andrey Semashev
7 
8 //  Distributed under the Boost Software License, Version 1.0.
9 //  See http://www.boost.org/LICENSE_1_0.txt
10 
11 #ifndef BOOST_CORE_UNDERLYING_TYPE_HPP
12 #define BOOST_CORE_UNDERLYING_TYPE_HPP
13 
14 #include <boost/config.hpp>
15 
16 // GCC 4.7 and later seem to provide std::underlying_type
17 #if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) || (defined(BOOST_GCC) && BOOST_GCC >= 40700 && defined(__GXX_EXPERIMENTAL_CXX0X__))
18 #include <type_traits>
19 #define BOOST_DETAIL_HAS_STD_UNDERLYING_TYPE
20 #endif
21 
22 #ifdef BOOST_HAS_PRAGMA_ONCE
23 #pragma once
24 #endif
25 
26 namespace boost {
27 
28 namespace detail {
29 
30 template< typename EnumType, typename Void = void >
31 struct underlying_type_impl;
32 
33 #if defined(BOOST_NO_CXX11_SCOPED_ENUMS)
34 
35 // Support for boost/core/scoped_enum.hpp
36 template< typename EnumType >
37 struct underlying_type_impl< EnumType, typename EnumType::is_boost_scoped_enum_tag >
38 {
39     /**
40      * The member typedef type names the underlying type of EnumType. It is EnumType::underlying_type when the EnumType is an emulated scoped enum,
41      */
42     typedef typename EnumType::underlying_type type;
43 };
44 
45 #endif
46 
47 #if defined(BOOST_DETAIL_HAS_STD_UNDERLYING_TYPE)
48 
49 template< typename EnumType, typename Void >
50 struct underlying_type_impl
51 {
52     typedef typename std::underlying_type< EnumType >::type type;
53 };
54 
55 #endif
56 
57 } // namespace detail
58 
59 #if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_DETAIL_HAS_STD_UNDERLYING_TYPE)
60 #define BOOST_NO_UNDERLYING_TYPE
61 #endif
62 
63 /**
64  * Meta-function to get the underlying type of a scoped enum.
65  *
66  * Requires EnumType must be an enum type or the emulation of a scoped enum.
67  * If BOOST_NO_UNDERLYING_TYPE is defined, the implementation will not be able
68  * to deduce the underlying type of enums. The user is expected to specialize
69  * this trait in this case.
70  */
71 template< typename EnumType >
72 struct underlying_type :
73     public detail::underlying_type_impl< EnumType >
74 {
75 };
76 
77 } // namespace boost
78 
79 #endif  // BOOST_CORE_UNDERLYING_TYPE_HPP
80