Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10706091
type_numbers.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
7 KB
Referenced Files
None
Subscribers
None
type_numbers.hpp
View Options
/**************************************************************************//**
*
* \file rosa/support/type_numbers.hpp
*
* \author David Juhasz (david.juhasz@tuwien.ac.at)
*
* \date 2017
*
* \brief Facilities for registering supported types and representing them with
* numbers.
*
* \note This implementation is partially based on the `type_number`
* implementation of CAF.
* \todo Check license.
*
******************************************************************************/
#ifndef ROSA_SUPPORT_TYPE_NUMBERS_HPP
#define ROSA_SUPPORT_TYPE_NUMBERS_HPP
#include
"rosa/support/atom.hpp"
#include
"rosa/support/math.hpp"
#include
"rosa/support/squashed_int.hpp"
#include
"rosa/support/type_helper.hpp"
#include
"rosa/support/types.hpp"
#include
<array>
#include
<string>
namespace
rosa
{
/// Compile-time list of all built-in types.
/// \note Appending new types to the end of this list maintains backward
/// compatibility in the sense that old builtin types have the same type number
/// associated to them in both the old and new versions. But changing any of
/// the already present types in the list breaks that backward compatibility.
/// Should compatibility be broken, step `rosa::TypeNumberVersion` below!
/// \note Keep this list in sync with the definition of
/// `rosa::NumberedTypeNames`.
using
BuiltinTypes
=
TypeList
<
AtomValue
,
///< atom
int16_t
,
///< i16
int32_t
,
///< i32
int64_t
,
///< i64
int8_t
,
///< i8
long
double
,
///< ldouble
std
::
string
,
///< str
uint16_t
,
///< u16
uint32_t
,
///< u32
uint64_t
,
///< u64
uint8_t
,
///< u8
unit_t
,
///< unit
bool
,
///< bool
double
,
///< double
float
///< float
>
;
/// Indicates the version number of `rosa::BuiltinTypes`. Software with the same
/// version number are supposed to have backward compatible type numbering.
/// \sa `rosa::BultinTypes` on backward compatibility.
constexpr
size_t
TypeNumberVersion
=
0
;
/// The number of built-in types.
static
constexpr
size_t
NumberOfBuiltinTypes
=
TypeListSize
<
BuiltinTypes
>::
Value
;
/// Anonymous namespace for helper facilities, consider it private.
namespace
{
/// Tells if a type is not `rosa::UnitType`.
///
/// \tparam T the type to check
template
<
typename
T
>
struct
IsNotUnitType
{
/// Denotes if `T` is the `rosa::UnitType` or not.
static
constexpr
bool
Value
=
!
std
::
is_same
<
T
,
UnitType
>::
value
;
};
}
// End namespace
/// Integer type to store type numbers.
/// \note The narrowest unsigned integer type that is wide enough to represent
/// `rosa::NumberOfBuiltinTypes` different values.
using
type_nr_t
=
typename
TypeListFind
<
typename
TypeListDrop
<
log2
(
NumberOfBuiltinTypes
)
/
8
,
IntegerTypesBySize
>::
Type
,
IsNotUnitType
>::
Type
::
Second
;
/// Turn `rosa::type_nr_t` into a strongly typed enumeration.
///
/// Values of `rosa::type_nr_t` casted to `rosa::TypeNumbers` can be used in a
/// type-safe way.
enum
class
TypeNumber
:
type_nr_t
{};
/// A type to cast type numbers into in order to output them to streams as
/// numbers and not ASCII-codes.
/// \note Use it for safety, necessary for printing `uint8_t` values.
using
printable_tn_t
=
printable_t
<
type_nr_t
>
;
/// Casts a `rosa::TypeNumber` into `rosa::printable_tn_t`.
///
/// \param TN `TypeNumber` to cast.
#define PRINTABLE_TN(TN) static_cast<printable_tn_t>(TN)
/// Converts a `rosa::TypeNumber` into `std::string`.
///
/// \param TN `TypeNumber` to convert
///
/// \return `string` representing `TN`
inline
std
::
string
to_string
(
const
TypeNumber
TN
)
{
return
std
::
to_string
(
static_cast
<
type_nr_t
>
(
TN
));
}
/// \name TypeNumberOf
/// \brief Computes `rosa::TypeNumber` for a type.
///
/// The `rosa::TypeNumber` for a type `T` can be obtained as \code
/// TypeNumberOf<T>::Value
/// \endcode
///
/// \note `rosa::TypeNumber` for a type is based on the corresponding squashed
/// type, except for `bool` and `rosa::AtomConstant` types.
///
/// \sa `rosa::SquashedType`˛
///
/// \note `rosa::TypeNumber` is the index of the type in `rosa::BuiltinTypes`
/// starting from `1`, index `0` indicates a non-builtin type.
///@{
/// Definition of the template for the general case.
///
/// \tparam T type to get `TypeNumber` for
template
<
typename
T
>
struct
TypeNumberOf
{
static
constexpr
TypeNumber
Value
=
static_cast
<
TypeNumber
>
(
TypeListIndexOf
<
BuiltinTypes
,
squashed_t
<
T
>>::
Value
+
1
);
};
/// Specialization for the `bool` type.
template
<>
struct
TypeNumberOf
<
bool
>
{
static
constexpr
TypeNumber
Value
=
static_cast
<
TypeNumber
>
(
TypeListIndexOf
<
BuiltinTypes
,
bool
>::
Value
+
1
);
};
/// Specialization for the `rosa::AtomConstant` type.
///
/// \note For a `rosa::AtomConstant` type, `rosa::TypeNumber` is based on the
/// `rosa::AtomValue` wrapped into the actual `rosa::AtomConstant`.
template
<
AtomValue
V
>
struct
TypeNumberOf
<
AtomConstant
<
V
>>
{
static
constexpr
TypeNumber
Value
=
TypeNumberOf
<
AtomValue
>::
Value
;
};
///@}
/// List of type names for all builtin-types, indexed via `rosa::TypeNumber`.
///
/// \note Keep this definition in sync with `rosa::BuiltinTypes`.
constexpr
std
::
array
<
const
char
*
,
NumberOfBuiltinTypes
>
NumberedTypeNames
{{
"atom"
,
"i16"
,
"i32"
,
"i64"
,
"i8"
,
"ldouble"
,
"str"
,
"u16"
,
"u32"
,
"u64"
,
"u8"
,
"unit"
,
"bool"
,
"double"
,
"float"
}};
/// Tells if a `rosa::TypeNumber` is valid in the software.
///
/// \note A `rosa::TypeNumber` generated by an incompatible version may be valid
/// but may denote a type that is different from the `rosa::TypeNumber` denotes
/// in the current software. That is why this validation needs to be done in
/// connection to checking `rosa::TypeNumberVersion` as well.
///
/// \param TN `TypeNumber` to validate in the context of the current software
///
/// \return Whether `TN` is valid in the current software
constexpr
bool
validTypeNumber
(
const
TypeNumber
TN
)
{
// \todo Duplication of static_cast into a const variable would be
// possible in C++14.
return
0
<
static_cast
<
type_nr_t
>
(
TN
)
&&
static_cast
<
type_nr_t
>
(
TN
)
<=
NumberOfBuiltinTypes
;
}
/// Provides information about the type corresponding to a `rosa::TypeNumber`.
///
/// \tparam TN `TypeNumber` to get information for
///
/// \pre `TN` is a valid `TypeNumber`:\code
/// validTypeNumber(TN)
/// \endcode
template
<
TypeNumber
TN
>
struct
TypeForNumber
{
STATIC_ASSERT
(
validTypeNumber
(
TN
),
"not a valid type number"
);
/// `TN` as `rosa::type_nr_t`.
static
constexpr
type_nr_t
TNI
=
static_cast
<
type_nr_t
>
(
TN
);
/// The builtin-type corresponding to `TN`.
using
Type
=
typename
TypeListAt
<
BuiltinTypes
,
TNI
-
1
>::
Type
;
/// The size of `Type`.
static
constexpr
size_t
Size
=
sizeof
(
Type
);
/// Textual representation of the builtin-type.
static
constexpr
const
char
*
Name
=
NumberedTypeNames
[
TNI
-
1
];
};
}
// End namespace rosa
#endif
// ROSA_SUPPORT_TYPE_NUMBERS_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, May 31, 4:44 PM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
328229
Default Alt Text
type_numbers.hpp (7 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment