Page MenuHomePhorge

AppTuple.hpp
No OneTemporary

Size
12 KB
Referenced Files
None
Subscribers
None

AppTuple.hpp

//===-- rosa/app/AppTuple.hpp -----------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/app/AppTuple.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2019-2020
///
/// \brief Facilities for handling multiple input/output values for connections
/// in the *application interface*.
///
/// \see \c rosa::app::Application
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_APP_APPTUPLE_HPP
#define ROSA_APP_APPTUPLE_HPP
#include "rosa/support/sequence.hpp"
#include "rosa/support/type_token.hpp"
#include <ostream>
#include <tuple>
namespace rosa {
namespace app {
/// A tuple to manage multiple input/output values in the *application
/// interface*.
///
/// \tparam Ts types of elements of the tuple
///
/// \note The template may be instantiated only with built-in types and the
/// number of those type may not exceed the capacity of a \c rosa::Token.
template <typename... Ts> struct AppTuple : public std::tuple<Ts...> {
// Statically enforce that the class template is instantiated only with
// built-in types.
STATIC_ASSERT((TypeListSubsetOf<TypeList<Ts...>, BuiltinTypes>::Value),
"not built-in types");
// Statically enforce that the class template is instantiated with not too
// many types.
// \note Instantiation would fail on \c rosa::app::AppTuple::TT if there
// are too many types; this assertion is for more readable error reporting.
STATIC_ASSERT(sizeof...(Ts) <= token::MaxTokenizableListSize,
"Too many types");
/// How many elements the instance has.
static constexpr token_size_t Length = sizeof...(Ts);
/// What types the class contains.
///
/// Type information encoded as \c rosa::Token.
static constexpr Token TT = TypeToken<Ts...>::Value;
/// Default constructor, zero-initializes elements.
AppTuple(void) = default;
/// Constructor, initializes the underlying \c std::tuple with lvalue
/// references.
///
/// \param Args value references to the values to store
AppTuple(const std::decay_t<Ts> &... Args) : std::tuple<Ts...>(Args...) {}
/// Constructor, initializes the underlying \c std::tuple with rvalue
/// references.
///
/// \param Args rvalue references to the values to store
AppTuple(std::decay_t<Ts> &&... Args)
: std::tuple<Ts...>(std::move(Args)...) {}
/// Contructor, initializes the underlying \c std::tuple from another matching
/// \c std::tuple.
AppTuple(const std::tuple<Ts...> &Args) : std::tuple<Ts...>(Args) {}
/// Default copy-constructor.
AppTuple(const AppTuple &) = default;
/// Default move-constructor.
AppTuple(AppTuple &&) = default;
/// Default copy-assignment.
AppTuple &operator=(const AppTuple &) = default;
/// Default move-assignment.
AppTuple &operator=(AppTuple &&) = default;
private:
/// Dumps \p this object to a given \c std::ostream.
///
/// \note Provides implementation for \c rosa::app::AppTuple::dump.
///
/// \tparam S0 Indices for accessing elements.
///
/// \param [in,out] OS output stream to dump to
///
/// \note The second argument provides indices statically as template
/// arguments \p S0..., so its actual value is ignored.
///
/// \pre Statically, \p S0... matches number of types \p this object was
/// created: \code
/// sizeof...(S0) == sizeof...(Ts)
/// \endcode
template <size_t... S0>
void dump(std::ostream &OS, Seq<S0...>) const noexcept;
public:
/// Dumps \p this object to a given \c std::ostream.
///
/// \param [in,out] OS output stream to dump to
void dump(std::ostream &OS) const noexcept;
};
template <typename... Ts>
template <size_t... S0>
void AppTuple<Ts...>::dump(std::ostream &OS, Seq<S0...>) const noexcept {
STATIC_ASSERT(sizeof...(S0) == sizeof...(Ts), "inconsistent type arguments");
// Convert value to std::string with std::to_string except for a value of
// std::string that does not need conversion.
auto dump_to_string = [](const auto &V) {
if constexpr (std::is_same<std::decay_t<decltype(V)>, std::string>::value) {
return V;
} else {
return std::to_string(V);
}
};
OS << "{";
(OS << ... << (" " + dump_to_string(std::get<S0>(*this))));
OS << " }";
}
template <typename... Ts>
void AppTuple<Ts...>::dump(std::ostream &OS) const noexcept {
dump(OS, seq_t<sizeof...(Ts)>());
}
/// Type alias for a \c rosa::app::AppTuple that contains no elements.
using EmptyAppTuple = AppTuple<>;
/// Template specialization for \c rosa::app::EmptyAppTuple.
template <> struct AppTuple<> : public std::tuple<> {
/// How many elements the instance has.
static constexpr token_size_t Length = 0;
/// What types the class contains.
///
/// Type information encoded as \c rosa::Token.
static constexpr Token TT = TypeToken<>::Value;
/// Constructor, initializes the underlying \c std::tuple.
AppTuple(void) : std::tuple<>() {}
/// Default copy-constructor.
AppTuple(const AppTuple &) = default;
// Default move-constructor.
AppTuple(AppTuple &&) = default;
/// Default copy-assignment.
AppTuple &operator=(const AppTuple &) = default;
// Default move-assignment,
AppTuple &operator=(AppTuple &&) = default;
/// Dumps \p this object to a given \c std::ostream.
///
/// \param [in,out] OS output stream to dump to
static void dump(std::ostream &OS) noexcept;
};
/// Creates a \c rosa::app::AppTuple instance from the given lvalues
/// references.
///
/// \tparam Ts types of elements of the tuple
///
/// \see \c rosa::app::AppTuple
///
/// \param Args values to store in the tuple
///
/// \return an instance of \c rosa::app::AppTuple<Ts...> with \p Args as
/// elements
template <typename... Ts>
inline AppTuple<Ts...> make_app_tuple(const Ts &... Args) noexcept {
return AppTuple<Ts...>(Args...);
}
/// Creates a \c rosa::app::AppTuple instance from the given rvalue
/// references.
///
/// \tparam Ts types of elements of the tuple
///
/// \see \c rosa::app::AppTuple
///
/// \param Args values to store in the tuple
///
/// \return an instance of \c rosa::app::AppTuple<Ts...> with \p Args as
/// elements
template <typename... Ts>
inline AppTuple<Ts...> make_app_tuple(Ts &&... Args) noexcept {
return AppTuple<Ts...>(std::move(Args)...);
}
/// Creates a \c rosa::app::AppTuple instance from the given \c std::tuple
/// reference.
///
/// \tparam Ts types of elements of the tuple
///
/// \see \c rosa::app::AppTuple
///
/// \param Args values to store in the tuple
///
/// \return an instance of \c rosa::app::AppTuple<Ts...> with \p Args as
/// elements
template <typename... Ts>
inline AppTuple<Ts...> make_app_tuple(const std::tuple<Ts...> &Args) noexcept {
return AppTuple<Ts...>(Args);
}
/// \defgroup UnwrapAppTuple Implementation of
/// rosa::app::UnwrapAppTuple
///
/// \brief Unwraps element types from an instance of \c
/// rosa::app::AppTuple into a \c rosa::TypeList
///
/// Types can be unwrapped from a \c rosa::app::AppTuple instance as \code
/// typename UnwrapAppTuple<List>::Type
/// \endcode
///
/// For example, the following expression evaluates to `true`: \code
/// std::is_same<typename UnwrapAppTuple<AppTuple<T1, T2>>::Type,
/// TypeList<T1, T2>>::value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam Tuple \c rosa::app::AppTuple to unwrap
template <typename Tuple> struct UnwrapAppTuple;
/// Implementation of the template for \c rosa::app::AppTuple instances.
template <typename... Ts> struct UnwrapAppTuple<AppTuple<Ts...>> {
using Type = TypeList<Ts...>;
};
///@}
///@}
/// \defgroup IsTuple Implementation of \c rosa::app::IsTuple
///
/// \brief Tells if a type is a tuple as in it can be converted to \c
/// rosa::app::AppTuple.
///
/// \see \c rosa::app::MatchingAppTuple
///
/// Whether a type \c T is a tuple can be checked as \code
/// IsTuple<T>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam T type to check
template <typename T> struct IsTuple;
/// Specialization for the case when the type is an instance of \c std::tuple.
template <typename... Ts> struct IsTuple<std::tuple<Ts...>> {
static constexpr bool Value = true;
};
/// Specialization for the case when the type is an instance of \c std::tuple.
template <typename... Ts> struct IsTuple<AppTuple<Ts...>> {
static constexpr bool Value = true;
};
/// Implementation for a general case of type \p T.
template <typename T> struct IsTuple { static constexpr bool Value = false; };
///@}
/// \defgroup IsAppTuple Implementation of \c rosa::app::IsAppTuple
///
/// \brief Tells if a type is an instance of \c rosa::app::AppTuple.
///
/// Whether a type \c T is an instance of \c rosa::app::AppTuple can be
/// checked as \code
/// IsAppTuple<T>::Value
/// \endcode
///
/// \note `!IsAppTuple<T>::Value || IsTuple<T>::Value`
///@{
/// Declaration of the template.
///
/// \tparam T type to check
template <typename T> struct IsAppTuple;
/// Specialization for the case when the type is an instance of \c
/// rosa::app::AppTuple.
template <typename... Ts> struct IsAppTuple<AppTuple<Ts...>> {
static constexpr bool Value = true;
};
/// Implementation for a general case of type \p T.
template <typename T> struct IsAppTuple {
static constexpr bool Value = false;
};
///@}
/// \defgroup MatchingAppTuple Implementation of \c
/// rosa::app::MatchingAppTuple
///
/// \brief Gives the \c rosa::app::AppTuple type that matches a given
/// tuple type.
///
/// The matching \c rosa::app::AppTuple type for a tuple type \p T can be
/// obtained as \code
/// typename MatchingAppTuple<T>::Type
/// \endcode
/// If \p T is \c rosa::app::AppTuple, the matching type is \p T itself.
/// If \p T is \c std::tuple, the matching type if \c rosa::app::AppTuple
/// with the same type parameters as \p T.
/// \c rosa::app::MatchingAppTuple is not defined for other type
/// parameters.
///
/// \note The template is defined for type \p T only if
/// `rosa::app::IsTuple<T>::Value`. Values of such types can be used to
/// construct a new instance of the class \c rosa::app::AppTuple.
///
///\see \c rosa::app::IsTuple
///@{
/// Declaration of the template.
///
/// \tparam T type to check
template <typename T> struct MatchingAppTuple;
/// Specialization for the case when the type is an instance of \c
/// rosa::app::AppTuple.
template <typename... Ts> struct MatchingAppTuple<AppTuple<Ts...>> {
using Type = AppTuple<Ts...>;
};
/// Specialization for the case when the type is an instance of \c
/// std::tuple.
template <typename... Ts> struct MatchingAppTuple<std::tuple<Ts...>> {
using Type = AppTuple<Ts...>;
};
///@}
/// Convenience template type alias for easy use of \c
/// rosa::app::MatchingAppTuple.
///
/// Converts a tuple type to the matching \c rosa::app::AppTuple type.
///
/// \tparam Tuple type to convert
template <typename Tuple>
using matching_app_tuple_t = typename MatchingAppTuple<Tuple>::Type;
/// \defgroup TypeListAllAppTuple Implementation of
/// \c rosa::app::TypeListAllAppTuple
///
/// \brief Tells if all types in a \c rosa::TypeList is an instance of \c
/// rosa::app::AppTuple.
///
/// Whether a \c rosa::TypeList \c List contains instances of \c
/// rosa::app::AppTuple only can be checked as \code
/// TypeListAllAppTuple<List>::Value
/// \endcode
///@{
/// Declaration of the template.
///
/// \tparam List \c rosa::TypeList to check
template <typename List> struct TypeListAllAppTuple;
/// Specialization for \c rosa::EmptyTypeList.
template <> struct TypeListAllAppTuple<EmptyTypeList> {
static constexpr bool Value = true;
};
/// Implementation for the general case when there is at leasst one element in
/// the list.
template <typename T, typename... Ts>
struct TypeListAllAppTuple<TypeList<T, Ts...>> {
static constexpr bool Value =
IsAppTuple<T>::Value && TypeListAllAppTuple<TypeList<Ts...>>::Value;
};
///@}
} // End namespace app
} // End namespace rosa
namespace std {
/// Dumps a \c rosa::app::App instance to a given \c std::ostream.
///
/// \param [in,out] OS output stream to dump to
/// \param Tuple \c rosa::app::App to dump
///
/// \return \p OS after dumping \p Tuple to it
template <typename... Ts>
ostream &operator<<(ostream &OS, const rosa::app::AppTuple<Ts...> &Tuple) {
Tuple.dump(OS);
return OS;
}
} // End namespace std
#endif // ROSA_APP_APPTUPLE_HPP

File Metadata

Mime Type
text/x-c++
Expires
Sun, Mar 1, 6:45 PM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
285476
Default Alt Text
AppTuple.hpp (12 KB)

Event Timeline