enum.hpp 4.0 KB

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