mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 22:59:47 +08:00
Interim changes after PR
This commit is contained in:
parent
89be7e62cf
commit
dd89f1c748
@ -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)); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user