Skip to content

Commit bcf5ec4

Browse files
author
John Wellbelove
committed
Merge branch 'pull-request/#1044-Add-traits-to-type_list' into development
2 parents c19a3fe + 3360eae commit bcf5ec4

File tree

11 files changed

+515
-152
lines changed

11 files changed

+515
-152
lines changed

include/etl/index_of_type.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/******************************************************************************
2+
The MIT License(MIT)
3+
4+
Embedded Template Library.
5+
https://github.com/ETLCPP/etl
6+
https://www.etlcpp.com
7+
8+
Copyright(c) 2025 John Wellbelove
9+
10+
Permission is hereby granted, free of charge, to any person obtaining a copy
11+
of this software and associated documentation files(the "Software"), to deal
12+
in the Software without restriction, including without limitation the rights
13+
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14+
copies of the Software, and to permit persons to whom the Software is
15+
furnished to do so, subject to the following conditions :
16+
17+
The above copyright notice and this permission notice shall be included in all
18+
copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
SOFTWARE.
27+
******************************************************************************/
28+
29+
#ifndef ETL_INDEX_OF_TYPE_INCLUDED
30+
#define ETL_INDEX_OF_TYPE_INCLUDED
31+
32+
#include "platform.h"
33+
#include "static_assert.h"
34+
#include "integral_limits.h"
35+
36+
namespace etl
37+
{
38+
#if ETL_USING_CPP11
39+
40+
//***************************************************************************
41+
/// Defines a no-position constant.
42+
//***************************************************************************
43+
static ETL_CONSTANT size_t index_of_type_npos = etl::integral_limits<size_t>::max;
44+
45+
//***************************************************************************
46+
/// Finds the index of a type in a variadic type parameter.
47+
//***************************************************************************
48+
template <typename T, typename... TTypes>
49+
struct index_of_type;
50+
51+
//***************************************************************************
52+
/// Finds the index of a type in a variadic type parameter.
53+
//***************************************************************************
54+
template <typename T, typename T1, typename... TRest>
55+
struct index_of_type<T, T1, TRest...> : public etl::integral_constant<size_t, etl::is_same<T, T1>::value ? 0 :
56+
(etl::index_of_type<T, TRest...>::value == etl::index_of_type_npos ? etl::index_of_type_npos :
57+
etl::index_of_type<T, TRest...>::value + 1)>
58+
{
59+
};
60+
61+
//***************************************************************************
62+
/// Finds the index of a type in a variadic type parameter.
63+
/// No types left.
64+
//***************************************************************************
65+
template <typename T>
66+
struct index_of_type<T> : public etl::integral_constant<size_t, etl::index_of_type_npos>
67+
{
68+
};
69+
70+
#if ETL_USING_CPP17
71+
//***************************************************************************
72+
/// Finds the index of a type in a variadic type parameter.
73+
//***************************************************************************
74+
template <typename T, typename... TTypes>
75+
inline constexpr size_t index_of_type_v = etl::index_of_type<T, TTypes...>::value;
76+
#endif
77+
#endif
78+
}
79+
80+
#endif

include/etl/intrusive_forward_list.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,10 @@ namespace etl
322322
if (p_next != &this->terminator)
323323
{
324324
link_type* p_unlinked = etl::unlink_after<link_type>(link);
325-
p_unlinked->clear();
325+
if (p_unlinked != ETL_NULLPTR)
326+
{
327+
p_unlinked->clear();
328+
}
326329
--current_size;
327330
}
328331
}

include/etl/private/variant_variadic.h

