mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-15 08:26:04 +08:00
Latest updates
This commit is contained in:
parent
dddeb3471f
commit
2025e6ff9b
85
include/etl/overload.h
Normal file
85
include/etl/overload.h
Normal file
@ -0,0 +1,85 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_OVERLOAD_INCLUDED
|
||||
#define ETL_OVERLOAD_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
#if ETL_CPP11_SUPPORTED
|
||||
#if ETL_CPP17_SUPPORTED && !defined(ETL_OVERLOAD_FORCE_CPP11)
|
||||
//*************************************************************************
|
||||
/// Variadic template definition of overload.
|
||||
//*************************************************************************
|
||||
template<class... Ts>
|
||||
struct overload : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Template deduction guide.
|
||||
//*************************************************************************
|
||||
template<class... Ts> overload(Ts...)->overload<Ts...>;
|
||||
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Variadic template definition of overload.
|
||||
//*************************************************************************
|
||||
template <typename T, typename... Ts>
|
||||
struct overload : T, overload<Ts...>
|
||||
{
|
||||
using T::operator();
|
||||
using overload<Ts...>::operator();
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Template specialisation of overload for one type.
|
||||
//*************************************************************************
|
||||
template <typename T> struct overload<T> : T
|
||||
{
|
||||
using T::operator();
|
||||
};
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Make an overload.
|
||||
//*************************************************************************
|
||||
template <typename... T>
|
||||
constexpr auto make_overload(T&&... t)
|
||||
{
|
||||
return overload<T...>{ etl::forward<T>(t)... };
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -42,6 +42,7 @@ SOFTWARE.
|
||||
#include "../error_handler.h"
|
||||
#include "../parameter_pack.h"
|
||||
#include "../placement_new.h"
|
||||
#include "../visitor.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@ -205,7 +206,7 @@ namespace etl
|
||||
constexpr variant()
|
||||
: data()
|
||||
{
|
||||
using type = typename etl::parameter_pack<TTypes...>::type_from_index<0>::type;
|
||||
using type = typename etl::parameter_pack<TTypes...>::template type_from_index<0>::type;
|
||||
|
||||
type temp;
|
||||
|
||||
@ -221,7 +222,7 @@ namespace etl
|
||||
constexpr variant(const T& value)
|
||||
: data()
|
||||
, operation(do_operation<T>)
|
||||
, type_id(etl::parameter_pack<TTypes...>::index_of_type<T>::value)
|
||||
, type_id(etl::parameter_pack<TTypes...>::template index_of_type<T>::value)
|
||||
{
|
||||
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
|
||||
|
||||
@ -266,7 +267,7 @@ namespace etl
|
||||
T temp(etl::forward<TArgs>(args)...);
|
||||
operation(action_type::Construct, data, &temp);
|
||||
|
||||
type_id = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
type_id = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
@ -285,7 +286,7 @@ namespace etl
|
||||
operation = do_operation<T>;
|
||||
operation(action_type::Construct, data, &value);
|
||||
|
||||
type_id = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
type_id = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -365,12 +366,21 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Do an operation determined by type.
|
||||
/// Accept an etl::visitor.
|
||||
//***************************************************************************
|
||||
template <typename... Types>
|
||||
void accept(etl::visitor<TTypes...>& v)
|
||||
{
|
||||
do_accept(v, std::make_index_sequence<sizeof...(TTypes)>{});
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Accept a generic visitor.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor>
|
||||
void accept(TVisitor& visitor)
|
||||
void operator()(TVisitor& v)
|
||||
{
|
||||
do_accept(visitor, std::make_index_sequence<sizeof...(TTypes)>{});
|
||||
do_operator(v, std::make_index_sequence<sizeof...(TTypes)>{});
|
||||
}
|
||||
|
||||
private:
|
||||
@ -430,6 +440,32 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Loop through the types until a match is found.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor, size_t... I>
|
||||
void do_operator(TVisitor& visitor, std::index_sequence<I...>)
|
||||
{
|
||||
(attempt_operator<I>(visitor) || ...);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Attempt to call a visitor.
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename TVisitor>
|
||||
bool attempt_operator(TVisitor& visitor)
|
||||
{
|
||||
if (Index == index())
|
||||
{
|
||||
visitor(etl::get<Index>(*this));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Default operation.
|
||||
//***************************************************************************
|
||||
@ -455,7 +491,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
constexpr bool holds_alternative(const etl::variant<TTypes...>& v) noexcept
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return (Index == variant_npos) ? false : (v.index() == Index);
|
||||
}
|
||||
@ -538,7 +574,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
constexpr T& get(etl::variant<TTypes...>& v)
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return get<Index>(v);
|
||||
}
|
||||
@ -547,7 +583,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
constexpr T&& get(etl::variant<TTypes...>&& v)
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return get<Index>(v);
|
||||
}
|
||||
@ -556,7 +592,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
constexpr const T& get(const etl::variant<TTypes...>& v)
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return get<Index>(v);
|
||||
}
|
||||
@ -565,7 +601,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
constexpr const T&& get(const etl::variant<TTypes...>&& v)
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return get<Index>(v);
|
||||
}
|
||||
@ -573,9 +609,9 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// get_if
|
||||
//***************************************************************************
|
||||
template < size_t Index, class... Types >
|
||||
constexpr etl::add_pointer_t<etl::variant_alternative_t<Index, etl::variant<Types...>>>
|
||||
get_if(etl::variant<Types...>* pv) noexcept
|
||||
template < size_t Index, typename... TTypes >
|
||||
constexpr etl::add_pointer_t<etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
|
||||
get_if(etl::variant<TTypes...>* pv) noexcept
|
||||
{
|
||||
if ((pv != nullptr) && (pv->index() == Index))
|
||||
{
|
||||
@ -588,9 +624,9 @@ namespace etl
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template< size_t Index, class... Types >
|
||||
constexpr etl::add_pointer_t<const etl::variant_alternative_t<Index, etl::variant<Types...>>>
|
||||
get_if(const etl::variant<Types...>* pv) noexcept
|
||||
template< size_t Index, typename... TTypes >
|
||||
constexpr etl::add_pointer_t<const etl::variant_alternative_t<Index, etl::variant<TTypes...>>>
|
||||
get_if(const etl::variant<TTypes...>* pv) noexcept
|
||||
{
|
||||
if ((pv != nullptr) && (pv->index() == Index))
|
||||
{
|
||||
@ -603,19 +639,19 @@ namespace etl
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template< class T, class... Types >
|
||||
constexpr etl::add_pointer_t<T> get_if(etl::variant<Types...>* pv) noexcept
|
||||
template< class T, typename... TTypes >
|
||||
constexpr etl::add_pointer_t<T> get_if(etl::variant<TTypes...>* pv) noexcept
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return etl::get_if<Index>(pv);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template< class T, class... Types >
|
||||
constexpr etl::add_pointer_t<const T> get_if(const etl::variant<Types...>* pv) noexcept
|
||||
template< class T, typename... TTypes >
|
||||
constexpr etl::add_pointer_t<const T> get_if(const etl::variant<TTypes...>* pv) noexcept
|
||||
{
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
|
||||
return etl::get_if<Index>(pv);
|
||||
}
|
||||
|
||||
@ -98,6 +98,8 @@ SOFTWARE.
|
||||
#define ETL_MEM_CAST_FORCE_CPP03
|
||||
#endif
|
||||
|
||||
#define ETL_OVERLOAD_FORCE_CPP11
|
||||
|
||||
#if defined(ETL_NO_STL)
|
||||
#define ETL_TIMER_SEMAPHORE_TYPE uint32_t
|
||||
#endif
|
||||
|
||||
@ -35,6 +35,7 @@ SOFTWARE.
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -399,23 +400,34 @@ namespace
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_variant_visitor)
|
||||
{
|
||||
{
|
||||
struct Visitor : public etl::visitor<char, int, std::string>
|
||||
{
|
||||
Visitor()
|
||||
: result_c(0)
|
||||
, result_i(0)
|
||||
, result_s("")
|
||||
{
|
||||
}
|
||||
|
||||
void visit(char& c)
|
||||
{
|
||||
|
||||
result_c = c;
|
||||
}
|
||||
|
||||
void visit(int& i)
|
||||
{
|
||||
|
||||
result_i = i;
|
||||
}
|
||||
|
||||
void visit(std::string& s)
|
||||
{
|
||||
|
||||
result_s = s;
|
||||
}
|
||||
|
||||
char result_c;
|
||||
int result_i;
|
||||
std::string result_s;
|
||||
};
|
||||
|
||||
Visitor visitor;
|
||||
@ -424,12 +436,64 @@ namespace
|
||||
|
||||
variant = char(1);
|
||||
variant.accept(visitor);
|
||||
CHECK_EQUAL(1, visitor.result_c);
|
||||
|
||||
variant = int(2);
|
||||
variant.accept(visitor);
|
||||
CHECK_EQUAL(2, visitor.result_i);
|
||||
|
||||
variant = std::string("3");
|
||||
variant.accept(visitor);
|
||||
CHECK_EQUAL("3", visitor.result_s);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_variant_operator_visit)
|
||||
{
|
||||
struct Visitor
|
||||
{
|
||||
Visitor()
|
||||
: result_c(0)
|
||||
, result_i(0)
|
||||
, result_s("")
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(char& c)
|
||||
{
|
||||
result_c = c;
|
||||
}
|
||||
|
||||
void operator()(int& i)
|
||||
{
|
||||
result_i = i;
|
||||
}
|
||||
|
||||
void operator()(std::string& s)
|
||||
{
|
||||
result_s = s;
|
||||
}
|
||||
|
||||
char result_c;
|
||||
int result_i;
|
||||
std::string result_s;
|
||||
};
|
||||
|
||||
Visitor visitor;
|
||||
|
||||
test_variant_3 variant;
|
||||
|
||||
variant = char(1);
|
||||
variant(visitor);
|
||||
CHECK_EQUAL(1, visitor.result_c);
|
||||
|
||||
variant = int(2);
|
||||
variant(visitor);
|
||||
CHECK_EQUAL(2, visitor.result_i);
|
||||
|
||||
variant = std::string("3");
|
||||
variant(visitor);
|
||||
CHECK_EQUAL("3", visitor.result_s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1348,6 +1348,7 @@
|
||||
<ClInclude Include="..\..\include\etl\mutex\mutex_clang_sync.h" />
|
||||
<ClInclude Include="..\..\include\etl\mutex\mutex_freertos.h" />
|
||||
<ClInclude Include="..\..\include\etl\negative.h" />
|
||||
<ClInclude Include="..\..\include\etl\overload.h" />
|
||||
<ClInclude Include="..\..\include\etl\placement_new.h" />
|
||||
<ClInclude Include="..\..\include\etl\null_type.h" />
|
||||
<ClInclude Include="..\..\include\etl\parameter_pack.h" />
|
||||
@ -5033,4 +5034,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@ -1112,11 +1112,12 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\mem_cast.h">
|
||||
<Filter>ETL\Utilities</Filter>
|
||||
<ClInclude Include="..\..\include\etl\private\variant_legacy.h">
|
||||
<Filter>ETL\Private</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\private\variant_new.h">
|
||||
<Filter>ETL\Private</Filter>
|
||||
<ClInclude Include="..\..\include\etl\experimental\mem_cast.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\overload.h">
|
||||
<Filter>ETL\Patterns</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\experimental\mem_cast.h">
|
||||
<Filter>ETL\Utilities</Filter>
|
||||
@ -2701,4 +2702,4 @@
|
||||
<Filter>Resource Files</Filter>
|
||||
</Natvis>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
Loading…
x
Reference in New Issue
Block a user