diff --git a/include/rosa/support/type_list.hpp b/include/rosa/support/type_list.hpp index bb50be3..3e35a19 100644 --- a/include/rosa/support/type_list.hpp +++ b/include/rosa/support/type_list.hpp @@ -1,444 +1,444 @@ //===-- 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 /// /// \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 namespace rosa { /// A list of types. /// /// \tparam Ts types to make a list of template 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 struct TypeListAtImpl; /// Definition for the general case when \p Pos is not \c 0 and there is type in /// the list. template struct TypeListAtImpl { using Type = typename TypeListAtImpl::Type; }; /// Specialization for the case when \p Pos is \c 0. template 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 struct TypeListAtImpl { 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::Type /// \endcode /// /// \note The resulting type is \c rosa::none_t if \code /// TypeListSize::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 struct TypeListAt; /// Implementation using \c rosa::TypeListAtImpl. template struct TypeListAt, Pos> { using Type = typename TypeListAtImpl::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 struct TypeListIndexOfImpl; /// Specialization for the case when the list is over. /// /// In this case, the found index is \c -1. template struct TypeListIndexOfImpl { static constexpr int Value = -1; }; /// Specialization for the case when the first type in the remaining list /// is a match. template struct TypeListIndexOfImpl { static constexpr int Value = Pos; }; /// Implementation for the general case when need to continue looking. template struct TypeListIndexOfImpl { static constexpr int Value = TypeListIndexOfImpl::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::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 struct TypeListIndexOf; /// Implementation of the template using \c rosa::TypeListIndexOfImpl. template struct TypeListIndexOf, 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::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 struct TypeListHead; /// Specialization for \c rosa::EmptyTypeList. /// /// In this case, the found type is \c rosa::none_t. template <> struct TypeListHead { using Type = none_t; }; /// Implementation for a non-empty \c rosa::TypeList. template struct TypeListHead> { 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::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 struct TypeListTail; /// Specialization for \c rosa::EmptyTypeList. /// /// In this case, the resulting type is \c rosa::EmptyTypeList. template <> struct TypeListTail { using Type = EmptyTypeList; }; /// Implementation for a non-empty \c rosa::TypeList. template struct TypeListTail> { using Type = TypeList; }; ///@} /// \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 /// typename TypeListPush::Type; // TypeList /// typename TypeListPush::Type; // TypeList /// \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 struct TypeListPush; /// Implementation for the case when pushing at the back of the /// \c rosa::TypeList. template struct TypeListPush, T> { using Type = TypeList; }; /// Implementation for the case when pushing to the front of the /// \c rosa::TypeList. template struct TypeListPush> { using Type = TypeList; }; ///@} /// \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::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 struct TypeListDrop; /// Specialization for \c rosa::EmptyTypeList. template struct TypeListDrop { using Type = EmptyTypeList; }; /// Implementation for a non-empty \c rosa::TypeList. template struct TypeListDrop> { using Type = typename std::conditional< - N == 0, TypeList, + N == 0, TypeList, typename TypeListDrop>::Type>::type; }; ///@} /// \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::Value /// \endcode ///@{ /// Declaration of the template. /// /// \tparam List \c rosa::TypeList to get the size of template struct TypeListSize; /// Implementation of the template. template struct TypeListSize> { static constexpr size_t Value = sizeof...(Ts); }; template constexpr size_t TypeListSize>::Value; ///@} /// Tests whether a \c rosa::TypeList is empty. /// /// \tparam List \c rosa::TypeList to check template struct TypeListEmpty { /// Denotes whether \p List is an empty \c rosa::TypeList or not. static constexpr bool Value = std::is_same::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::Value /// \endcode ///@{ /// Declaration of the template. /// /// \tparam List \c rosa::TypeList to search in /// \tparam T type to search for template struct TypeListContains; /// Implementation of the template. template struct TypeListContains, T> { static constexpr bool Value = std::conditional, 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::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 struct TypeListSubsetOf; /// Specialization for the case when all the elements of the original \p ListA /// was found in \p ListB. template struct TypeListSubsetOf { static constexpr bool Value = true; }; /// Specializaton for the case when an element of the original \p ListA cannot /// be found in \p ListB. template struct TypeListSubsetOf { static constexpr bool Value = false; }; /// Definition for the general case. template struct TypeListSubsetOf, List> : TypeListSubsetOf, List, TypeListContains::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