forked from boostorg/core
		
	
		
			
				
	
	
		
			173 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
[/
 | 
						|
 / Copyright (c) 2009 Beman Dawes
 | 
						|
 / Copyright (c) 2011-2012 Vicente J. Botet Escriba
 | 
						|
 / Copyright (c) 2012 Anthony Williams
 | 
						|
 / Copyright (c) 2014 Andrey Semashev
 | 
						|
 /
 | 
						|
 / Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
						|
 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
 /]
 | 
						|
 | 
						|
[section:scoped_enum scoped_enum]
 | 
						|
 | 
						|
[simplesect Authors]
 | 
						|
 | 
						|
* Beman Dawes
 | 
						|
* Vicente J. Botet Escriba
 | 
						|
* Anthony Williams
 | 
						|
 | 
						|
[endsimplesect]
 | 
						|
 | 
						|
[section Overview]
 | 
						|
 | 
						|
The `boost/core/scoped_enum.hpp` header contains a number of macros that can be used to generate
 | 
						|
C++11 scoped enums (7.2 \[dcl.enum\]) if the feature is supported by the compiler, otherwise emulate
 | 
						|
it with C++03 constructs. The `BOOST_NO_CXX11_SCOPED_ENUMS` macro from Boost.Config is used to detect
 | 
						|
the feature support in the compiler.
 | 
						|
 | 
						|
Some of the enumerations defined in the standard library are scoped enums.
 | 
						|
 | 
						|
    enum class future_errc
 | 
						|
    {
 | 
						|
        broken_promise,
 | 
						|
        future_already_retrieved,
 | 
						|
        promise_already_satisfied,
 | 
						|
        no_state
 | 
						|
    };
 | 
						|
 | 
						|
The user can portably declare such enumeration as follows:
 | 
						|
 | 
						|
    BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
 | 
						|
    {
 | 
						|
        broken_promise,
 | 
						|
        future_already_retrieved,
 | 
						|
        promise_already_satisfied,
 | 
						|
        no_state
 | 
						|
    }
 | 
						|
    BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
 | 
						|
 | 
						|
These macros allows to use `future_errc` in almost all the cases as an scoped enum.
 | 
						|
 | 
						|
    future_errc ev = future_errc::no_state;
 | 
						|
 | 
						|
It is possible to specify the underlying type of the enumeration:
 | 
						|
 | 
						|
    BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(future_errc, unsigned int)
 | 
						|
    {
 | 
						|
        broken_promise,
 | 
						|
        future_already_retrieved,
 | 
						|
        promise_already_satisfied,
 | 
						|
        no_state
 | 
						|
    }
 | 
						|
    BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
 | 
						|
 | 
						|
The enumeration supports explicit conversion from the underlying type.
 | 
						|
 | 
						|
The enumeration can be forward declared:
 | 
						|
 | 
						|
    BOOST_SCOPED_ENUM_FORWARD_DECLARE(future_errc);
 | 
						|
 | 
						|
There are however some limitations. First, the emulated scoped enum is not a C++ enum, so `is_enum< future_errc >` will be `false_type`.
 | 
						|
 | 
						|
Second, 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
 | 
						|
 | 
						|
    switch (ev)
 | 
						|
    {
 | 
						|
    case future_errc::broken_promise:
 | 
						|
        // ...
 | 
						|
 | 
						|
use
 | 
						|
 | 
						|
    switch (boost::native_value(ev))
 | 
						|
    {
 | 
						|
    case future_errc::broken_promise:
 | 
						|
        // ...
 | 
						|
 | 
						|
and instead of
 | 
						|
 | 
						|
    template <>
 | 
						|
    struct is_error_code_enum< future_errc > :
 | 
						|
        public true_type
 | 
						|
    {
 | 
						|
    };
 | 
						|
 | 
						|
use
 | 
						|
 | 
						|
    template <>
 | 
						|
    struct is_error_code_enum< BOOST_SCOPED_ENUM_NATIVE(future_errc) > :
 | 
						|
        public true_type
 | 
						|
    {
 | 
						|
    };
 | 
						|
 | 
						|
Lastly, explicit conversion to the underlying type should be performed with `boost::underlying_cast` instead of `static_cast`:
 | 
						|
 | 
						|
    unsigned int val = boost::underlying_cast< unsigned int >(ev);
 | 
						|
 | 
						|
Here is usage example:
 | 
						|
 | 
						|
    BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char)
 | 
						|
    {
 | 
						|
        green,
 | 
						|
        red,
 | 
						|
        cyan
 | 
						|
    }
 | 
						|
    BOOST_SCOPED_ENUM_DECLARE_END(algae)
 | 
						|
    ...
 | 
						|
    algae sample( algae::red );
 | 
						|
    void foo( algae color );
 | 
						|
    ...
 | 
						|
    sample = algae::green;
 | 
						|
    foo( algae::cyan );
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[section Deprecated syntax]
 | 
						|
 | 
						|
In early versions of the header there were two ways to declare scoped enums, with different pros and cons to each.
 | 
						|
The other way used a different set of macros:
 | 
						|
 | 
						|
    BOOST_SCOPED_ENUM_START(algae)
 | 
						|
    {
 | 
						|
        green,
 | 
						|
        red,
 | 
						|
        cyan
 | 
						|
    };
 | 
						|
    BOOST_SCOPED_ENUM_END
 | 
						|
    ...
 | 
						|
    BOOST_SCOPED_ENUM(algae) sample( algae::red );
 | 
						|
    void foo( BOOST_SCOPED_ENUM(algae) color );
 | 
						|
    ...
 | 
						|
    sample = algae::green;
 | 
						|
    foo( algae::cyan );
 | 
						|
 | 
						|
Here `BOOST_SCOPED_ENUM_START` corresponds to `BOOST_SCOPED_ENUM_DECLARE_BEGIN`, `BOOST_SCOPED_ENUM_END` to `BOOST_SCOPED_ENUM_DECLARE_END`
 | 
						|
and `BOOST_SCOPED_ENUM` to `BOOST_SCOPED_ENUM_NATIVE`. Note also the semicolon before `BOOST_SCOPED_ENUM_END`.
 | 
						|
 | 
						|
In the current version these macros produce equivalent result to the ones described above and are considered deprecated.
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[section Acquiring the underlying type of the enum]
 | 
						|
 | 
						|
The header `boost/core/underlying_type.hpp` defines the metafunction `boost::underlying_type` which can be used to
 | 
						|
obtain the underlying type of the scoped enum. This metafunction has support for emulated scoped enums declared with
 | 
						|
macros in `boost/core/scoped_enum.hpp`. When native scoped enums are supported by the compiler, this metafunction
 | 
						|
is equivalent to `std::underlying_type`.
 | 
						|
 | 
						|
Unfortunately, there are configurations which implement scoped enums but not `std::underlying_type`. In this case
 | 
						|
`boost::underlying_type` has to be specialized by user. The macro `BOOST_NO_UNDERLYING_TYPE` is defined to indicate
 | 
						|
such cases.
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[section Acknowledgments]
 | 
						|
 | 
						|
This scoped enum emulation was developed by Beman Dawes, Vicente J. Botet Escriba and Anthony Williams.
 | 
						|
 | 
						|
Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott, Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida,
 | 
						|
Matt Calabrese, Daniel James and Andrey Semashev.
 | 
						|
 | 
						|
[endsect]
 | 
						|
 | 
						|
[endsect]
 |