Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F19835027
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
24 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/examples/type-facilities/type-facilities.cpp b/examples/type-facilities/type-facilities.cpp
index a946c91..63611ec 100644
--- a/examples/type-facilities/type-facilities.cpp
+++ b/examples/type-facilities/type-facilities.cpp
@@ -1,85 +1,85 @@
/*******************************************************************************
*
* File: type-facilities.cpp
*
* Contents: An example showcasing various type-related support facilities.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#include "rosa/config/version.h"
#include "rosa/support/log.h"
#include "rosa/support/terminal_colors.h"
#include "rosa/support/type_token.hpp"
#include <iostream>
using namespace rosa;
using namespace rosa::terminal;
int main(void) {
LOG_INFO_STREAM << library_string() << " -- " << Color::Red
<< "type facilities" << Color::Default << std::endl;
auto &Log = LOG_TRACE_STREAM << std::endl;
Log << "NumberOfBuiltinTypes: " << NumberOfBuiltinTypes << std::endl
<< "TokenBits: " << token::TokenBits << std::endl
<< "RepresentationBits: " << token::RepresentationBits << std::endl
<< "MaxTokenizableListSize: " << token::MaxTokenizableListSize
<< std::endl
<< std::endl;
Log << "Type number information on 'uint8_t':" << std::endl;
- constexpr type_nr_t TN = TypeNumber<uint8_t>::Value;
+ constexpr TypeNumber TN = TypeNumberOf<uint8_t>::Value;
Log << " type number: " << PRINTABLE_TN(TN) << std::endl
<< " size: " << TypeForNumber<TN>::Size << std::endl
<< " name: " << TypeForNumber<TN>::Name << std::endl
<< std::endl;
Log << "Type number information of AtomConstants:"
<< std::endl;
using Atom1 = AtomConstant<atom("atom1")>;
using Atom2 = AtomConstant<atom("atom2")>;
Log << " std::is_same<Atom1, Atom2>::value: "
<< std::is_same<Atom1, Atom2>::value << std::endl
- << " TypeNumber<Atom1>::Value: "
- << PRINTABLE_TN(TypeNumber<Atom1>::Value) << std::endl
- << " TypeNumber<Atom2>::Value: "
- << PRINTABLE_TN(TypeNumber<Atom2>::Value) << std::endl
- << " name: " << TypeForNumber<TypeNumber<Atom1>::Value>::Name
+ << " TypeNumberOf<Atom1>::Value: "
+ << PRINTABLE_TN(TypeNumberOf<Atom1>::Value) << std::endl
+ << " TypeNumberOf<Atom2>::Value: "
+ << PRINTABLE_TN(TypeNumberOf<Atom2>::Value) << std::endl
+ << " name: " << TypeForNumber<TypeNumberOf<Atom1>::Value>::Name
<< std::endl
<< std::endl;
Log << "Type token information on 'TypeList<uint8_t, uint16_t>':"
<< std::endl;
// Token is generated statically.
- constexpr token_t Token = TypeToken<uint8_t, uint16_t>::Token;
- STATIC_ASSERT((Token == TypeListToken<TypeList<uint8_t, uint16_t>>::Token),
+ constexpr Token T = TypeToken<uint8_t, uint16_t>::Value;
+ STATIC_ASSERT((T == TypeListToken<TypeList<uint8_t, uint16_t>>::Value),
"alias template definition is wrong");
- token_t T = Token; // We need a non-const value for dropping head later.
+ Token T_ = T; // We need a non-const value for dropping head later.
// Iterate over encoded entries in Token.
- while (!emptyToken(T)) {
- Log << " token: " << PRINTABLE_TOKEN(T) << std::endl
- << " valid: " << validToken(T) << std::endl
- << " empty: " << emptyToken(T) << std::endl
- << " full size: " << sizeOfToken(T) << std::endl
- << " head type number: " << PRINTABLE_TN(typeNumberOfHeadOfToken(T))
+ while (!emptyToken(T_)) {
+ Log << " token: " << PRINTABLE_TOKEN(T_) << std::endl
+ << " valid: " << validToken(T_) << std::endl
+ << " empty: " << emptyToken(T_) << std::endl
+ << " full size: " << sizeOfToken(T_) << std::endl
+ << " head type number: " << PRINTABLE_TN(typeNumberOfHeadOfToken(T_))
<< std::endl
- << " size of head: " << sizeOfHeadOfToken(T) << std::endl
- << " name of head: " << nameOfHeadOfToken(T) << std::endl
- << " is head uint8_t: " << isHeadOfTokenTheSameType<uint8_t>(T)
+ << " size of head: " << sizeOfHeadOfToken(T_) << std::endl
+ << " name of head: " << nameOfHeadOfToken(T_) << std::endl
+ << " is head uint8_t: " << isHeadOfTokenTheSameType<uint8_t>(T_)
<< std::endl
- << " is head uint16_t: " << isHeadOfTokenTheSameType<uint16_t>(T)
+ << " is head uint16_t: " << isHeadOfTokenTheSameType<uint16_t>(T_)
<< std::endl
<< "Dropping head..." << std::endl;
- dropHeadOfToken(T);
+ dropHeadOfToken(T_);
}
// Here when Token became empty.
- Log << " token: " << PRINTABLE_TOKEN(T) << std::endl
- << " empty: " << emptyToken(T) << std::endl;
+ Log << " token: " << PRINTABLE_TOKEN(T_) << std::endl
+ << " empty: " << emptyToken(T_) << std::endl;
return 0;
}
diff --git a/include/rosa/support/type_numbers.hpp b/include/rosa/support/type_numbers.hpp
index f01b5af..ebd7362 100644
--- a/include/rosa/support/type_numbers.hpp
+++ b/include/rosa/support/type_numbers.hpp
@@ -1,155 +1,163 @@
/******************************************************************************
*
* File: type_numbers.hpp
*
* Contents: Facilities for registering supported types and representing them
* with numbers.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
* 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 TypeNumberVersion below!
// NOTE: Keep this list in sync with the definition of 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 BuiltinTypes. Software with the same version
// number are supposed to have backward compatible type numbering.
// NOTE: See note above on backward compatiblity of BultinTypes.
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 T is not UnitType.
template <typename T> struct IsNotUnitType {
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
// NumberOfBuiltinTypes different values.
using type_nr_t =
typename TypeListFind<typename TypeListDrop<log2(NumberOfBuiltinTypes) / 8,
IntegerTypesBySize>::Type,
IsNotUnitType>::Type::Second;
+// Turn type_nr_t into a strongly typed enumeration, so 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(type_nr_t);
// Helper preprocessor macro to cast type numbers into printable_tn_t.
#define PRINTABLE_TN(N) static_cast<printable_tn_t>(N)
// Computes the type number for T.
// NOTE: TypeNumber is the index of T in BuiltinTypes starting from 1,
// index 0 indicates a non-builtin type.
template <typename T, bool IsIntegral = std::is_integral<T>::value>
-struct TypeNumber {
- static constexpr type_nr_t Value =
- static_cast<type_nr_t>(TypeListIndexOf<BuiltinTypes, T>::Value + 1);
+struct TypeNumberOf {
+ static constexpr TypeNumber Value =
+ static_cast<TypeNumber>(TypeListIndexOf<BuiltinTypes, T>::Value + 1);
};
-template <typename T> struct TypeNumber<T, true> {
+template <typename T> struct TypeNumberOf<T, true> {
using Type = squashed_int_t<T>;
- static constexpr type_nr_t Value =
- static_cast<type_nr_t>(TypeListIndexOf<BuiltinTypes, Type>::Value + 1);
+ static constexpr TypeNumber Value =
+ static_cast<TypeNumber>(TypeListIndexOf<BuiltinTypes, Type>::Value + 1);
};
-template <> struct TypeNumber<bool, true> {
- static constexpr type_nr_t Value =
- static_cast<type_nr_t>(TypeListIndexOf<BuiltinTypes, bool>::Value + 1);
+template <> struct TypeNumberOf<bool, true> {
+ static constexpr TypeNumber Value =
+ static_cast<TypeNumber>(TypeListIndexOf<BuiltinTypes, bool>::Value + 1);
};
-template <AtomValue V> struct TypeNumber<AtomConstant<V>, false> {
- static constexpr type_nr_t Value = TypeNumber<AtomValue>::Value;
+template <AtomValue V> struct TypeNumberOf<AtomConstant<V>, false> {
+ static constexpr TypeNumber Value = TypeNumberOf<AtomValue>::Value;
};
// List of all type names, indexed via TypeNumber.
// NOTE: Keep this definition in sync with 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 the given TypeNumber is valid in the software.
// NOTE: A type number generated by an incompatible version may be valid but
// supposed to denote a type different than that in the current software.
-constexpr bool validTypeNumber(const type_nr_t TypeNumber) {
- return 0 < TypeNumber && TypeNumber <= NumberOfBuiltinTypes;
+constexpr bool validTypeNumber(const TypeNumber TN) {
+ // FIXME: 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;
}
// Computes the corresponding builtin type with some information from a type
// number.
-// PRE: validTypeNumber(TypeNumber)
-template <type_nr_t TypeNumber> struct TypeForNumber {
- STATIC_ASSERT(validTypeNumber(TypeNumber), "not a valid type number");
- using Type = typename TypeListAt<BuiltinTypes, TypeNumber - 1>::Type;
+// PRE: validTypeNumber(TN)
+template <TypeNumber TN> struct TypeForNumber {
+ STATIC_ASSERT(validTypeNumber(TN), "not a valid type number");
+ static constexpr type_nr_t TNI = static_cast<type_nr_t>(TN);
+ using Type = typename TypeListAt<BuiltinTypes, TNI - 1>::Type;
static constexpr size_t Size = sizeof(Type);
- static constexpr const char *Name = NumberedTypeNames[TypeNumber - 1];
+ static constexpr const char *Name = NumberedTypeNames[TNI - 1];
};
} // End namespace rosa
#endif // ROSA_SUPPORT_TYPE_NUMBERS_HPP
diff --git a/include/rosa/support/type_token.hpp b/include/rosa/support/type_token.hpp
index ee15d03..b164b86 100644
--- a/include/rosa/support/type_token.hpp
+++ b/include/rosa/support/type_token.hpp
@@ -1,158 +1,164 @@
/******************************************************************************
*
* 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)
// 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;
+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_t Token = 0;
+ static constexpr Token Value = static_cast<Token>(0);
};
template <typename T, typename... Ts>
struct TypeListTokenImpl<TypeList<T, Ts...>> {
- static constexpr type_nr_t TN = TypeNumber<T>::Value;
+ 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_t Token =
- (TypeListTokenImpl<TypeList<Ts...>>::Token << token::RepresentationBits) |
- TN;
+ 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_t Token = TypeListTokenImpl<List>::Token;
+ 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 Token.
+// Extracts the type number of the first encoded type of T.
// 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));
+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 Token);
+bool validToken(const Token T);
// Tells if the token does encode an empty list.
-bool emptyToken(const token_t Token);
+bool emptyToken(const Token T);
-// Tells the full memory size of the list encoded in the token.
-// PRE: validToken(Token)
-size_t sizeOfToken(const token_t Token);
+// Tells the full memory size of the list encoded in T.
+// PRE: validToken(T)
+size_t sizeOfToken(const Token T);
-// 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 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 the token.
-// PRE: !empty(Token) && validToken(Token)
-const char *nameOfHeadOfToken(const token_t Token);
+// 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 &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);
+void dropHeadOfToken(Token &T);
+
+// 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
diff --git a/lib/support/type_token.cpp b/lib/support/type_token.cpp
index 8fbd0d8..9e8a1aa 100644
--- a/lib/support/type_token.cpp
+++ b/lib/support/type_token.cpp
@@ -1,112 +1,114 @@
/******************************************************************************
*
* File: type_token.cpp
*
* Contents: Runtime part of type token handling.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#include "rosa/support/type_token.hpp"
// FIXME: Automatically generate a proper number of cases for the functions
// with a big number of mechanical cases in them below.
namespace rosa {
using namespace token;
-bool validToken(const token_t Token) {
- token_t T = Token;
+bool validToken(const Token T) {
+ Token T_ = T;
bool Valid = true;
- while (Valid && !emptyToken(T)) {
- Valid &= validTypeNumber(typeNumberOfHeadOfToken(T));
- dropHeadOfToken(T);
+ while (Valid && !emptyToken(T_)) {
+ Valid &= validTypeNumber(typeNumberOfHeadOfToken(T_));
+ dropHeadOfToken(T_);
}
return Valid;
}
-bool emptyToken(const token_t Token) { return Token == 0; }
+bool emptyToken(const Token T) { return static_cast<token_t>(T) == 0; }
-size_t sizeOfToken(const token_t Token) {
- ASSERT(validToken(Token));
- token_t T = Token;
+size_t sizeOfToken(const Token T) {
+ ASSERT(validToken(T));
+ Token T_ = T;
size_t S = 0;
- while (!emptyToken(T)) {
- S += sizeOfHeadOfToken(T);
- dropHeadOfToken(T);
+ while (!emptyToken(T_)) {
+ S += sizeOfHeadOfToken(T_);
+ dropHeadOfToken(T_);
}
return S;
}
#define SIZECASE(N) \
{ \
case N: \
- return TypeForNumber<N>::Size; \
+ return TypeForNumber<static_cast<TypeNumber>(N)>::Size; \
}
-size_t sizeOfHeadOfToken(const token_t Token) {
- ASSERT(!emptyToken(Token) && validToken(Token));
- switch (typeNumberOfHeadOfToken(Token)) {
+size_t sizeOfHeadOfToken(const Token T) {
+ ASSERT(!emptyToken(T) && validToken(T));
+ switch (static_cast<type_nr_t>(typeNumberOfHeadOfToken(T))) {
default: {
- // Should never come here when Token is valid and the case-list
- // below covers BuiltinTypes.
+ // Should never come here when T is valid and the case-list below covers
+ // BuiltinTypes.
ROSA_CRITICAL("unknown type number");
}
SIZECASE(1);
SIZECASE(2);
SIZECASE(3);
SIZECASE(4);
SIZECASE(5);
SIZECASE(6);
SIZECASE(7);
SIZECASE(8);
SIZECASE(9);
SIZECASE(10);
SIZECASE(11);
SIZECASE(12);
SIZECASE(13);
SIZECASE(14);
SIZECASE(15);
}
}
#define NAMECASE(N) \
{ \
case N: \
- return TypeForNumber<N>::Name; \
+ return TypeForNumber<static_cast<TypeNumber>(N)>::Name; \
}
-const char *nameOfHeadOfToken(const token_t Token) {
- ASSERT(!emptyToken(Token) && validToken(Token));
- switch (typeNumberOfHeadOfToken(Token)) {
+const char *nameOfHeadOfToken(const Token T) {
+ ASSERT(!emptyToken(T) && validToken(T));
+ switch (static_cast<type_nr_t>(typeNumberOfHeadOfToken(T))) {
default: {
- // Should never come here when Token is valid and the case-list
- // below covers BuiltinTypes.
+ // Should never come here when T is valid and the case-list below covers
+ // BuiltinTypes.
ROSA_CRITICAL("unknown type number");
}
NAMECASE(1);
NAMECASE(2);
NAMECASE(3);
NAMECASE(4);
NAMECASE(5);
NAMECASE(6);
NAMECASE(7);
NAMECASE(8);
NAMECASE(9);
NAMECASE(10);
NAMECASE(11);
NAMECASE(12);
NAMECASE(13);
NAMECASE(14);
NAMECASE(15);
}
}
-void dropHeadOfToken(token_t &Token) { Token >>= RepresentationBits; }
+void dropHeadOfToken(Token &T) {
+ T = static_cast<Token>(static_cast<token_t>(T) >> RepresentationBits);
+}
} // End namespace rosa
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Jul 12, 6:02 PM (18 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
351747
Default Alt Text
(24 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment