Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386526
type_list.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
14 KB
Referenced Files
None
Subscribers
None
type_list.hpp
View Options
//===-- rosa/support/type_list.hpp ------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/type_list.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Facilities for types representing lists of types.
///
/// \note This implementation is partially based on the \c 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
{
/// Constructor, needs to do nothing.
constexpr
TypeList
(
void
)
{}
};
/// The empty \c rosa::Typelist.
using
EmptyTypeList
=
TypeList
<>
;
/// \defgroup TypeListAtImpl Implementation of rosa::TypeListAt
///
/// \brief Gets the type at index \p Pos from a list of types.
///
/// \note Only to be used by the implementation of \c 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 \p Pos is not \c 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 \p Pos is \c 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 \c rosa::none_t.
template
<
size_t
Pos
>
struct
TypeListAtImpl
<
Pos
>
{
using
Type
=
none_t
;
};
///@}
/// \defgroup TypeListAt Definition of rosa::TypeListAt
///
/// \brief Gets the element at index \p Pos of \p List.
///
///
/// The type at index \c Pos in a \c rosa::TypeList \c List can be obtained as
/// \code
/// typename TypeListAt<List, Pos>::Type
/// \endcode
///
/// \note The resulting type is \c rosa::none_t if \code
/// TypeListSize<List>::Value < Pos
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::TypeList to take an element from
/// \tparam Pos index to take the element from
template
<
typename
List
,
size_t
Pos
>
struct
TypeListAt
;
/// Implementation using \c rosa::TypeListAtImpl.
template
<
size_t
Pos
,
typename
...
Ts
>
struct
TypeListAt
<
TypeList
<
Ts
...
>
,
Pos
>
{
using
Type
=
typename
TypeListAtImpl
<
Pos
,
Ts
...
>::
Type
;
};
///@}
/// \defgroup TypeListIndexOfImpl Implementation of rosa::TypeListIndexOf
///
/// \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 \c 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 \c -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 Definition of rosa::TypeListIndexOf
///
/// \brief Tells the index of the first occurence of type in a
/// \c rosa::TypeList.
///
/// The index of the first occurence of type \c T in \c rosa::TypeList \c List
/// can be obtained as \code
/// TypeListIndexOf<List, T>::Value
/// \endcode
///
/// \note The resulting index is \c -1 if \c T is not present in \c List.
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::TypeList to search in
/// \tparam T type to search for
template
<
typename
List
,
typename
T
>
struct
TypeListIndexOf
;
/// Implementation of the template using \c rosa::TypeListIndexOfImpl.
template
<
typename
...
Ts
,
typename
T
>
struct
TypeListIndexOf
<
TypeList
<
Ts
...
>
,
T
>
{
static
constexpr
int
Value
=
TypeListIndexOfImpl
<
0
,
T
,
Ts
...
>::
Value
;
};
///@}
/// \defgroup TypeListHead Implementation of rosa::TypeListHead
///
/// \brief Gets the first element of a \c rosa::TypeList.
///
/// The first element of a \c rosa::TypeList \c List can be obtained as \code
/// typename TypeListHead<List>::Type
/// \endcode
///
/// \note The resulting type is \c rosa::none_t if \c List is
/// \c rosa::EmptyTypeList.
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::TypeList to get the first element of
template
<
typename
List
>
struct
TypeListHead
;
/// Specialization for \c rosa::EmptyTypeList.
///
/// In this case, the found type is \c rosa::none_t.
template
<>
struct
TypeListHead
<
EmptyTypeList
>
{
using
Type
=
none_t
;
};
/// Implementation for a non-empty \c rosa::TypeList.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListHead
<
TypeList
<
T
,
Ts
...
>>
{
using
Type
=
T
;
};
///@}
/// \defgroup TypeListTail Implementation of rosa::TypeListTail
///
/// \brief Gets the tail of a \c rosa::TypeList.
///
/// The tail of a \c rosa::TypeList \c List, that is \c List except for its
/// first element, can be obtained as \code
/// typename TypeListTail<List>::Type
/// \endcode
///
/// \note If \c List is \c rosa::EmptyTypeList, then the resulting type is also
/// \c rosa::EmptyTypeList.
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::TypeList to take the tail of
template
<
typename
List
>
struct
TypeListTail
;
/// Specialization for \c rosa::EmptyTypeList.
///
/// In this case, the resulting type is \c rosa::EmptyTypeList.
template
<>
struct
TypeListTail
<
EmptyTypeList
>
{
using
Type
=
EmptyTypeList
;
};
/// Implementation for a non-empty \c rosa::TypeList.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListTail
<
TypeList
<
T
,
Ts
...
>>
{
using
Type
=
TypeList
<
Ts
...
>
;
};
///@}
/// \defgroup TypeListPush Implementation of rosa::TypeListPush
///
/// \brief Extends a \c rosa::TypeList with a type.
///
/// Whether the new type is pushed in the front or in the back of the
/// \c 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 \p Q is a \c rosa::TypeList, a \c rosa::TypeList
/// otherwise
/// \tparam Q a type if \p P is a \c rosa::TypeList, a \c rosa::TypeList
/// otherwise
template
<
typename
P
,
typename
Q
>
struct
TypeListPush
;
/// Implementation for the case when pushing at the back of the
/// \c 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
/// \c rosa::TypeList.
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListPush
<
T
,
TypeList
<
Ts
...
>>
{
using
Type
=
TypeList
<
T
,
Ts
...
>
;
};
///@}
/// \defgroup TypeListDrop Implementation of rosa::TypeListDrop
///
/// \brief Drops some elements from the beginning of a \c rosa::TypeList.
///
/// The first \c N types of a \c rosa::TypeList \c 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 \c rosa::TypeList to drop the first \p N element of
template
<
size_t
N
,
typename
List
>
struct
TypeListDrop
;
/// Specialization for \c rosa::EmptyTypeList.
template
<
size_t
N
>
struct
TypeListDrop
<
N
,
EmptyTypeList
>
{
using
Type
=
EmptyTypeList
;
};
/// Implementation for a non-empty \c rosa::TypeList.
template
<
size_t
N
,
typename
T
,
typename
...
Ts
>
struct
TypeListDrop
<
N
,
TypeList
<
T
,
Ts
...
>>
{
using
Type
=
typename
std
::
conditional
<
N
==
0
,
TypeList
<
T
,
Ts
...
>
,
typename
TypeListDrop
<
N
-
1
,
TypeList
<
Ts
...
>>::
Type
>::
type
;
};
///@}
/// \defgroup TypeListConcat Implementation of rosa::TypeListConcat
///
/// \brief Concatenates two \c rosa::TypeList instances.
///
/// Two instances of \c rosa::TypeList \c List1 and \c List2 can be
/// concatenated as \code
/// typename TypeListConcat<List1, List2>::Type
/// \endcode
///@{
/// Declaration of the template
///
/// \tparam List1 the first instance of \c rosa::TypeList
/// \tparam List2 the second instance of \c rosa::TypeList
template
<
typename
List1
,
typename
List2
>
struct
TypeListConcat
;
/// Implementation of the template for \c rosa::TypeList instances.
template
<
typename
...
As
,
typename
...
Bs
>
struct
TypeListConcat
<
TypeList
<
As
...
>
,
TypeList
<
Bs
...
>>
{
using
Type
=
TypeList
<
As
...,
Bs
...
>
;
};
///@}
/// \defgroup TypeListSize Implementation of rosa::TypeListSize
///
/// \brief Tells the number of types stored in a \c rosa::TypeList.
///
/// The size of a \c rosa::TypeList \c List can be obtained as \code
/// TypeListSize<List>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::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 \c rosa::TypeList is empty.
///
/// \tparam List \c rosa::TypeList to check
template
<
typename
List
>
struct
TypeListEmpty
{
/// Denotes whether \p List is an empty \c rosa::TypeList or not.
static
constexpr
bool
Value
=
std
::
is_same
<
EmptyTypeList
,
List
>::
value
;
};
/// \defgroup TypeListContains Implementation of rosa::TypeListContains
///
/// \brief Tells if a \c rosa::TypeList contains a given type.
///
/// Whether a \c rosa::TypeList \c List contains the type \c T can be checked as
/// \code
/// TypeListContains<List, T>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::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 Implementation of rosa::TypeListSubsetOf
///
/// \brief Tells if a \c rosa::TypeList is a subset of another one.
///
/// Whether a \c rosa::TypeList \c ListA is a subset of another
/// \c rosa::TypeList \c ListB can be checked as \code
/// TypeListSubsetOf<ListA, ListB>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam ListA \c rosa::TypeList to check if is a subset of \p ListB
/// \tparam ListB \c rosa::TypeList to check if is a superset of \p 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 \p ListA
/// was found in \p ListB.
template
<
typename
List
>
struct
TypeListSubsetOf
<
EmptyTypeList
,
List
,
true
>
{
static
constexpr
bool
Value
=
true
;
};
/// Specializaton for the case when an element of the original \p ListA cannot
/// be found in \p 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 Implementation of rosa::TypeListFind
///
/// \brief Finds the first type in a list of types that satisfies a predicate.
///
/// \note Only to be used by the implementation of \c 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 Definition of rosa::TypeListFind
///
/// \brief Finds the first element satisfying a predicate in a
/// \c rosa::TypeList.
///
/// The first type satisfying a predicate \c Pred in a \c rosa::TypeList
/// \c List can be obtained as \code
/// typename TypeListFind<List, Pred>::Type
/// \endcode
///
/// \note The resulting type is \c rosa::none_t if no type in \c List satisfies
/// \c Pred.
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::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 \c 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
Thu, Jul 3, 7:42 PM (6 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157332
Default Alt Text
type_list.hpp (14 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment