Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10706083
type_list.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
12 KB
Referenced Files
None
Subscribers
None
type_list.hpp
View Options
/***************************************************************************//**
*
* \file rosa/support/type_list.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Facilities for types representing lists of types.
*
* \note This implementation is partially based on the `type_list`
* implementation of CAF.
* \todo Check license.
*
******************************************************************************/
#ifndef ROSA_SUPPORT_TYPE_LIST_HPP
#define ROSA_SUPPORT_TYPE_LIST_HPP
#include
"rosa/support/debug.hpp"
#include
"rosa/support/types.hpp"
#include
<type_traits>
namespace
rosa
{
/// A list of types.
///
/// \tparam Ts types to make a list of
template
<
typename
...
Ts
>
struct
TypeList
{
/// Ctor, needs to do nothing.
constexpr
TypeList
(
void
)
{}
};
/// The empty `rosa::Typelist`.
using
EmptyTypeList
=
TypeList
<>
;
/// \defgroup TypeListAtImpl
/// \brief Gets the type at index `Pos` from a list of types.
///
/// \note Only to be used by the implementation of `rosa::TypeListAt`.
///@{
/// Declaration of the template.
///
/// \tparam Pos index to take the element from
/// \tparam Ts types
template
<
size_t
Pos
,
typename
...
Ts
>
struct
TypeListAtImpl
;
/// Definition for the general case when `Pos` is not `0` and there is type in
/// the list.
template
<
size_t
Pos
,
typename
T
,
typename
...
Ts
>
struct
TypeListAtImpl
<
Pos
,
T
,
Ts
...
>
{
using
Type
=
typename
TypeListAtImpl
<
Pos
-
1
,
Ts
...
>::
Type
;
};
/// Specialization for the case when `Pos` is `0`˙.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListAtImpl
<
0
,
T
,
Ts
...
>
{
using
Type
=
T
;
};
/// Specialization for the case when there is no more type.
///
/// In this case, the found type is `rosa::none_t`.
template
<
size_t
Pos
>
struct
TypeListAtImpl
<
Pos
>
{
using
Type
=
none_t
;
};
///@}
/// \defgroup TypeListAt
/// \brief Gets the element at index `Pos` of `List`.
///
///
/// The type at index `Pos` in a `rosa::TypeList` `List` can be obtained as
/// \code
/// typename TypeListAt<List, Pos>::Type
/// \endcode
///
/// \note The resulting type is `rosa::none_t` if \code
/// TypeListSize<List>::Value < Pos
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to take an element from
/// \tparam Pos index to take the element from
template
<
typename
List
,
size_t
Pos
>
struct
TypeListAt
;
/// Implementation using `rosa::TypeListAtImpl`.
template
<
size_t
Pos
,
typename
...
Ts
>
struct
TypeListAt
<
TypeList
<
Ts
...
>
,
Pos
>
{
using
Type
=
typename
TypeListAtImpl
<
Pos
,
Ts
...
>::
Type
;
};
///@}
/// \defgroup TypeListIndexOfImpl
/// \brief Tells the index of the first occurence of a type in a list of types.
///
/// \note Only to be used by the implementation of `rosa::TypeListIndexOf`.
///@{
/// Declaration of the template.
///
/// \tparam Pos the number types already being checked from the beginning of the
/// list
/// \tparam X type to search for
/// \tparam Ts remaining list of types
template
<
size_t
Pos
,
typename
X
,
typename
...
Ts
>
struct
TypeListIndexOfImpl
;
/// Specialization for the case when the list is over.
///
/// In this case, the found index is `-1`.
template
<
size_t
Pos
,
typename
X
>
struct
TypeListIndexOfImpl
<
Pos
,
X
>
{
static
constexpr
int
Value
=
-1
;
};
/// Specialization for the case when the first type in the remaining list
/// is a match.
template
<
size_t
Pos
,
typename
X
,
typename
...
Ts
>
struct
TypeListIndexOfImpl
<
Pos
,
X
,
X
,
Ts
...
>
{
static
constexpr
int
Value
=
Pos
;
};
/// Implementation for the general case when need to continue looking.
template
<
size_t
Pos
,
typename
X
,
typename
T
,
typename
...
Ts
>
struct
TypeListIndexOfImpl
<
Pos
,
X
,
T
,
Ts
...
>
{
static
constexpr
int
Value
=
TypeListIndexOfImpl
<
Pos
+
1
,
X
,
Ts
...
>::
Value
;
};
///@}
/// \defgroup TypeListIndexOf
/// \brief Tells the index of the first occurence of type in a `rosa::TypeList`.
///
/// The index of the first occurence of type `T` in `rosa::TypeList` `List` can
/// be obtained as \code
/// TypeListIndexOf<List, T>::Value
/// \endcode
///
/// \note The resulting index is `-1` if `T` is not present in `List`.
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to search in
/// \tparam T type to search for
template
<
typename
List
,
typename
T
>
struct
TypeListIndexOf
;
/// Implementation of the template using `rosa::TypeListIndexOfImpl`.
template
<
typename
...
Ts
,
typename
T
>
struct
TypeListIndexOf
<
TypeList
<
Ts
...
>
,
T
>
{
static
constexpr
int
Value
=
TypeListIndexOfImpl
<
0
,
T
,
Ts
...
>::
Value
;
};
///@}
/// \defgroup TypeListHead
/// \brief Gets the first element of a `rosa::TypeList`.
///
/// The first element of a `rosa::TypeList` `List` can be obtained as \code
/// typename TypeListHead<List>::Type
/// \endcode
///
/// \note The resulting type is `rosa::none_t` if `List` is the
/// `rosa::EmptyTypeList`.
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to get the first element of
template
<
typename
List
>
struct
TypeListHead
;
/// Specialization for `rosa::EmptyTypeList`.
///
/// In this case, the found type is `rosa::none_t`.
template
<>
struct
TypeListHead
<
EmptyTypeList
>
{
using
Type
=
none_t
;
};
/// Implementation for a non-empty `rosa::TypeList`.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListHead
<
TypeList
<
T
,
Ts
...
>>
{
using
Type
=
T
;
};
///@}
/// \defgroup TypeListTail
///
/// \brief Gets the tail of a `rosa::TypeList`.
///
/// The tail of a `rosa::TypeList` `List`, that is `List` except for its first
/// element, can be obtained as \code
/// typename TypeListTail<List>::Type
/// \endcode
///
/// \note If `List` is the `rosa::EmptyTypeList`, then the resulting type is
/// also `rosa::EmptyTypeList`.
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to take the tail of
template
<
typename
List
>
struct
TypeListTail
;
/// Specialization for the `rosa::EmptyTypeList`.
///
/// In this case, the resulting type is `rosa::EmptyTypeList`.
template
<>
struct
TypeListTail
<
EmptyTypeList
>
{
using
Type
=
EmptyTypeList
;
};
/// Implementation for a non-empty `rosa::TypeList`.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListTail
<
TypeList
<
T
,
Ts
...
>>
{
using
Type
=
TypeList
<
Ts
...
>
;
};
///@}
/// \defgroup TypeListPush
/// \brief Extends a `rosa::TypeList` with a type.
///
/// Whether the new type is pushed in the front or in the back of the
/// `rosa::TypeList` depends on the order of template arguments, as shown in the
/// following example: \code
/// using List = TypeList<A>
/// typename TypeListPush<List, T>::Type; // TypeList<A, T>
/// typename TypeListPush<T, List>::Type; // TypeList<T, A>
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam P a type if `Q` is a `rosa::TypeList`, a `rosa::TypeList` otherwise
/// \tparam Q a type if `P` is a `rosa::TypeList`, a `rosa::TypeList` otherwise
template
<
typename
P
,
typename
Q
>
struct
TypeListPush
;
/// Implementation for the case when pushing at the back of the
/// `rosa::TypeList`.
template
<
typename
...
Ts
,
typename
T
>
struct
TypeListPush
<
TypeList
<
Ts
...
>
,
T
>
{
using
Type
=
TypeList
<
Ts
...,
T
>
;
};
/// Implementation for the case when pushing to the front of the
/// `rosa::TypeList`.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListPush
<
T
,
TypeList
<
Ts
...
>>
{
using
Type
=
TypeList
<
T
,
Ts
...
>
;
};
///@}
/// \defgroup TypeListDrop
/// \brief Drops some elements from the beginning of a `rosa::TypeList`.
///
/// The first `N` types of a `rosa::TypeList` `List` can be dropped as \code
/// typename TypeListDrop<N, List>::Type
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam N number of types to drop
/// \tparam List `TypeList` to drop the first `N` element of
template
<
size_t
N
,
typename
List
>
struct
TypeListDrop
;
/// Specialization for the `rosa::EmptyTypeList`.
template
<
size_t
N
>
struct
TypeListDrop
<
N
,
EmptyTypeList
>
{
using
Type
=
EmptyTypeList
;
};
/// Implementation for a non-empty `rosa::TypeList`.
template
<
size_t
N
,
typename
T
,
typename
...
Ts
>
struct
TypeListDrop
<
N
,
TypeList
<
T
,
Ts
...
>>
{
using
Type
=
typename
std
::
conditional
<
N
==
0
,
TypeList
<
Ts
...
>
,
typename
TypeListDrop
<
N
-
1
,
TypeList
<
Ts
...
>>::
Type
>::
type
;
};
///@}
/// \defgroup TypeListSize
/// \brief Tells the number of types stored in a `rosa::TypeList`.
///
/// The size of a `rosa::TypeList` `List` can be obtained as \code
/// TypeListSize<List>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to get the size of
template
<
typename
List
>
struct
TypeListSize
;
/// Implementation of the template.
template
<
typename
...
Ts
>
struct
TypeListSize
<
TypeList
<
Ts
...
>>
{
static
constexpr
size_t
Value
=
sizeof
...(
Ts
);
};
template
<
typename
...
Ts
>
constexpr
size_t
TypeListSize
<
TypeList
<
Ts
...
>>::
Value
;
///@}
/// Tests whether a `rosa::TypeList` is empty.
///
/// \tparam List the `TypeList` to check
template
<
typename
List
>
struct
TypeListEmpty
{
/// Denotes whether `List` is an empty `rosa::TypeList` or not.
static
constexpr
bool
Value
=
std
::
is_same
<
EmptyTypeList
,
List
>::
value
;
};
/// \defgroup TypeListContains
/// \brief Tells if a `rosa::TypeList` contains a type.
///
/// Whether a `rosa::TypeList` `List` contains the type `T` can be checked as
/// \code
/// TypeListContains<List, T>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to search in
/// \tparam T type to search for
template
<
typename
List
,
typename
T
>
struct
TypeListContains
;
/// Implementation of the template.
template
<
typename
...
Ts
,
typename
T
>
struct
TypeListContains
<
TypeList
<
Ts
...
>
,
T
>
{
static
constexpr
bool
Value
=
std
::
conditional
<
TypeListIndexOf
<
TypeList
<
Ts
...
>
,
T
>::
Value
==
-1
,
std
::
false_type
,
std
::
true_type
>::
type
::
value
;
};
///@}
/// \defgroup TypeListSubsetOf
/// \brief Tells if a `rosa::TypeList` is a subset of another one.
///
/// Whether a `rosa::TypeList` `ListA` is a subset of another `rosa::TypeList`
/// `ListB` can be checked as \code
/// TypeListSubsetOf<ListA, ListB>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam ListA `TypeList` to check if is a subset of `ListB`
/// \tparam ListB `TypeList` to check if is a superset of `ListA`
/// \tparam Fwd always use the default value!
template
<
typename
ListA
,
typename
ListB
,
bool
Fwd
=
true
>
struct
TypeListSubsetOf
;
/// Specialization for the case when all the elements of the original `ListA`
/// was found in `ListB`.
template
<
typename
List
>
struct
TypeListSubsetOf
<
EmptyTypeList
,
List
,
true
>
{
static
constexpr
bool
Value
=
true
;
};
/// Specializaton for the case when an element of the original `ListA` cannot be
/// found in `ListB`.
template
<
typename
ListA
,
typename
ListB
>
struct
TypeListSubsetOf
<
ListA
,
ListB
,
false
>
{
static
constexpr
bool
Value
=
false
;
};
/// Definition for the general case.
template
<
typename
T
,
typename
...
Ts
,
typename
List
>
struct
TypeListSubsetOf
<
TypeList
<
T
,
Ts
...
>
,
List
>
:
TypeListSubsetOf
<
TypeList
<
Ts
...
>
,
List
,
TypeListContains
<
List
,
T
>::
Value
>
{};
///@}
/// \defgroup TypeListFindImpl
/// \brief Finds the first type in a list of types that satisfies a predicate.
///
/// \note Only to be used by the implementation of `rosa::TypeListFind`.
///@{
/// Declaration of the template.
///
/// \tparam Pred the predicate to check types against
/// \tparam Ts list of types to check
template
<
template
<
typename
>
class
Pred
,
typename
...
Ts
>
struct
TypeListFindImpl
;
/// Specialization for the case when no more types remain to check.
template
<
template
<
typename
>
class
Pred
>
struct
TypeListFindImpl
<
Pred
>
{
using
Type
=
none_t
;
};
/// Implementation for the general case when there is a type to check.
template
<
template
<
typename
>
class
Pred
,
typename
T
,
typename
...
Ts
>
struct
TypeListFindImpl
<
Pred
,
T
,
Ts
...
>
{
using
Type
=
typename
std
::
conditional
<
Pred
<
T
>::
Value
,
T
,
typename
TypeListFindImpl
<
Pred
,
Ts
...
>::
Type
>::
type
;
};
///@}
/// \defgroup TypeListFind
/// \brief Finds the first element satisfying a predicate in a `rosa::TypeList`.
///
/// The first type satisfying a predicate `Pred` in a `rosa::TypeList` `List`
/// can be obtained as \code
/// typename TypeListFind<List, Pred>::Type
/// \endcode
///
/// \note The resulting type is `rosa::none_t` if no type in `List` satisfies
/// `Pred`.
///@{
/// Declaration of the template.
///
/// \tparam List `TypeList` to search in
/// \tparam Pred predicate to check elements against
template
<
typename
List
,
template
<
typename
>
class
Pred
>
struct
TypeListFind
;
/// Implementation of the template using `rosa::TypeListFindImpl`.
template
<
typename
...
Ts
,
template
<
typename
>
class
Pred
>
struct
TypeListFind
<
TypeList
<
Ts
...
>
,
Pred
>
{
using
Type
=
typename
TypeListFindImpl
<
Pred
,
Ts
...
>::
Type
;
};
///@}
}
// End namespace rosa
#endif
// ROSA_SUPPORT_TYPE_LIST_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, May 31, 4:44 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
318458
Default Alt Text
type_list.hpp (12 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment