Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1494486
AppTuple.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
12 KB
Referenced Files
None
Subscribers
None
AppTuple.hpp
View Options
//===-- 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
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Mar 1, 6:45 PM (23 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
285476
Default Alt Text
AppTuple.hpp (12 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment