• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2 / Copyright (c) 2009 Beman Dawes
3 / Copyright (c) 2011-2012 Vicente J. Botet Escriba
4 / Copyright (c) 2012 Anthony Williams
5 / Copyright (c) 2014 Andrey Semashev
6 /
7 / Distributed under the Boost Software License, Version 1.0. (See accompanying
8 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 /]
10
11[section:scoped_enum scoped_enum]
12
13[simplesect Authors]
14
15* Beman Dawes
16* Vicente J. Botet Escriba
17* Anthony Williams
18
19[endsimplesect]
20
21[section Overview]
22
23The `boost/core/scoped_enum.hpp` header contains a number of macros that can be used to generate
24C++11 scoped enums (7.2 \[dcl.enum\]) if the feature is supported by the compiler, otherwise emulate
25it with C++03 constructs. The `BOOST_NO_CXX11_SCOPED_ENUMS` macro from Boost.Config is used to detect
26the feature support in the compiler.
27
28Some of the enumerations defined in the standard library are scoped enums.
29
30    enum class future_errc
31    {
32        broken_promise,
33        future_already_retrieved,
34        promise_already_satisfied,
35        no_state
36    };
37
38The user can portably declare such enumeration as follows:
39
40    BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
41    {
42        broken_promise,
43        future_already_retrieved,
44        promise_already_satisfied,
45        no_state
46    }
47    BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
48
49These macros allows to use `future_errc` in almost all the cases as an scoped enum.
50
51    future_errc ev = future_errc::no_state;
52
53It is possible to specify the underlying type of the enumeration:
54
55    BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(future_errc, unsigned int)
56    {
57        broken_promise,
58        future_already_retrieved,
59        promise_already_satisfied,
60        no_state
61    }
62    BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
63
64The enumeration supports explicit conversion from the underlying type.
65
66The enumeration can be forward declared:
67
68    BOOST_SCOPED_ENUM_FORWARD_DECLARE(future_errc);
69
70There are however some limitations. The emulated scoped enum is not a C++ enum, so `is_enum< future_errc >` will be `false_type`.
71
72The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some helpers. Instead of
73
74    switch (ev)
75    {
76    case future_errc::broken_promise:
77        // ...
78
79use
80
81    switch (boost::native_value(ev))
82    {
83    case future_errc::broken_promise:
84        // ...
85
86and instead of
87
88    template <>
89    struct is_error_code_enum< future_errc > :
90        public true_type
91    {
92    };
93
94use
95
96    template <>
97    struct is_error_code_enum< BOOST_SCOPED_ENUM_NATIVE(future_errc) > :
98        public true_type
99    {
100    };
101
102Explicit conversion to the underlying type should be performed with `boost::underlying_cast` instead of `static_cast`:
103
104    unsigned int val = boost::underlying_cast< unsigned int >(ev);
105
106In C++03, scoped enums behave differently in case of calling an overloaded function when one overload takes a scoped enum as a parameter, and the other takes a parameter of an integral type. Consider the following code:
107
108    enum enum_regular { REGULAR_A, REGULAR_B };
109
110    BOOST_SCOPED_ENUM_DECLARE_BEGIN(enum_scoped)
111    {
112        a, b
113    }
114    BOOST_SCOPED_ENUM_DECLARE_END(enum_scoped)
115
116    void regular_or_int(enum_regular); // (1)
117    void regular_or_int(int);          // (2)
118    void scoped_or_int(enum_scoped);   // (3)
119    void scoped_or_int(int);           // (4)
120
121    regular_or_int(REGULAR_A);                  // calls (1) in C++03 and C++11
122    scoped_or_int(enum_scoped::a);              // calls (3) in C++11 but (4) in C++03!
123    scoped_or_int(enum_scoped(enum_scoped::a)); // calls (3) in C++03 and C++11
124
125Here is usage example:
126
127    BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char)
128    {
129        green,
130        red,
131        cyan
132    }
133    BOOST_SCOPED_ENUM_DECLARE_END(algae)
134    ...
135    algae sample( algae::red );
136    void foo( algae color );
137    ...
138    sample = algae::green;
139    foo( algae::cyan );
140
141[endsect]
142
143[section Deprecated syntax]
144
145In early versions of the header there were two ways to declare scoped enums, with different pros and cons to each.
146The other way used a different set of macros:
147
148    BOOST_SCOPED_ENUM_START(algae)
149    {
150        green,
151        red,
152        cyan
153    };
154    BOOST_SCOPED_ENUM_END
155    ...
156    BOOST_SCOPED_ENUM(algae) sample( algae::red );
157    void foo( BOOST_SCOPED_ENUM(algae) color );
158    ...
159    sample = algae::green;
160    foo( algae::cyan );
161
162Here `BOOST_SCOPED_ENUM_START` corresponds to `BOOST_SCOPED_ENUM_DECLARE_BEGIN`, `BOOST_SCOPED_ENUM_END` to `BOOST_SCOPED_ENUM_DECLARE_END`
163and `BOOST_SCOPED_ENUM` to `BOOST_SCOPED_ENUM_NATIVE`. Note also the semicolon before `BOOST_SCOPED_ENUM_END`.
164
165In the current version these macros produce equivalent result to the ones described above and are considered deprecated.
166
167[endsect]
168
169[section Acquiring the underlying type of the enum]
170
171The header `boost/core/underlying_type.hpp` defines the metafunction `boost::underlying_type` which can be used to
172obtain the underlying type of the scoped enum. This metafunction has support for emulated scoped enums declared with
173macros in `boost/core/scoped_enum.hpp`. When native scoped enums are supported by the compiler, this metafunction
174is equivalent to `std::underlying_type`.
175
176Unfortunately, there are configurations which implement scoped enums but not `std::underlying_type`. In this case
177`boost::underlying_type` has to be specialized by user. The macro `BOOST_NO_UNDERLYING_TYPE` is defined to indicate
178such cases.
179
180[endsect]
181
182[section Acknowledgments]
183
184This scoped enum emulation was developed by Beman Dawes, Vicente J. Botet Escriba and Anthony Williams.
185
186Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott, Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida,
187Matt Calabrese, Daniel James and Andrey Semashev.
188
189[endsect]
190
191[endsect]
192