Skip to content

Commit

Permalink
Added etl::count_of, etl::has_duplicates, etl::has_duplicates_of
Browse files Browse the repository at this point in the history
  • Loading branch information
John Wellbelove committed Aug 2, 2024
1 parent c61f493 commit f219e86
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 8 deletions.
60 changes: 56 additions & 4 deletions include/etl/generators/type_traits_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2296,16 +2296,68 @@ typedef integral_constant<bool, true> true_type;
using signed_type_t = typename signed_type<T>::type;
#endif

//*********************************************
// type_identity
//*********************************************
// type_identity

template <typename T>
struct type_identity { typedef T type; };
template <typename T>
struct type_identity { typedef T type; };

#if ETL_USING_CPP11
template <typename T>
using type_identity_t = typename type_identity<T>::type;
#endif

#if ETL_USING_CPP11
//*********************************************
// has_duplicates
template <typename... TTypes>
struct has_duplicates;

template <typename TFirst, typename... TRest>
struct has_duplicates<TFirst, TRest...> : etl::conditional_t<etl::is_one_of<TFirst, TRest...>::value,
etl::true_type,
has_duplicates<TRest...>> {};

template <>
struct has_duplicates<> : etl::false_type {};
#endif

#if ETL_USING_CPP17
template <typename... TTypes>
inline constexpr bool has_duplicates_v = etl::has_duplicates<TTypes...>::value;
#endif

#if ETL_USING_CPP11
//*********************************************
// count_of
template <typename T, typename... TTypes>
struct count_of;

template <typename T, typename U, typename... URest>
struct count_of<T, U, URest...> : etl::integral_constant<size_t,
etl::is_same<T, U>::value +
count_of<T, URest...>::value> {};

template <typename T>
struct count_of<T> : etl::integral_constant<size_t, 0> {};
#endif

#if ETL_USING_CPP17
template <typename T, typename... TTypes>
inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
#endif

#if ETL_USING_CPP11
//*********************************************
// has_duplicates_of
template <typename T, typename... TTypes>
struct has_duplicates_of : etl::bool_constant<(etl::count_of<T, TTypes...>::value > 1U)> {};
#endif

#if ETL_USING_CPP17
template <typename T, typename... TTypes>
inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TTypes...>::value;
#endif
}

// Helper macros
Expand Down
60 changes: 56 additions & 4 deletions include/etl/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -2289,16 +2289,68 @@ typedef integral_constant<bool, true> true_type;
using signed_type_t = typename signed_type<T>::type;
#endif

//*********************************************
// type_identity
//*********************************************
// type_identity

template <typename T>
struct type_identity { typedef T type; };
template <typename T>
struct type_identity { typedef T type; };

#if ETL_USING_CPP11
template <typename T>
using type_identity_t = typename type_identity<T>::type;
#endif

#if ETL_USING_CPP11
//*********************************************
// has_duplicates
template <typename... TTypes>
struct has_duplicates;

template <typename TFirst, typename... TRest>
struct has_duplicates<TFirst, TRest...> : etl::conditional_t<etl::is_one_of<TFirst, TRest...>::value,
etl::true_type,
has_duplicates<TRest...>> {};

template <>
struct has_duplicates<> : etl::false_type {};
#endif

#if ETL_USING_CPP17
template <typename... TTypes>
inline constexpr bool has_duplicates_v = etl::has_duplicates<TTypes...>::value;
#endif

#if ETL_USING_CPP11
//*********************************************
// count_of
template <typename T, typename... TTypes>
struct count_of;

template <typename T, typename U, typename... URest>
struct count_of<T, U, URest...> : etl::integral_constant<size_t,
etl::is_same<T, U>::value +
count_of<T, URest...>::value> {};

template <typename T>
struct count_of<T> : etl::integral_constant<size_t, 0> {};
#endif

#if ETL_USING_CPP17
template <typename T, typename... TTypes>
inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
#endif

#if ETL_USING_CPP11
//*********************************************
// has_duplicates_of
template <typename T, typename... TTypes>
struct has_duplicates_of : etl::bool_constant<(etl::count_of<T, TTypes...>::value > 1U)> {};
#endif

#if ETL_USING_CPP17
template <typename T, typename... TTypes>
inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TTypes...>::value;
#endif
}

// Helper macros
Expand Down
46 changes: 46 additions & 0 deletions test/test_type_traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,4 +1333,50 @@ namespace
{
CHECK_CLOSE(type_identity_test_add(1.5f, 2), 3.5f, 0.01f);
}

//*************************************************************************
TEST(test_has_duplicates)
{
#if ETL_USING_CPP17
CHECK_FALSE((etl::has_duplicates_v<char>));
CHECK_FALSE((etl::has_duplicates_v<char, int, double>));
CHECK_TRUE((etl::has_duplicates_v<char, int, char>));
#else
CHECK_FALSE((etl::has_duplicates<char>::value));
CHECK_FALSE((etl::has_duplicates<char, int, double>::value));
CHECK_TRUE((etl::has_duplicates<char, int, char>::value));
#endif
}

//*************************************************************************
TEST(test_has_duplicates_of)
{
#if ETL_USING_CPP17
CHECK_FALSE((etl::has_duplicates_of_v<char>));
CHECK_TRUE((etl::has_duplicates_of_v<char, char, int, char>)); // char is duplicated.
CHECK_FALSE((etl::has_duplicates_of_v<int, char, int, char>)); // int is not duplicated.
#else
CHECK_FALSE((etl::has_duplicates_of<char>::value));
CHECK_TRUE((etl::has_duplicates_of<char, char, int, char>::value)); // char is duplicated.
CHECK_FALSE((etl::has_duplicates_of<int, char, int, char>::value)); // int is not duplicated.
#endif
}

//*************************************************************************
TEST(test_count_of)
{
#if ETL_USING_CPP17
CHECK_EQUAL(0, (etl::count_of_v<char>));
CHECK_EQUAL(0, (etl::count_of_v<char, int>));
CHECK_EQUAL(1, (etl::count_of_v<char, char>));
CHECK_EQUAL(1, (etl::count_of_v<char, int, char>));
CHECK_EQUAL(2, (etl::count_of_v<char, int, char, double, char>));
#else
CHECK_EQUAL(0, (etl::count_of<char>::value));
CHECK_EQUAL(0, (etl::count_of<char, int>::value));
CHECK_EQUAL(1, (etl::count_of<char, char>::value));
CHECK_EQUAL(1, (etl::count_of<char, int, char>::value));
CHECK_EQUAL(2, (etl::count_of<char, int, char, double, char>::value));
#endif
}
}

0 comments on commit f219e86

Please sign in to comment.