1#ifndef BOOST_DESCRIBE_ENUM_HPP_INCLUDED
2#define BOOST_DESCRIBE_ENUM_HPP_INCLUDED
3
4// Copyright 2020 Peter Dimov
5// Distributed under the Boost Software License, Version 1.0.
6// https://www.boost.org/LICENSE_1_0.txt
7
8#include <boost/describe/detail/config.hpp>
9
10#if !defined(BOOST_DESCRIBE_CXX14)
11
12#define BOOST_DESCRIBE_ENUM(E, ...)
13#define BOOST_DESCRIBE_NESTED_ENUM(E, ...)
14
15#else
16
17#include <boost/describe/detail/pp_for_each.hpp>
18#include <boost/describe/detail/list.hpp>
19#include <type_traits>
20
21namespace boost
22{
23namespace describe
24{
25namespace detail
26{
27
28template<class D> struct enum_descriptor
29{
30 // can't use auto here because of the need to supply the definitions below
31 static constexpr decltype(D::value()) value = D::value();
32 static constexpr decltype(D::name()) name = D::name();
33};
34
35#ifndef __cpp_inline_variables
36// GCC requires these definitions
37template<class D> constexpr decltype(D::value()) enum_descriptor<D>::value;
38template<class D> constexpr decltype(D::name()) enum_descriptor<D>::name;
39#endif
40
41template<class... T> auto enum_descriptor_fn_impl( int, T... )
42{
43 return list<enum_descriptor<T>...>();
44}
45
46#define BOOST_DESCRIBE_ENUM_BEGIN(E) \
47 inline auto boost_enum_descriptor_fn( E** ) \
48 { return boost::describe::detail::enum_descriptor_fn_impl( 0
49
50#define BOOST_DESCRIBE_ENUM_ENTRY(E, e) , []{ struct _boost_desc { \
51 static constexpr auto value() noexcept { return E::e; } \
52 static constexpr auto name() noexcept { return #e; } }; return _boost_desc(); }()
53
54#define BOOST_DESCRIBE_ENUM_END(E) ); }
55
56} // namespace detail
57
58#if defined(_MSC_VER) && !defined(__clang__)
59
60#define BOOST_DESCRIBE_ENUM(E, ...) \
61 namespace should_use_BOOST_DESCRIBE_NESTED_ENUM {} \
62 static_assert(std::is_enum<E>::value, "BOOST_DESCRIBE_ENUM should only be used with enums"); \
63 BOOST_DESCRIBE_ENUM_BEGIN(E) \
64 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, __VA_ARGS__) \
65 BOOST_DESCRIBE_ENUM_END(E)
66
67#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) \
68 static_assert(std::is_enum<E>::value, "BOOST_DESCRIBE_NESTED_ENUM should only be used with enums"); \
69 friend BOOST_DESCRIBE_ENUM_BEGIN(E) \
70 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, __VA_ARGS__) \
71 BOOST_DESCRIBE_ENUM_END(E)
72
73#else
74
75#define BOOST_DESCRIBE_ENUM(E, ...) \
76 namespace should_use_BOOST_DESCRIBE_NESTED_ENUM {} \
77 static_assert(std::is_enum<E>::value, "BOOST_DESCRIBE_ENUM should only be used with enums"); \
78 BOOST_DESCRIBE_MAYBE_UNUSED BOOST_DESCRIBE_ENUM_BEGIN(E) \
79 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \
80 BOOST_DESCRIBE_ENUM_END(E)
81
82#define BOOST_DESCRIBE_NESTED_ENUM(E, ...) \
83 static_assert(std::is_enum<E>::value, "BOOST_DESCRIBE_NESTED_ENUM should only be used with enums"); \
84 BOOST_DESCRIBE_MAYBE_UNUSED friend BOOST_DESCRIBE_ENUM_BEGIN(E) \
85 BOOST_DESCRIBE_PP_FOR_EACH(BOOST_DESCRIBE_ENUM_ENTRY, E, ##__VA_ARGS__) \
86 BOOST_DESCRIBE_ENUM_END(E)
87
88#endif
89
90} // namespace describe
91} // namespace boost
92
93#endif // defined(BOOST_DESCRIBE_CXX14)
94
95#if defined(_MSC_VER) && !defined(__clang__)
96
97#define BOOST_DEFINE_ENUM(E, ...) enum E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__)
98#define BOOST_DEFINE_ENUM_CLASS(E, ...) enum class E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__)
99
100#define BOOST_DEFINE_FIXED_ENUM(E, Base, ...) enum E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__)
101#define BOOST_DEFINE_FIXED_ENUM_CLASS(E, Base, ...) enum class E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, __VA_ARGS__)
102
103#else
104
105#define BOOST_DEFINE_ENUM(E, ...) enum E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__)
106#define BOOST_DEFINE_ENUM_CLASS(E, ...) enum class E { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__)
107
108#define BOOST_DEFINE_FIXED_ENUM(E, Base, ...) enum E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__)
109#define BOOST_DEFINE_FIXED_ENUM_CLASS(E, Base, ...) enum class E: Base { __VA_ARGS__ }; BOOST_DESCRIBE_ENUM(E, ##__VA_ARGS__)
110
111#endif
112
113#endif // #ifndef BOOST_DESCRIBE_ENUM_HPP_INCLUDED
114

source code of boost/libs/describe/include/boost/describe/enum.hpp