mirror of
https://github.com/boostorg/core.git
synced 2025-05-10 07:13: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
|
inline
|
||||||
typename EnumType::enum_type native_value(EnumType e)
|
typename EnumType::enum_type native_value(EnumType e)
|
||||||
{
|
{
|
||||||
return e.native_value_();
|
return e.get_native_value_();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // BOOST_NO_CXX11_SCOPED_ENUMS
|
#else // BOOST_NO_CXX11_SCOPED_ENUMS
|
||||||
@ -126,7 +126,6 @@ namespace boost
|
|||||||
|
|
||||||
#define BOOST_SCOPED_ENUM_DECLARE_END2() \
|
#define BOOST_SCOPED_ENUM_DECLARE_END2() \
|
||||||
enum_type get_native_value_() const BOOST_NOEXCEPT { return enum_type(v_); } \
|
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, 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 ==(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_); } \
|
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 : : : <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 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