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