Interim changes after PR

This commit is contained in:
John Wellbelove 2022-06-10 11:18:48 +01:00
parent 89be7e62cf
commit dd89f1c748
5 changed files with 80 additions and 36 deletions

View File

@ -98,10 +98,11 @@ namespace etl
/// 'Bad variant access' exception for the variant class.
///\ingroup variant
//***************************************************************************
class bad_variant_access : public variant_exception {
class bad_variant_access : public variant_exception
{
public:
bad_variant_access(string_type file_name_, numeric_type line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"B"), file_name_, line_number_)
{}
};
@ -1073,18 +1074,18 @@ namespace etl
{
template <size_t, typename>
struct variant_alternative_helper;
#define ETL_VARIANT_HELPER(INDEX, TYPE) \
template <typename T1, \
typename T2, \
typename T3, \
typename T4, \
typename T5, \
typename T6, \
typename T7, \
typename T8> \
struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8>> \
{ \
typedef TYPE type; \
#define ETL_VARIANT_HELPER(INDEX, TYPE) \
template <typename T1, \
typename T2, \
typename T3, \
typename T4, \
typename T5, \
typename T6, \
typename T7, \
typename T8> \
struct variant_alternative_helper<INDEX, variant<T1, T2, T3, T4, T5, T6, T7, T8> > \
{ \
typedef TYPE type; \
};
ETL_VARIANT_HELPER(0, T1)
ETL_VARIANT_HELPER(1, T2)
@ -1096,41 +1097,49 @@ namespace etl
ETL_VARIANT_HELPER(7, T8)
#undef ETL_VARIANT_HELPER
} // namespace private_variant
template <size_t tIndex, typename TVariant>
struct variant_alternative
{
typedef typename private_variant::variant_alternative_helper<tIndex, TVariant>::type type;
};
template <size_t tIndex, typename TVariant>
struct variant_alternative<tIndex, TVariant const>
{
typedef typename private_variant::variant_alternative_helper<tIndex, TVariant>::type const type;
};
template <size_t tIndex, typename TVariant>
struct variant_alternative<tIndex, TVariant volatile>
{
typedef typename private_variant::variant_alternative_helper<tIndex, TVariant>::type volatile type;
};
template <size_t tIndex, typename TVariant>
struct variant_alternative<tIndex, TVariant const volatile>
{
typedef typename private_variant::variant_alternative_helper<tIndex, TVariant>::type const volatile type;
};
template <typename T, typename TVariant>
inline T& get(TVariant& variant)
{
return variant.template get<T>();
}
template <typename T, typename TVariant>
inline T const& get(TVariant const& variant)
{
return variant.template get<T>();
}
template <size_t tIndex, typename TVariant>
inline typename variant_alternative<tIndex, TVariant>::type& get(TVariant& variant)
{
return get<typename variant_alternative<tIndex, TVariant>::type>(variant);
}
template <size_t tIndex, typename TVariant>
inline typename variant_alternative<tIndex, TVariant const>::type& get(TVariant const& variant)
{
@ -1143,15 +1152,15 @@ namespace etl
{ \
switch (variant.index()) \
{ \
case 0: return static_cast<TRet>(visitor(get<0>(variant))); \
case 1: return static_cast<TRet>(visitor(get<1>(variant))); \
case 2: return static_cast<TRet>(visitor(get<2>(variant))); \
case 3: return static_cast<TRet>(visitor(get<3>(variant))); \
case 4: return static_cast<TRet>(visitor(get<4>(variant))); \
case 5: return static_cast<TRet>(visitor(get<5>(variant))); \
case 6: return static_cast<TRet>(visitor(get<6>(variant))); \
case 7: return static_cast<TRet>(visitor(get<7>(variant))); \
default: ETL_ASSERT(false, ETL_ERROR(bad_variant_access)); \
case 0: return static_cast<TRet>(visitor(get<0>(variant))); \
case 1: return static_cast<TRet>(visitor(get<1>(variant))); \
case 2: return static_cast<TRet>(visitor(get<2>(variant))); \
case 3: return static_cast<TRet>(visitor(get<3>(variant))); \
case 4: return static_cast<TRet>(visitor(get<4>(variant))); \
case 5: return static_cast<TRet>(visitor(get<5>(variant))); \
case 6: return static_cast<TRet>(visitor(get<6>(variant))); \
case 7: return static_cast<TRet>(visitor(get<7>(variant))); \
default: ETL_ASSERT(false, ETL_ERROR(bad_variant_access)); \
} \
}

View File

@ -430,10 +430,11 @@ namespace etl
/// 'Bad variant access' exception for the variant class.
///\ingroup variant
//***************************************************************************
class bad_variant_access : public variant_exception {
class bad_variant_access : public variant_exception
{
public:
bad_variant_access(string_type file_name_, numeric_type line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"A"), file_name_, line_number_)
: variant_exception(ETL_ERROR_TEXT("variant:bad variant access", ETL_VARIANT_FILE_ID"B"), file_name_, line_number_)
{}
};
@ -1289,8 +1290,9 @@ namespace etl
template <typename TCallable, typename... Ts>
struct single_visit_result_type
{
using type = decltype(std::declval<TCallable>()(std::declval<Ts>()...));
using type = decltype(etl::declval<TCallable>()(etl::declval<Ts>()...));
};
template <typename TCallable, typename... Ts>
using single_visit_result_type_t = typename single_visit_result_type<TCallable, Ts...>::type;
@ -1311,6 +1313,7 @@ namespace etl
//***************************************************************************
template <template <typename...> typename, typename...>
struct visit_result_helper;
template <template <typename...> typename TToInject, size_t... tAltIndices, typename TCur>
struct visit_result_helper<TToInject, index_sequence<tAltIndices...>, TCur>
{
@ -1320,6 +1323,7 @@ namespace etl
using type = common_type_t<TToInject<var_type<tAltIndices> >...>;
};
template <template <typename...> typename TToInject, size_t... tAltIndices, typename TCur, typename TNext, typename... TVs>
struct visit_result_helper<TToInject, index_sequence<tAltIndices...>, TCur, TNext, TVs...>
{
@ -1333,6 +1337,7 @@ namespace etl
using next_inject = TToInject<var_type<tIndex>, TNextInj...>;
using recursive_result = typename visit_result_helper<next_inject, make_index_sequence<variant_size<remove_reference_t<TNext> >::value>, TNext, TVs...>::type;
};
using type = common_type_t<typename next_inject_wrap<tAltIndices>::recursive_result...>;
};
@ -1363,7 +1368,7 @@ namespace etl
template <typename TRet, typename TCallable, typename TVariant, size_t tIndex>
constexpr TRet do_visit_single(TCallable&& f, TVariant&& v)
{
return static_cast<TCallable&&>(f)(etl::get<tIndex>(static_cast<TVariant&&>(v)));
return static_cast<TCallable&&>(f)(etl::get<tIndex>(etl::forward<TVariant>(v)));
}
//***************************************************************************
@ -1376,6 +1381,7 @@ namespace etl
{
using function_pointer = add_pointer_t<TRet(TCallable&&, TCurVariant&&, TVarRest&&...)>;
template <size_t tIndex>
static constexpr function_pointer fptr() noexcept
{
return &do_visit_single<TRet, TCallable, TCurVariant, tIndex, TVarRest...>;
@ -1389,10 +1395,15 @@ namespace etl
ETL_CONSTEXPR14 static TRet do_visit(TCallable&& f, TVariant&& v, index_sequence<tIndices...>, TVarRest&&... variants)
{
ETL_ASSERT(!v.valueless_by_exception(), ETL_ERROR(bad_variant_access));
using helper_t = do_visit_helper<TRet, TCallable, TVariant, TVarRest...>;
using func_ptr = typename helper_t::function_pointer;
constexpr func_ptr jmp_table[]{
helper_t::template fptr<tIndices>()...};
constexpr func_ptr jmp_table[]
{
helper_t::template fptr<tIndices>()...
};
return jmp_table[v.index()](static_cast<TCallable&&>(f), static_cast<TVariant&&>(v), static_cast<TVarRest&&>(variants)...);
}
@ -1400,6 +1411,7 @@ namespace etl
ETL_CONSTEXPR14 static TRet visit(TCallable&& f, TVariant&& v, TVs&&... vs)
{
constexpr size_t variants = etl::variant_size<typename remove_reference<TVariant>::type>::value;
return private_variant::do_visit<TRet>(static_cast<TCallable&&>(f),
static_cast<TVariant&&>(v),
make_index_sequence<variants>{},
@ -1417,6 +1429,7 @@ namespace etl
add_pointer_t<TVariant> variant_;
public:
constexpr constexpr_visit_closure(TCallable&& c, TVariant&& v)
: callable_(&c), variant_(&v)
{

View File

@ -65,6 +65,7 @@ namespace etl
template <typename T>
constexpr T&& forward(typename etl::remove_reference<T>::type&& t) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(!etl::is_lvalue_reference<T>::value, "Invalid rvalue to lvalue conversion");
return static_cast<T&&>(t);
}
#endif

View File

@ -834,7 +834,7 @@ namespace
//*************************************************************************
TEST(test_variant__accept_functor_with_overload)
TEST(test_variant_accept_functor_with_overload)
{
char result_c;
int result_i;
@ -1168,7 +1168,7 @@ namespace
CHECK(pcd == nullptr);
}
//*************************************************************************
struct variant_test_visit_dispatcher
{
// const overloads
@ -1176,22 +1176,27 @@ namespace
{
return 1;
}
int8_t operator()(int8_t const&) const
{
return 10;
}
int8_t operator()(uint8_t&) const
{
return 2;
}
int8_t operator()(uint8_t const&) const
{
return 20;
}
int8_t operator()(int16_t&) const
{
return 3;
}
int8_t operator()(int16_t const&) const
{
return 30;
@ -1202,22 +1207,27 @@ namespace
{
return 5;
}
int8_t operator()(int8_t const&)
{
return 50;
}
int8_t operator()(uint8_t&)
{
return 6;
}
int8_t operator()(uint8_t const&)
{
return 60;
}
int8_t operator()(int16_t&)
{
return 7;
}
int8_t operator()(int16_t const&)
{
return 70;
@ -1229,7 +1239,7 @@ namespace
return -1;
}
};
//*************************************************************************
TEST(test_variant_visit)
{
etl::variant<int8_t, uint8_t, int16_t> variant;
@ -1238,6 +1248,7 @@ namespace
auto const& visitor_const = visitor;
int16_t type = etl::visit(visitor_const, variant);
CHECK_EQUAL(1, type);
auto const& variant_const = variant;
type = etl::visit(visitor_const, variant_const);
CHECK_EQUAL(10, type);
@ -1256,12 +1267,14 @@ namespace
CHECK_EQUAL(70, type);
}
//*************************************************************************
struct test_variant_multiple_visit_helper
{
template <typename T1, typename T2>
int16_t operator()(T1 v1, T2 v2) const
{
int16_t res{};
if (std::is_same<T1, int8_t>::value)
res = 1;
else if (std::is_same<T1, uint8_t>::value)
@ -1275,23 +1288,27 @@ namespace
return res - static_cast<int16_t>(v1) * static_cast<int16_t>(v2);
}
};
//*************************************************************************
TEST(test_variant_multiple_visit)
{
etl::variant<int8_t, uint8_t> variant1;
etl::variant<int8_t, uint16_t, uint8_t> variant2;
variant1 = int8_t{3};
variant2 = int8_t{1};
auto res = etl::visit<int16_t>(test_variant_multiple_visit_helper{}, variant1, variant2);
CHECK_EQUAL(11 - 3, res);
variant2 = uint16_t{2};
res = etl::visit<int16_t>(test_variant_multiple_visit_helper{}, variant1, variant2);
CHECK_EQUAL(21 - 3 * 2, res);
variant1 = uint8_t{};
variant2 = uint8_t{};
res = etl::visit<int16_t>(test_variant_multiple_visit_helper{}, variant1, variant2);
CHECK_EQUAL(32, res);
}
//*************************************************************************
TEST(test_variant_multiple_visit_auto_return)
{
@ -1303,8 +1320,10 @@ namespace
{
return v1 * v2;
};
auto res = etl::visit(f, variant1, variant2);
CHECK_EQUAL(3, res);
variant2 = uint16_t{2};
res = etl::visit(f, variant1, variant2);
CHECK_EQUAL(3 * 2, res);
@ -1319,8 +1338,10 @@ namespace
{
variant_was_signed = etl::is_signed<etl::remove_reference_t<decltype(v)>>::value;
};
etl::visit(f, variant1);
CHECK_EQUAL(true, variant_was_signed);
variant1 = uint8_t{};
etl::visit<void>(f, variant1);
CHECK_EQUAL(false, variant_was_signed);

View File

@ -1832,9 +1832,6 @@
<ClCompile Include="..\test_variance.cpp">
<Filter>Tests\Algorithms</Filter>
</ClCompile>
<ClCompile Include="..\test_variant_legacy.cpp">
<Filter>Tests\Algorithms</Filter>
</ClCompile>
<ClCompile Include="..\test_binary.cpp">
<Filter>Tests\Binary</Filter>
</ClCompile>
@ -3254,6 +3251,9 @@
<ClCompile Include="..\sanity-check\delegate_cpp03.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_variant_legacy.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">