Lines changed: 23 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ SOFTWARE.
3131
#include "../platform.h"
3232
#include "../utility.h"
3333
#include "../largest.h"
34+
#include "../nth_type.h"
3435
#include "../exception.h"
3536
#include "../type_traits.h"
3637
#include "../integral_limits.h"
3738
#include "../static_assert.h"
3839
#include "../alignment.h"
3940
#include "../error_handler.h"
40-
#include "../parameter_pack.h"
41+
#include "../type_list.h"
4142
#include "../placement_new.h"
4243
#include "../visitor.h"
4344
#include "../memory.h"
@@ -66,82 +67,6 @@ namespace etl
6667
{
6768
namespace private_variant
6869
{
69-
//***************************************************************************
70-
// This is a copy of the normal etl::parameter_pack, but without the static_assert
71-
// so that the C++11 versions of do_visitor() & do_operator() do not throw a compile time error.
72-
//***************************************************************************
73-
template <typename... TTypes>
74-
class parameter_pack
75-
{
76-
public:
77-
78-
static constexpr size_t size = sizeof...(TTypes);
79-
80-
//***************************************************************************
81-
/// index_of_type
82-
//***************************************************************************
83-
template <typename T>
84-
class index_of_type
85-
{
86-
private:
87-
88-
using type = etl::remove_cvref_t<T>;
89-
90-
//***********************************
91-
template <typename Type, typename T1, typename... TRest>
92-
struct index_of_type_helper
93-
{
94-
static constexpr size_t value = etl::is_same<Type, T1>::value ? 1 : 1 + index_of_type_helper<Type, TRest...>::value;
95-
};
96-
97-
//***********************************
98-
template <typename Type, typename T1>
99-
struct index_of_type_helper<Type, T1>
100-
{
101-
static constexpr size_t value = 1UL;
102-
};
103-
104-
public:
105-
106-
static_assert(etl::is_one_of<type, TTypes...>::value, "T is not in parameter pack");
107-
108-
/// The index value.
109-
static constexpr size_t value = index_of_type_helper<type, TTypes...>::value - 1;
110-
};
111-
112-
//***************************************************************************
113-
/// type_from_index
114-
//***************************************************************************
115-
template <size_t I>
116-
class type_from_index
117-
{
118-
private:
119-
120-
//***********************************
121-
template <size_t II, size_t N, typename T1, typename... TRest>
122-
struct type_from_index_helper
123-
{
124-
using type = typename etl::conditional<II == N, T1, typename type_from_index_helper<II, N + 1, TRest...>::type>::type;
125-
};
126-
127-
//***********************************
128-
template <size_t II, size_t N, typename T1>
129-
struct type_from_index_helper<II, N, T1>
130-
{
131-
using type = T1;
132-
};
133-
134-
public:
135-
136-
/// Template alias
137-
using type = typename type_from_index_helper<I, 0, TTypes...>::type;
138-
};
139-
140-
//***********************************
141-
template <size_t I>
142-
using type_from_index_t = typename type_from_index<I>::type;
143-
};
144-
14570
//*******************************************
14671
// The traits an object may have.
14772
//*******************************************
@@ -327,7 +252,7 @@ namespace etl
327252
template <size_t Index, typename... TTypes>
328253
struct variant_alternative<Index, etl::variant<TTypes...>>
329254
{
330-
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
255+
using type = nth_type_t<Index, TTypes...>;
331256
};
332257

333258
template <size_t Index, typename T>
@@ -529,13 +454,13 @@ namespace etl
529454
// Get the index of a type.
530455
//*******************************************
531456
template <typename T>
532-
using index_of_type = typename etl::private_variant::parameter_pack<TTypes...>::template index_of_type<etl::remove_cvref_t<T>>;
457+
using index_of_type = etl::type_list_index_of_type<etl::type_list<TTypes...>, etl::remove_cvref_t<T>>;
533458

534459
//*******************************************
535460
// Get the type from the index.
536461
//*******************************************
537462
template <size_t Index>
538-
using type_from_index = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
463+
using type_from_index = typename etl::type_list_type_at_index<etl::type_list<TTypes...>, Index>::type;
539464

540465
public:
541466

@@ -546,7 +471,7 @@ namespace etl
546471
#include "diagnostic_uninitialized_push.h"
547472
ETL_CONSTEXPR14 variant()
548473
{
549-
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<0U>::type;
474+
using type = type_from_index<0U>;
550475

551476
default_construct_in_place<type>(data);
552477
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
@@ -592,7 +517,7 @@ namespace etl
592517
ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t<Index>, TArgs&&... args)
593518
: type_id(Index)
594519
{
595-
using type = typename private_variant::parameter_pack<TTypes...>:: template type_from_index_t<Index>;
520+
using type = type_from_index<Index>;
596521
static_assert(etl::is_one_of<type, TTypes...> ::value, "Unsupported type");
597522

598523
construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
@@ -625,7 +550,7 @@ namespace etl
625550
ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t<Index>, std::initializer_list<U> init, TArgs&&... args)
626551
: type_id(Index)
627552
{
628-
using type = typename private_variant::parameter_pack<TTypes...>:: template type_from_index_t<Index>;
553+
using type = type_from_index<Index>;
629554
static_assert(etl::is_one_of<type, TTypes...> ::value, "Unsupported type");
630555

631556
construct_in_place_args<type>(data, init, etl::forward<TArgs>(args)...);
@@ -715,7 +640,7 @@ namespace etl
715640

716641
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
717642

718-
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
643+
type_id = index_of_type<T>::value;
719644

720645
return *static_cast<T*>(data);
721646
}
@@ -737,7 +662,7 @@ namespace etl
737662

738663
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
739664

740-
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
665+
type_id = index_of_type<T>::value;
741666

742667
return *static_cast<T*>(data);
743668
}
@@ -747,9 +672,9 @@ namespace etl
747672
/// Emplace by index with variadic constructor parameters.
748673
//***************************************************************************
749674
template <size_t Index, typename... TArgs>
750-
typename etl::variant_alternative<Index, variant<TArgs...>>::type& emplace(TArgs&&... args)
675+
typename etl::variant_alternative<Index, variant<TTypes...>>::type& emplace(TArgs&&... args)
751676
{
752-
static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size, "Index out of range");
677+
static_assert(Index < sizeof...(TTypes), "Index out of range");
753678

754679
using type = type_from_index<Index>;
755680

@@ -769,9 +694,9 @@ namespace etl
769694
/// Emplace by index with variadic constructor parameters.
770695
//***************************************************************************
771696
template <size_t Index, typename U, typename... TArgs>
772-
typename etl::variant_alternative<Index, variant<TArgs...>>::type& emplace(std::initializer_list<U> il, TArgs&&... args)
697+
typename etl::variant_alternative<Index, variant<TTypes...>>::type& emplace(std::initializer_list<U> il, TArgs&&... args)
773698
{
774-
static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size, "Index out of range");
699+
static_assert(Index < sizeof...(TTypes), "Index out of range");
775700

776701
using type = type_from_index<Index>;
777702

@@ -803,7 +728,7 @@ namespace etl
803728
construct_in_place<type>(data, etl::forward<T>(value));
804729

805730
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
806-
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<type>::value;
731+
type_id = index_of_type<type>::value;
807732

808733
return *this;
809734
}
@@ -896,7 +821,7 @@ namespace etl
896821
template <typename T, etl::enable_if_t<is_supported_type<T>(), int> = 0>
897822
constexpr bool is_type() const noexcept
898823
{
899-
return (type_id == etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value);
824+
return (type_id == index_of_type<T>::value);
900825
}
901826

