is_enum.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
  2. // Hinnant & John Maddock 2000.
  3. // Use, modification and distribution are subject to the Boost Software License,
  4. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt).
  6. //
  7. // See http://www.boost.org/libs/type_traits for most recent version including documentation.
  8. #ifndef BOOST_TT_IS_ENUM_HPP_INCLUDED
  9. #define BOOST_TT_IS_ENUM_HPP_INCLUDED
  10. #include <boost/type_traits/intrinsics.hpp>
  11. #include <boost/type_traits/integral_constant.hpp>
  12. #ifndef BOOST_IS_ENUM
  13. #include <boost/type_traits/add_reference.hpp>
  14. #include <boost/type_traits/is_arithmetic.hpp>
  15. #include <boost/type_traits/is_reference.hpp>
  16. #include <boost/type_traits/is_convertible.hpp>
  17. #include <boost/type_traits/is_array.hpp>
  18. #ifdef __GNUC__
  19. #include <boost/type_traits/is_function.hpp>
  20. #endif
  21. #include <boost/type_traits/detail/config.hpp>
  22. #if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION)
  23. # include <boost/type_traits/is_class.hpp>
  24. # include <boost/type_traits/is_union.hpp>
  25. #endif
  26. #endif
  27. namespace boost {
  28. #ifndef BOOST_IS_ENUM
  29. #if !(defined(__BORLANDC__) && (__BORLANDC__ <= 0x551))
  30. namespace detail {
  31. #if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION)
  32. template <typename T>
  33. struct is_class_or_union
  34. {
  35. BOOST_STATIC_CONSTANT(bool, value = ::boost::is_class<T>::value || ::boost::is_union<T>::value);
  36. };
  37. #else
  38. template <typename T>
  39. struct is_class_or_union
  40. {
  41. # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))// we simply can't detect it this way.
  42. BOOST_STATIC_CONSTANT(bool, value = false);
  43. # else
  44. template <class U> static ::boost::type_traits::yes_type is_class_or_union_tester(void(U::*)(void));
  45. # if BOOST_WORKAROUND(__MWERKS__, <= 0x3000) // no SFINAE
  46. static ::boost::type_traits::no_type is_class_or_union_tester(...);
  47. BOOST_STATIC_CONSTANT(
  48. bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type));
  49. # else
  50. template <class U>
  51. static ::boost::type_traits::no_type is_class_or_union_tester(...);
  52. BOOST_STATIC_CONSTANT(
  53. bool, value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(::boost::type_traits::yes_type));
  54. # endif
  55. # endif
  56. };
  57. #endif
  58. struct int_convertible
  59. {
  60. int_convertible(int);
  61. };
  62. // Don't evaluate convertibility to int_convertible unless the type
  63. // is non-arithmetic. This suppresses warnings with GCC.
  64. template <bool is_typename_arithmetic_or_reference = true>
  65. struct is_enum_helper
  66. {
  67. template <typename T> struct type
  68. {
  69. BOOST_STATIC_CONSTANT(bool, value = false);
  70. };
  71. };
  72. template <>
  73. struct is_enum_helper<false>
  74. {
  75. template <typename T> struct type
  76. {
  77. static const bool value = ::boost::is_convertible<typename boost::add_reference<T>::type, ::boost::detail::int_convertible>::value;
  78. };
  79. };
  80. template <typename T> struct is_enum_impl
  81. {
  82. //typedef ::boost::add_reference<T> ar_t;
  83. //typedef typename ar_t::type r_type;
  84. #if defined(__GNUC__)
  85. #ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
  86. // We MUST check for is_class_or_union on conforming compilers in
  87. // order to correctly deduce that noncopyable types are not enums
  88. // (dwa 2002/04/15)...
  89. BOOST_STATIC_CONSTANT(bool, selector =
  90. ::boost::is_arithmetic<T>::value
  91. || ::boost::is_reference<T>::value
  92. || ::boost::is_function<T>::value
  93. || is_class_or_union<T>::value
  94. || is_array<T>::value);
  95. #else
  96. // ...however, not checking is_class_or_union on non-conforming
  97. // compilers prevents a dependency recursion.
  98. BOOST_STATIC_CONSTANT(bool, selector =
  99. ::boost::is_arithmetic<T>::value
  100. || ::boost::is_reference<T>::value
  101. || ::boost::is_function<T>::value
  102. || is_array<T>::value);
  103. #endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
  104. #else // !defined(__GNUC__):
  105. BOOST_STATIC_CONSTANT(bool, selector =
  106. ::boost::is_arithmetic<T>::value
  107. || ::boost::is_reference<T>::value
  108. || is_class_or_union<T>::value
  109. || is_array<T>::value);
  110. #endif
  111. #if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
  112. typedef ::boost::detail::is_enum_helper<
  113. ::boost::detail::is_enum_impl<T>::selector
  114. > se_t;
  115. #else
  116. typedef ::boost::detail::is_enum_helper<selector> se_t;
  117. #endif
  118. typedef typename se_t::template type<T> helper;
  119. BOOST_STATIC_CONSTANT(bool, value = helper::value);
  120. };
  121. } // namespace detail
  122. template <class T> struct is_enum : public integral_constant<bool, ::boost::detail::is_enum_impl<T>::value> {};
  123. #else // __BORLANDC__
  124. //
  125. // buggy is_convertible prevents working
  126. // implementation of is_enum:
  127. template <class T> struct is_enum : public integral_constant<bool, false> {};
  128. #endif
  129. #else // BOOST_IS_ENUM
  130. template <class T> struct is_enum : public integral_constant<bool, BOOST_IS_ENUM(T)> {};
  131. #endif
  132. } // namespace boost
  133. #endif // BOOST_TT_IS_ENUM_HPP_INCLUDED