Page MenuHomePhorge

type_list.hpp
No OneTemporary

Size
14 KB
Referenced Files
None
Subscribers
None

type_list.hpp

//===-- 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

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)

Event Timeline