Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1493539
type_token.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
6 KB
Referenced Files
None
Subscribers
None
type_token.hpp
View Options
/******************************************************************************
*
* File: type_token.hpp
*
* Contents: Facilities for encoding TypeLists as unsigned integer values.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#ifndef ROSA_SUPPORT_TYPE_TOKEN_HPP
#define ROSA_SUPPORT_TYPE_TOKEN_HPP
#include
"rosa/support/type_numbers.hpp"
namespace
rosa
{
// NOTE on compatibility between different versions of the type token
// implementation:
// Different software versions produce compatible type tokens as long as
// backward compatibility of BuiltinTypes is maintained (denoted by
// TypeNumberVersion, see a note on that) and the type token implementation
// uses the same type as token_t (boiling down to the same token::TokenBits
// value) and the same token::RepresentationBits value. Thus, interacting
// software need to cross-validate the aforementioned values to check
// compatibility. Interoperation between compatible sofware is limited to
// backward compatiblity, that is builtin types defined in both software
// versions are handled correctly but a newer system may produce a type token
// which is invalid in an old one. Therefore, tokens obtained from a compatible
// remote system need to be validated.
// Integer type to store type tokens.
// NOTE: The trade-off between the binary overhead of type encoding and the
// maximal size of encodable lists can be tuned by using unsigned integer types
// of different widths as token_t.
using
token_t
=
uint64_t
;
// Sanity check in case someone would change token_t.
STATIC_ASSERT
(
std
::
is_unsigned
<
token_t
>::
value
,
"token_t is not an unsigned integer"
);
// Turn token_t into a strongly typed enumeration, so Tokens can be used in a
// type-safe way.
enum
class
Token
:
token_t
{};
// A type to cast tokens 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_token_t
=
PRINTABLE
(
token_t
);
// Helper preprocessor macro to cast tokens into printable_token_t.
#define PRINTABLE_TOKEN(T) static_cast<printable_token_t>(T)
// Converts a Token into string.
inline
std
::
string
to_string
(
const
Token
T
)
{
return
std
::
to_string
(
static_cast
<
token_t
>
(
T
));
}
// Nested namespace for protecting constants related to type tokens.
namespace
token
{
// The number of bits in one token.
constexpr
size_t
TokenBits
=
sizeof
(
Token
)
*
8
;
// The number of bits a builtin type can be uniquely encoded into, that is any
// valid TypeNumber can fit into.
// NOTE: There is one extra bit position added for encoding so that providing a
// better chance to maintain backward comaptibility when BuiltinTypes is
// extended.
constexpr
size_t
RepresentationBits
=
log2
(
NumberOfBuiltinTypes
)
+
1
;
// Maximal size of uniquely tokenizable TypeList.
constexpr
size_t
MaxTokenizableListSize
=
TokenBits
/
RepresentationBits
;
}
// End namespace token
// Generates a token, unsigned integer representation, for the TypeList.
// NOTE: The TypeList cannot have more than MaxTokenizableListSize elements and
// must be a subset of BuiltinTypes with respect to squashed integers.
// NOTE: A generated token uniquely represents a list of types, except for
// AtomConstant types. Observe that any AtomConstant is encoded as the type
// AtomValue. The type information on all separate AtomConstant types are lost
// and replaced by the AtomValue type whose actual value needs to be considered
// in order to obtain the original AtomConstant type and so the full type
// information on the encoded TypeList.
template
<
typename
List
>
struct
TypeListTokenImpl
;
template
<>
struct
TypeListTokenImpl
<
EmptyTypeList
>
{
static
constexpr
Token
Value
=
static_cast
<
Token
>
(
0
);
};
template
<
typename
T
,
typename
...
Ts
>
struct
TypeListTokenImpl
<
TypeList
<
T
,
Ts
...
>>
{
static
constexpr
TypeNumber
TN
=
TypeNumberOf
<
T
>::
Value
;
// Check if the generated type number is valid.
STATIC_ASSERT
(
validTypeNumber
(
TN
),
"non-builtin type"
);
static
constexpr
Token
Value
=
static_cast
<
Token
>
(
(
static_cast
<
token_t
>
(
TypeListTokenImpl
<
TypeList
<
Ts
...
>>::
Value
)
<<
token
::
RepresentationBits
)
|
static_cast
<
type_nr_t
>
(
TN
));
};
template
<
typename
List
>
struct
TypeListToken
;
template
<
typename
...
Ts
>
struct
TypeListToken
<
TypeList
<
Ts
...
>>
{
// NOTE: TypeNumber is computed against squased_int_t for integral types, so
// let's do the same here.
using
List
=
typename
SquashedTypeList
<
TypeList
<
Ts
...
>>::
Type
;
// Check the length of the list here.
// NOTE: Type validation is done one-by-one in TypeListTokenImpl.
STATIC_ASSERT
((
TypeListSize
<
List
>::
Value
<=
token
::
MaxTokenizableListSize
),
"too long list of types"
);
static
constexpr
Token
Value
=
TypeListTokenImpl
<
List
>::
Value
;
};
// Convenience template turning a list of types into a TypeList to generate
// TypeListToken for it.
template
<
typename
...
Ts
>
using
TypeToken
=
TypeListToken
<
TypeList
<
Ts
...
>>
;
// Anonymous namespace with helper facilities, consider it private.
namespace
{
// Extracts the type number of the first encoded type of T.
// NOTE: The returned type number is not validated.
inline
TypeNumber
typeNumberOfHeadOfToken
(
const
Token
T
)
{
return
static_cast
<
TypeNumber
>
(
static_cast
<
token_t
>
(
T
)
&
((
1
<<
token
::
RepresentationBits
)
-
1
));
}
}
// End namespace
// Tells if the given Token is valid, can be decoded by the current software.
// NOTE: Validation gives a correct result only when Token was generated by a
// compatible software (see note above).
bool
validToken
(
const
Token
T
);
// Tells if the token does encode an empty list.
bool
emptyToken
(
const
Token
T
);
// Tells how many types are encoded in T.
size_t
lengthOfToken
(
const
Token
T
);
// Tells the full memory size of the list encoded in T.
// PRE: validToken(T)
size_t
sizeOfValuesOfToken
(
const
Token
T
);
// Tells the memory size of the first type encoded in T.
// PRE: !empty(T) && validToken(T)
size_t
sizeOfHeadOfToken
(
const
Token
T
);
// Tells the name of the first type encoded in T.
// PRE: !empty(T) && validToken(T)
const
char
*
nameOfHeadOfToken
(
const
Token
T
);
// Drops the head element of the encoded list.
void
dropHeadOfToken
(
Token
&
T
);
// Drops the first N element of the encoded list.
void
dropNOfToken
(
Token
&
T
,
const
size_t
N
);
// Tells if the head of the encoded list is of type Type.
// PRE: !empty(T) && validToken(T)
template
<
typename
Type
>
bool
isHeadOfTokenTheSameType
(
const
Token
T
)
{
ASSERT
(
!
emptyToken
(
T
)
&&
validToken
(
T
));
return
TypeNumberOf
<
Type
>::
Value
==
typeNumberOfHeadOfToken
(
T
);
}
}
// End namespace rosa
#endif
// ROSA_SUPPORT_TYPE_TOKEN_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, Mar 1, 5:19 PM (2 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
287522
Default Alt Text
type_token.hpp (6 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment