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