core/test/scoped_enum.cpp

158 lines
3.7 KiB
C++

/*
* 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>
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));
}
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();
}