mirror of
https://github.com/boostorg/core.git
synced 2025-05-09 23:03:54 +00:00
Added tests for scoped enums and underlying_type. Fixed a bug with native_value(). Fixed a bug that allowed implicit conversions of scoped enums to int (at least with clang 3.4).
This commit is contained in:
parent
2b18ddfbce
commit
f930ce31cf
@ -63,7 +63,7 @@ namespace boost
|
||||
inline
|
||||
typename EnumType::enum_type native_value(EnumType e)
|
||||
{
|
||||
return e.native_value_();
|
||||
return e.get_native_value_();
|
||||
}
|
||||
|
||||
#else // BOOST_NO_CXX11_SCOPED_ENUMS
|
||||
@ -126,7 +126,6 @@ namespace boost
|
||||
|
||||
#define BOOST_SCOPED_ENUM_DECLARE_END2() \
|
||||
enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \
|
||||
operator enum_type() const BOOST_NOEXCEPT { return get_native_value_(); } \
|
||||
friend bool operator ==(self_type lhs, self_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \
|
||||
friend bool operator ==(self_type lhs, enum_type rhs) BOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \
|
||||
friend bool operator ==(enum_type lhs, self_type rhs) BOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \
|
||||
|
@ -75,3 +75,9 @@ run demangle_test.cpp : : : <test-info>always_show_run_output ;
|
||||
|
||||
run demangled_name_test.cpp : : : <test-info>always_show_run_output ;
|
||||
run demangled_name_test.cpp : : : <rtti>off <test-info>always_show_run_output : demangled_name_test_no_rtti ;
|
||||
|
||||
run scoped_enum.cpp ;
|
||||
compile-fail scoped_enum_compile_fail_conv_from_int.cpp ;
|
||||
compile-fail scoped_enum_compile_fail_conv_to_int.cpp ;
|
||||
|
||||
run underlying_type.cpp ;
|
||||
|
157
test/scoped_enum.cpp
Normal file
157
test/scoped_enum.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
30
test/scoped_enum_compile_fail_conv_from_int.cpp
Normal file
30
test/scoped_enum_compile_fail_conv_from_int.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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_compile_fail_conv_from_int.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.06.2014
|
||||
*
|
||||
* \brief This test checks that scoped enum emulation prohibits implicit conversions from int
|
||||
*/
|
||||
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(color)
|
||||
{
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(color)
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
color col = 2;
|
||||
|
||||
return boost::native_value(col);
|
||||
}
|
31
test/scoped_enum_compile_fail_conv_to_int.cpp
Normal file
31
test/scoped_enum_compile_fail_conv_to_int.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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_compile_fail_conv_to_int.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.06.2014
|
||||
*
|
||||
* \brief This test checks that scoped enum emulation prohibits implicit conversions to int
|
||||
*/
|
||||
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
|
||||
BOOST_SCOPED_ENUM_DECLARE_BEGIN(color)
|
||||
{
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(color)
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
color col = color::red;
|
||||
int n = col;
|
||||
|
||||
return n;
|
||||
}
|
68
test/underlying_type.cpp
Normal file
68
test/underlying_type.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 underlying_type.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.06.2014
|
||||
*
|
||||
* \brief This test checks that underlying_type trait works.
|
||||
*/
|
||||
|
||||
#include <boost/core/underlying_type.hpp>
|
||||
#include <boost/core/scoped_enum.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <boost/core/is_same.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(emulated_enum, unsigned char)
|
||||
{
|
||||
value0,
|
||||
value1,
|
||||
value2
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(emulated_enum)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
|
||||
enum class native_enum : unsigned short
|
||||
{
|
||||
value0,
|
||||
value1,
|
||||
value2
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_UNDERLYING_TYPE)
|
||||
namespace boost {
|
||||
|
||||
template< >
|
||||
struct underlying_type< emulated_enum >
|
||||
{
|
||||
typedef unsigned char type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
template< >
|
||||
struct underlying_type< native_enum >
|
||||
{
|
||||
typedef unsigned short type;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
#endif
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((boost::core::is_same< boost::underlying_type< emulated_enum >::type, unsigned char >));
|
||||
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
BOOST_TEST_TRAIT_TRUE((boost::core::is_same< boost::underlying_type< native_enum >::type, unsigned short >));
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user