Latest updates

This commit is contained in:
John Wellbelove 2021-06-22 10:43:39 +01:00
parent dddeb3471f
commit 2025e6ff9b
6 changed files with 223 additions and 34 deletions

85
include/etl/overload.h Normal file
View 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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}
};
}

View File

@ -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>

View File

@ -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>