Page MenuHomePhorge

type_token.hpp
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

type_token.hpp

/******************************************************************************
*
* 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");
// 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)
// Nested namespace for protecting constants related to type tokens.
namespace token {
// The number of bits in one token.
constexpr size_t TokenBits = sizeof(token_t) * 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_t Token = 0;
};
template <typename T, typename... Ts>
struct TypeListTokenImpl<TypeList<T, Ts...>> {
static constexpr type_nr_t TN = TypeNumber<T>::Value;
// Check if the generated type number is valid.
STATIC_ASSERT(validTypeNumber(TN), "non-builtin type");
static constexpr token_t Token =
(TypeListTokenImpl<TypeList<Ts...>>::Token << token::RepresentationBits) |
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_t Token = TypeListTokenImpl<List>::Token;
};
// 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 Token.
// NOTE: The returned type number is not validated.
inline type_nr_t typeNumberOfHeadOfToken(const token_t Token) {
return static_cast<type_nr_t>(Token & ((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 Token);
// Tells if the token does encode an empty list.
bool emptyToken(const token_t Token);
// Tells the full memory size of the list encoded in the token.
// PRE: validToken(Token)
size_t sizeOfToken(const token_t Token);
// Tells the memory size of the first type encoded in the token.
// PRE: !empty(Token) && validToken(Token)
size_t sizeOfHeadOfToken(const token_t Token);
// Tells the name of the first type encoded in the token.
// PRE: !empty(Token) && validToken(Token)
const char *nameOfHeadOfToken(const token_t Token);
// Drops the head element of the encoded list.
void dropHeadOfToken(token_t &Token);
// Tells if the head of the encoded list is of type T.
// PRE: !empty(Token) && validToken(Token)
template <typename T>
bool isHeadOfTokenTheSameType(const token_t Token) {
ASSERT(!emptyToken(Token) && validToken(Token));
return TypeNumber<T>::Value == typeNumberOfHeadOfToken(Token);
}
} // End namespace rosa
#endif // ROSA_SUPPORT_TYPE_TOKEN_HPP

File Metadata

Mime Type
text/x-c++
Expires
Sat, Aug 29, 2:02 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
374923
Default Alt Text
type_token.hpp (6 KB)

Event Timeline