mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-17 17:36:33 +08:00
Fold expression experiment
This commit is contained in:
parent
f4060bc9ea
commit
67c19bb0dc
@ -7,7 +7,7 @@ Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
Copyright(c) 2021 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
@ -43,11 +43,56 @@ SOFTWARE.
|
||||
#include "../parameter_pack.h"
|
||||
#include "../placement_new.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#if defined(ETL_COMPILER_KEIL)
|
||||
#pragma diag_suppress 940
|
||||
#pragma diag_suppress 111
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//template <typename T, T... Integers>
|
||||
//class integer_sequence
|
||||
//{
|
||||
//public:
|
||||
//
|
||||
// ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
|
||||
|
||||
// typedef T value_type;
|
||||
//
|
||||
// static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
|
||||
// {
|
||||
// return sizeof...(Integers);
|
||||
// }
|
||||
//};
|
||||
|
||||
//namespace private_integer_sequence
|
||||
//{
|
||||
// template <size_t N, typename IndexSeq>
|
||||
// struct make_index_sequence;
|
||||
|
||||
// template <size_t N, size_t... Indices>
|
||||
// struct make_index_sequence<N, integer_sequence<size_t, Indices...>>
|
||||
// {
|
||||
// typedef typename make_index_sequence<N - 1, integer_sequence<size_t, N - 1, Indices...>>::type type;
|
||||
// };
|
||||
|
||||
// template <size_t... Indices>
|
||||
// struct make_index_sequence<0, integer_sequence<size_t, Indices...>>
|
||||
// {
|
||||
// typedef integer_sequence<size_t, Indices...> type;
|
||||
// };
|
||||
//}
|
||||
|
||||
//template <size_t N>
|
||||
//using make_index_sequence = typename private_integer_sequence::make_index_sequence<N, integer_sequence<size_t>>::type;
|
||||
|
||||
//template <size_t... Indices>
|
||||
//using index_sequence = integer_sequence<size_t, Indices...>;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
///\defgroup variant variant
|
||||
/// A class that can contain one a several specified types in a type safe manner.
|
||||
@ -68,6 +113,13 @@ namespace etl
|
||||
{
|
||||
};
|
||||
|
||||
constexpr bool operator >(etl::monostate, etl::monostate) noexcept { return false; }
|
||||
constexpr bool operator <(etl::monostate, etl::monostate) noexcept { return false; }
|
||||
constexpr bool operator !=(etl::monostate, etl::monostate) noexcept { return false; }
|
||||
constexpr bool operator <=(etl::monostate, etl::monostate) noexcept { return true; }
|
||||
constexpr bool operator >=(etl::monostate, etl::monostate) noexcept { return true; }
|
||||
constexpr bool operator ==(etl::monostate, etl::monostate) noexcept { return true; }
|
||||
|
||||
//***************************************************************************
|
||||
/// Base exception for the variant class.
|
||||
///\ingroup variant
|
||||
@ -207,11 +259,11 @@ namespace etl
|
||||
{
|
||||
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
|
||||
|
||||
T temp(etl::forward<TArgs>(args)...);
|
||||
|
||||
operation(action_type::Destruct, data, nullptr);
|
||||
|
||||
operation = do_operation<T>;
|
||||
|
||||
T temp(etl::forward<TArgs>(args)...);
|
||||
operation(action_type::Construct, data, &temp);
|
||||
|
||||
type_id = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
@ -312,6 +364,15 @@ namespace etl
|
||||
return static_cast<const T&>(data);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Do an operation determined by type.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor>
|
||||
void accept(TVisitor& visitor)
|
||||
{
|
||||
do_accept(visitor, std::make_index_sequence<sizeof...(TTypes)>{});
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
using operation_type = void(*)(action_type, void*, const void*);
|
||||
@ -343,6 +404,32 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Loop through the types until a match is found.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor, size_t... I>
|
||||
void do_accept(TVisitor& visitor, std::index_sequence<I...>)
|
||||
{
|
||||
(attempt_visitor<I>(visitor) || ...);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Attempt to call a visitor.
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename TVisitor>
|
||||
bool attempt_visitor(TVisitor& visitor)
|
||||
{
|
||||
if (Index == index())
|
||||
{
|
||||
visitor.visit(etl::get<Index>(*this));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Default operation.
|
||||
//***************************************************************************
|
||||
@ -401,7 +488,7 @@ namespace etl
|
||||
constexpr etl::variant_alternative_t<Index, etl::variant<TTypes...>>&
|
||||
get(etl::variant<TTypes...>& v)
|
||||
{
|
||||
static_assert(Index < sizeof...(TTypes), "Index out of range");
|
||||
//static_assert(Index < sizeof...(TTypes), "Index out of range");
|
||||
ETL_ASSERT(Index == v.index(), ETL_ERROR(etl::variant_incorrect_type_exception));
|
||||
|
||||
using type = etl::variant_alternative_t<Index, etl::variant<TTypes...>>;
|
||||
@ -559,5 +646,4 @@ namespace etl
|
||||
: etl::integral_constant<size_t, variant_size<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
Copyright(c) 2021 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
@ -29,6 +29,7 @@ SOFTWARE.
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/private/variant_new.h"
|
||||
#include "etl/visitor.h"
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
@ -395,5 +396,40 @@ namespace
|
||||
|
||||
D1 db = etl::move(etl::get<D1>(variant));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_variant_visitor)
|
||||
{
|
||||
struct Visitor : public etl::visitor<char, int, std::string>
|
||||
{
|
||||
void visit(char& c)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void visit(int& i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void visit(std::string& s)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
Visitor visitor;
|
||||
|
||||
test_variant_3 variant;
|
||||
|
||||
variant = char(1);
|
||||
variant.accept(visitor);
|
||||
|
||||
variant = int(2);
|
||||
variant.accept(visitor);
|
||||
|
||||
variant = std::string("3");
|
||||
variant.accept(visitor);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user