Commit c7fc316f authored by Damien Lacoste's avatar Damien Lacoste
Browse files

Merge branch 'test_tango_type_traits' into 'main'

tests: add catch2_tango_type_traits

These add some tests for tango_type_traits, and specifically one to test for accepted enum type cause what we have is broken.

Close #1579 

And should be used to fix #1574

See merge request !1550
parents 511f5ee8 16862e89
Loading
Loading
Loading
Loading
Loading
+2 −24
Original line number Diff line number Diff line
@@ -9,33 +9,11 @@

#include <tango/client/DeviceAttribute.h>
#include <tango/common/tango_const.h>

#include <type_traits>
#include <tango/common/tango_type_traits.h>

namespace Tango
{

namespace detail
{

/// Type trait to judge if T is an enumeration usable as device attribute data
///
/// Example usage: `static_assert(detail::CheckEnumCompatibleType<T>::value, "Failing XYZ")`
template <typename T, typename Enable = void>
struct CheckEnumCompatibleType
{
    static constexpr bool value = std::false_type{};
};

template <typename T>
struct CheckEnumCompatibleType<T, std::enable_if_t<std::is_enum_v<T>>>
{
    using UT = std::underlying_type_t<T>;
    static constexpr bool value = std::is_same_v<DevShort, UT>;
};

} // namespace detail

//+-------------------------------------------------------------------------------------------------------------------
//
// method :
@@ -412,7 +390,7 @@ void DeviceAttribute::insert(std::vector<T> &_datum, int _x, int _y)
template <typename T>
void DeviceAttribute::template_type_check()
{
    static_assert(detail::CheckEnumCompatibleType<T>::value,
    static_assert(is_enum_compatible_v<T>,
                  "Type provided for insertion is not a valid enum."
                  " Only C enum or C++11 enum class with "
                  "underlying Tango::DevShort data type is supported.");
+18 −0
Original line number Diff line number Diff line
@@ -649,5 +649,23 @@ constexpr bool is_tango_base_type_v = is_tango_base_type<T>::value;
template <class T>
using is_tango_base_type_t = typename is_tango_base_type<T>::type;

/// Type trait to judge if T is an enumeration usable as device attribute data
///
/// Example usage: `static_assert(is_enum_compatible_v<T>, "Failing XYZ")`
template <typename T, typename Enable = void>
struct is_enum_compatible : std::false_type
{
};

template <typename T>
struct is_enum_compatible<T, std::enable_if_t<std::is_enum_v<T>>>
{
    using UT = std::underlying_type_t<T>;
    static constexpr bool value = std::is_same_v<DevShort, UT> || std::is_convertible_v<T, UT>;
};

template <typename T>
constexpr bool is_enum_compatible_v = is_enum_compatible<T>::value;

} // namespace Tango
#endif /* TANGO_TYPE_TRAITS_H */
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ tango_catch2_tests_create(
    catch2_loggerstream_attribute.cpp
    catch2_device_proxy.cpp
    catch2_log4tango.cpp
    catch2_tango_type_traits.cpp
    $<$<AND:$<NOT:$<CXX_COMPILER_ID:MSVC>>,$<STREQUAL:$<TARGET_PROPERTY:tango,TYPE>,SHARED_LIBRARY>>:catch2_create_cpp_class.cpp>
    $<$<BOOL:${TANGO_USE_TELEMETRY}>:${CMAKE_CURRENT_SOURCE_DIR}/catch2_unit_test_telemetry_current_function.cpp>
    )
+57 −0
Original line number Diff line number Diff line
/*
 * SPDX-FileCopyrightText: 2024 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */
#include "catch2_common.h"

namespace details
{
enum C_type
{
    ENUM_1,
    ENUM_2,
    ENUM_3
};

enum class scoped_enum : Tango::DevShort
{
    ENUM_1,
    ENUM_2,
    ENUM_3
};

enum class scoped_enum_int : unsigned int
{
    ENUM_1,
    ENUM_2,
    ENUM_3
};
} // namespace details

//
// Tests -------------------------------------------------------
//
SCENARIO("Static test tango_type_traits is_tango_base_type")
{
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevBoolean>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevUChar>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevShort>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevUShort>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevLong>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevULong>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevLong64>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevULong64>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevFloat>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevDouble>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevState>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevEncoded>);
    STATIC_REQUIRE(Tango::is_tango_base_type_v<Tango::DevString>);
}

SCENARIO("Static test tango_type_traits is_enum_compatible")
{
    STATIC_REQUIRE(Tango::is_enum_compatible_v<details::C_type>);
    STATIC_REQUIRE(Tango::is_enum_compatible_v<details::scoped_enum>);
    STATIC_REQUIRE_FALSE(Tango::is_enum_compatible_v<details::scoped_enum_int>);
}