diff --git a/include/rosa/support/type_numbers.hpp b/include/rosa/support/type_numbers.hpp index 9eb6e28..01b65bf 100644 --- a/include/rosa/support/type_numbers.hpp +++ b/include/rosa/support/type_numbers.hpp @@ -1,168 +1,168 @@ /****************************************************************************** * * 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 #include 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; // 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::Value; // Anonymous namespace for helper facilities, consider it private. namespace { // Tells if T is not UnitType. template struct IsNotUnitType { static constexpr bool Value = !std::is_same::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::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(N) // Converts a TypeNumber into string. inline std::string to_string(const TypeNumber TN) { return std::to_string(static_cast(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 ::value> struct TypeNumberOf { static constexpr TypeNumber Value = static_cast(TypeListIndexOf::Value + 1); }; template struct TypeNumberOf { using Type = squashed_int_t; static constexpr TypeNumber Value = static_cast(TypeListIndexOf::Value + 1); }; template <> struct TypeNumberOf { static constexpr TypeNumber Value = static_cast(TypeListIndexOf::Value + 1); }; template struct TypeNumberOf, false> { static constexpr TypeNumber Value = TypeNumberOf::Value; }; // List of all type names, indexed via TypeNumber. // NOTE: Keep this definition in sync with BuiltinTypes. constexpr std::array 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. + // possible in C++14. return 0 < static_cast(TN) && static_cast(TN) <= NumberOfBuiltinTypes; } // Computes the corresponding builtin type with some information from a type // number. // PRE: validTypeNumber(TN) template struct TypeForNumber { STATIC_ASSERT(validTypeNumber(TN), "not a valid type number"); static constexpr type_nr_t TNI = static_cast(TN); using Type = typename TypeListAt::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