scoped_enum.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright Andrey Semashev 2014.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file scoped_enum.cpp
  9. * \author Andrey Semashev
  10. * \date 06.06.2014
  11. *
  12. * \brief This test checks that scoped enum emulation works similar to C++11 scoped enums.
  13. */
  14. #include <boost/core/scoped_enum.hpp>
  15. #include <boost/core/lightweight_test.hpp>
  16. BOOST_SCOPED_ENUM_DECLARE_BEGIN(namespace_enum1)
  17. {
  18. value0,
  19. value1,
  20. value2
  21. }
  22. BOOST_SCOPED_ENUM_DECLARE_END(namespace_enum1)
  23. BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(namespace_enum2, unsigned char)
  24. {
  25. // Checks that enum value names do not clash
  26. value0 = 10,
  27. value1 = 20,
  28. value2 = 30
  29. }
  30. BOOST_SCOPED_ENUM_DECLARE_END(namespace_enum2)
  31. struct my_struct
  32. {
  33. // Checks that declarations are valid in class scope
  34. BOOST_SCOPED_ENUM_DECLARE_BEGIN(color)
  35. {
  36. red,
  37. green,
  38. blue
  39. }
  40. BOOST_SCOPED_ENUM_DECLARE_END(color)
  41. color m_color;
  42. explicit my_struct(color col) : m_color(col)
  43. {
  44. }
  45. color get_color() const
  46. {
  47. return m_color;
  48. }
  49. };
  50. void check_operators()
  51. {
  52. namespace_enum1 enum1 = namespace_enum1::value0;
  53. BOOST_TEST(enum1 == namespace_enum1::value0);
  54. BOOST_TEST(enum1 != namespace_enum1::value1);
  55. BOOST_TEST(enum1 != namespace_enum1::value2);
  56. enum1 = namespace_enum1::value1;
  57. BOOST_TEST(enum1 != namespace_enum1::value0);
  58. BOOST_TEST(enum1 == namespace_enum1::value1);
  59. BOOST_TEST(enum1 != namespace_enum1::value2);
  60. BOOST_TEST(!(enum1 < namespace_enum1::value0));
  61. BOOST_TEST(!(enum1 <= namespace_enum1::value0));
  62. BOOST_TEST(enum1 >= namespace_enum1::value0);
  63. BOOST_TEST(enum1 > namespace_enum1::value0);
  64. BOOST_TEST(!(enum1 < namespace_enum1::value1));
  65. BOOST_TEST(enum1 <= namespace_enum1::value1);
  66. BOOST_TEST(enum1 >= namespace_enum1::value1);
  67. BOOST_TEST(!(enum1 > namespace_enum1::value1));
  68. namespace_enum1 enum2 = namespace_enum1::value0;
  69. BOOST_TEST(enum1 != enum2);
  70. enum2 = enum1;
  71. BOOST_TEST(enum1 == enum2);
  72. }
  73. void check_argument_passing()
  74. {
  75. my_struct str(my_struct::color::green);
  76. BOOST_TEST(str.get_color() == my_struct::color::green);
  77. }
  78. void check_switch_case()
  79. {
  80. my_struct str(my_struct::color::blue);
  81. switch (boost::native_value(str.get_color()))
  82. {
  83. case my_struct::color::blue:
  84. break;
  85. default:
  86. BOOST_ERROR("Unexpected color value in switch/case");
  87. }
  88. }
  89. template< typename T >
  90. struct my_trait
  91. {
  92. enum _ { value = 0 };
  93. };
  94. template< >
  95. struct my_trait< BOOST_SCOPED_ENUM_NATIVE(namespace_enum2) >
  96. {
  97. enum _ { value = 1 };
  98. };
  99. template< typename T >
  100. void native_type_helper(T)
  101. {
  102. BOOST_TEST(my_trait< T >::value != 0);
  103. }
  104. void check_native_type()
  105. {
  106. BOOST_TEST(my_trait< int >::value == 0);
  107. BOOST_TEST(my_trait< BOOST_SCOPED_ENUM_NATIVE(namespace_enum2) >::value != 0);
  108. BOOST_TEST(my_trait< boost::native_type< namespace_enum2 >::type >::value != 0);
  109. namespace_enum2 enum1 = namespace_enum2::value0;
  110. native_type_helper(boost::native_value(enum1));
  111. }
  112. void check_underlying_cast()
  113. {
  114. namespace_enum2 enum1 = namespace_enum2::value1;
  115. BOOST_TEST(boost::underlying_cast< unsigned char >(enum1) == 20);
  116. }
  117. void check_underlying_type()
  118. {
  119. // The real check for the type is in the underlying_type trait test.
  120. namespace_enum2 enum1 = namespace_enum2::value1;
  121. BOOST_TEST(sizeof(enum1) == sizeof(unsigned char));
  122. }
  123. int main(int, char*[])
  124. {
  125. check_operators();
  126. check_argument_passing();
  127. check_switch_case();
  128. check_native_type();
  129. check_underlying_cast();
  130. check_underlying_type();
  131. return boost::report_errors();
  132. }