Page MenuHomePhorge

type_numbers.hpp
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

type_numbers.hpp

/******************************************************************************
*
* 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)
// Converts a TypeNumber into string.
inline std::string to_string(const TypeNumber TN) {
return std::to_string(static_cast<type_nr_t>(TN));
}
// 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 TypeNumberOf {
static constexpr TypeNumber Value =
static_cast<TypeNumber>(TypeListIndexOf<BuiltinTypes, T>::Value + 1);
};
template <typename T> struct TypeNumberOf<T, true> {
using Type = squashed_int_t<T>;
static constexpr TypeNumber Value =
static_cast<TypeNumber>(TypeListIndexOf<BuiltinTypes, Type>::Value + 1);
};
template <> struct TypeNumberOf<bool, true> {
static constexpr TypeNumber Value =
static_cast<TypeNumber>(TypeListIndexOf<BuiltinTypes, bool>::Value + 1);
};
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 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(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[TNI - 1];
};
} // End namespace rosa
#endif // ROSA_SUPPORT_TYPE_NUMBERS_HPP

File Metadata

Mime Type
text/x-c++
Expires
Fri, Jul 4, 7:58 AM (53 m, 8 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157543
Default Alt Text
type_numbers.hpp (5 KB)

Event Timeline