902827
//***************************************************************************
@@ -1469,7 +1394,7 @@ namespace etl
14691394
template <typename T, typename... TTypes>
14701395
ETL_CONSTEXPR14 bool holds_alternative(const etl::variant<TTypes...>& v) noexcept
14711396
{
1472-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1397+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
14731398

14741399
return (Index == variant_npos) ? false : (v.index() == Index);
14751400
}
@@ -1560,7 +1485,7 @@ namespace etl
15601485
template <typename T, typename... TTypes>
15611486
ETL_CONSTEXPR14 T& get(etl::variant<TTypes...>& v)
15621487
{
1563-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1488+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
15641489

15651490
return get<Index>(v);
15661491
}
@@ -1569,7 +1494,7 @@ namespace etl
15691494
template <typename T, typename... TTypes>
15701495
ETL_CONSTEXPR14 T&& get(etl::variant<TTypes...>&& v)
15711496
{
1572-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1497+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
15731498

15741499
return get<Index>(etl::move(v));
15751500
}
@@ -1578,7 +1503,7 @@ namespace etl
15781503
template <typename T, typename... TTypes>
15791504
ETL_CONSTEXPR14 const T& get(const etl::variant<TTypes...>& v)
15801505
{
1581-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1506+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
15821507

15831508
return get<Index>(v);
15841509
}
@@ -1587,7 +1512,7 @@ namespace etl
15871512
template <typename T, typename... TTypes>
15881513
ETL_CONSTEXPR14 const T&& get(const etl::variant<TTypes...>&& v)
15891514
{
1590-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1515+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
15911516

15921517
return get<Index>(etl::move(v));
15931518
}
@@ -1628,7 +1553,7 @@ namespace etl
16281553
template< class T, typename... TTypes >
16291554
ETL_CONSTEXPR14 etl::add_pointer_t<T> get_if(etl::variant<TTypes...>* pv) noexcept
16301555
{
1631-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1556+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
16321557

16331558
if ((pv != nullptr) && (pv->index() == Index))
16341559
{
@@ -1644,7 +1569,7 @@ namespace etl
16441569
template< typename T, typename... TTypes >
16451570
ETL_CONSTEXPR14 etl::add_pointer_t<const T> get_if(const etl::variant<TTypes...>* pv) noexcept
16461571
{
1647-
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
1572+
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
16481573

16491574
if ((pv != nullptr) && (pv->index() == Index))
16501575
{

0 commit comments

Comments
 (0)