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
15#include <boost/core/scoped_enum.hpp>
16#include <boost/core/lightweight_test.hpp>
17
18#if defined(_MSC_VER)
19# pragma warning(disable: 4244) // conversion from enum_type to underlying_type
20#endif
21
22BOOST_SCOPED_ENUM_DECLARE_BEGIN(namespace_enum1)
23{
24 value0,
25 value1,
26 value2
27}
28BOOST_SCOPED_ENUM_DECLARE_END(namespace_enum1)
29
30BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(namespace_enum2, unsigned char)
31{
32 // Checks that enum value names do not clash
33 value0 = 10,
34 value1 = 20,
35 value2 = 30
36}
37BOOST_SCOPED_ENUM_DECLARE_END(namespace_enum2)
38
39struct my_struct
40{
41 // Checks that declarations are valid in class scope
42 BOOST_SCOPED_ENUM_DECLARE_BEGIN(color)
43 {
44 red,
45 green,
46 blue
47 }
48 BOOST_SCOPED_ENUM_DECLARE_END(color)
49
50 color m_color;
51
52 explicit my_struct(color col) : m_color(col)
53 {
54 }
55
56 color get_color() const
57 {
58 return m_color;
59 }
60};
61
62void check_operators()
63{
64 namespace_enum1 enum1 = namespace_enum1::value0;
65 BOOST_TEST(enum1 == namespace_enum1::value0);
66 BOOST_TEST(enum1 != namespace_enum1::value1);
67 BOOST_TEST(enum1 != namespace_enum1::value2);
68
69 enum1 = namespace_enum1::value1;
70 BOOST_TEST(enum1 != namespace_enum1::value0);
71 BOOST_TEST(enum1 == namespace_enum1::value1);
72 BOOST_TEST(enum1 != namespace_enum1::value2);
73
74 BOOST_TEST(!(enum1 < namespace_enum1::value0));
75 BOOST_TEST(!(enum1 <= namespace_enum1::value0));
76 BOOST_TEST(enum1 >= namespace_enum1::value0);
77 BOOST_TEST(enum1 > namespace_enum1::value0);
78
79 BOOST_TEST(!(enum1 < namespace_enum1::value1));
80 BOOST_TEST(enum1 <= namespace_enum1::value1);
81 BOOST_TEST(enum1 >= namespace_enum1::value1);
82 BOOST_TEST(!(enum1 > namespace_enum1::value1));
83
84 namespace_enum1 enum2 = namespace_enum1::value0;
85 BOOST_TEST(enum1 != enum2);
86
87 enum2 = enum1;
88 BOOST_TEST(enum1 == enum2);
89}
90
91void check_argument_passing()
92{
93 my_struct str(my_struct::color::green);
94 BOOST_TEST(str.get_color() == my_struct::color::green);
95}
96
97void check_switch_case()
98{
99 my_struct str(my_struct::color::blue);
100
101 switch (boost::native_value(e: str.get_color()))
102 {
103 case my_struct::color::blue:
104 break;
105 default:
106 BOOST_ERROR("Unexpected color value in switch/case");
107 }
108}
109
110template< typename T >
111struct my_trait
112{
113 enum _ { value = 0 };
114};
115
116template< >
117struct my_trait< BOOST_SCOPED_ENUM_NATIVE(namespace_enum2) >
118{
119 enum _ { value = 1 };
120};
121
122template< typename T >
123void native_type_helper(T)
124{
125 BOOST_TEST(my_trait< T >::value != 0);
126}
127
128void check_native_type()
129{
130 BOOST_TEST(my_trait< int >::value == 0);
131 BOOST_TEST(my_trait< BOOST_SCOPED_ENUM_NATIVE(namespace_enum2) >::value != 0);
132 BOOST_TEST(my_trait< boost::native_type< namespace_enum2 >::type >::value != 0);
133
134 namespace_enum2 enum1 = namespace_enum2::value0;
135 native_type_helper(boost::native_value(e: enum1));
136}
137
138void check_underlying_cast()
139{
140 namespace_enum2 enum1 = namespace_enum2::value1;
141 BOOST_TEST(boost::underlying_cast< unsigned char >(enum1) == 20);
142}
143
144void check_underlying_type()
145{
146 // The real check for the type is in the underlying_type trait test.
147 namespace_enum2 enum1 = namespace_enum2::value1;
148 BOOST_TEST(sizeof(enum1) == sizeof(unsigned char));
149 (void)enum1;
150}
151
152int main(int, char*[])
153{
154 check_operators();
155 check_argument_passing();
156 check_switch_case();
157 check_native_type();
158 check_underlying_cast();
159 check_underlying_type();
160
161 return boost::report_errors();
162}
163

source code of boost/libs/core/test/scoped_enum.cpp