blob: abe2c692f85d1ebc79d6703343f9dcd5799bccd6 [file] [log] [blame]
Brian Silverman407d3cd2018-08-04 17:48:52 -07001[/
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. First, the emulated scoped enum is not a C++ enum, so `is_enum< future_errc >` will be `false_type`.
71
72Second, the 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
102Lastly, explicit 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
106Here is usage example:
107
108 BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char)
109 {
110 green,
111 red,
112 cyan
113 }
114 BOOST_SCOPED_ENUM_DECLARE_END(algae)
115 ...
116 algae sample( algae::red );
117 void foo( algae color );
118 ...
119 sample = algae::green;
120 foo( algae::cyan );
121
122[endsect]
123
124[section Deprecated syntax]
125
126In early versions of the header there were two ways to declare scoped enums, with different pros and cons to each.
127The other way used a different set of macros:
128
129 BOOST_SCOPED_ENUM_START(algae)
130 {
131 green,
132 red,
133 cyan
134 };
135 BOOST_SCOPED_ENUM_END
136 ...
137 BOOST_SCOPED_ENUM(algae) sample( algae::red );
138 void foo( BOOST_SCOPED_ENUM(algae) color );
139 ...
140 sample = algae::green;
141 foo( algae::cyan );
142
143Here `BOOST_SCOPED_ENUM_START` corresponds to `BOOST_SCOPED_ENUM_DECLARE_BEGIN`, `BOOST_SCOPED_ENUM_END` to `BOOST_SCOPED_ENUM_DECLARE_END`
144and `BOOST_SCOPED_ENUM` to `BOOST_SCOPED_ENUM_NATIVE`. Note also the semicolon before `BOOST_SCOPED_ENUM_END`.
145
146In the current version these macros produce equivalent result to the ones described above and are considered deprecated.
147
148[endsect]
149
150[section Acquiring the underlying type of the enum]
151
152The header `boost/core/underlying_type.hpp` defines the metafunction `boost::underlying_type` which can be used to
153obtain the underlying type of the scoped enum. This metafunction has support for emulated scoped enums declared with
154macros in `boost/core/scoped_enum.hpp`. When native scoped enums are supported by the compiler, this metafunction
155is equivalent to `std::underlying_type`.
156
157Unfortunately, there are configurations which implement scoped enums but not `std::underlying_type`. In this case
158`boost::underlying_type` has to be specialized by user. The macro `BOOST_NO_UNDERLYING_TYPE` is defined to indicate
159such cases.
160
161[endsect]
162
163[section Acknowledgments]
164
165This scoped enum emulation was developed by Beman Dawes, Vicente J. Botet Escriba and Anthony Williams.
166
167Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott, Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida,
168Matt Calabrese, Daniel James and Andrey Semashev.
169
170[endsect]
171
172[endsect]