Fix etl::common_type decaying both arguments to T2 (#1529)

The two-type etl::common_type specialization recursed with
decay<T2> twice when either argument was not already decayed,
so etl::common_type_t<long&, int&> yielded int instead of long.
Recurse with decay<T1> and decay<T2>, matching the cppreference
sample implementation, and add regression tests comparing
against std::common_type for reference-type arguments.

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
rleigh-electradx 2026-08-04 19:04:19 +01:00 committed by GitHub
parent c8bc1bd896
commit 77079c8125
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 1 deletions

View File

@ -3724,7 +3724,7 @@ namespace etl
struct common_type<T1, T2> struct common_type<T1, T2>
: etl::conditional< etl::is_same<T1, typename etl::decay<T1>::type>::value && etl::is_same<T2, typename etl::decay<T2>::type>::value, : etl::conditional< etl::is_same<T1, typename etl::decay<T1>::type>::value && etl::is_same<T2, typename etl::decay<T2>::type>::value,
private_common_type::common_type_2_impl<T1, T2>, private_common_type::common_type_2_impl<T1, T2>,
common_type<typename etl::decay<T2>::type, typename etl::decay<T2>::type>>::type common_type<typename etl::decay<T1>::type, typename etl::decay<T2>::type>>::type
{ {
}; };

View File

@ -2268,5 +2268,23 @@ namespace
CHECK_TRUE(etl::is_unsigned<char32_t>::value); CHECK_TRUE(etl::is_unsigned<char32_t>::value);
#endif #endif
} }
#if ETL_USING_CPP11
//*************************************************************************
TEST(test_common_type)
{
// Reference types must decay to the same result as std::common_type.
CHECK((etl::is_same<etl::common_type_t<long&, int&>, long>::value));
CHECK((etl::is_same<etl::common_type_t<long&, int&>, std::common_type<long&, int&>::type>::value));
CHECK((etl::is_same<etl::common_type_t<int&, long&>, long>::value));
CHECK((etl::is_same<etl::common_type_t<int&, long&>, std::common_type<int&, long&>::type>::value));
CHECK((etl::is_same<etl::common_type_t<const char&, char&>, char>::value));
CHECK((etl::is_same<etl::common_type_t<const char&, char&>, std::common_type<const char&, char&>::type>::value));
// Already decayed types.
CHECK((etl::is_same<etl::common_type_t<int, long, int>, long>::value));
CHECK((etl::is_same<etl::common_type_t<int, long, int>, std::common_type<int, long, int>::type>::value));
}
#endif
} }
} // namespace } // namespace