diff --git a/include/rosa/core/Unit.h b/include/rosa/core/Unit.h index f729d71..d9e479d 100644 --- a/include/rosa/core/Unit.h +++ b/include/rosa/core/Unit.h @@ -1,116 +1,116 @@ /***************************************************************************//** * * \file rosa/core/Unit.h * * \author David Juhasz (david.juhasz@tuwien.ac.at) * * \date 2017 * * \brief Declaration of `rosa::Unit` base-class. * ******************************************************************************/ #ifndef ROSA_CORE_UNIT_H #define ROSA_CORE_UNIT_H #include "rosa/support/atom.hpp" #include "rosa/core/forward_declarations.h" #include #include namespace rosa { /// Base class for every entity in a `rosa::System` that has to be identified /// and traced. /// /// \note Life-cycle of `rosa::Unit` instances is supposed to be managed by the /// `rosa::System` owning the instance, do not create and destroy any /// `rosa::Unit` directly. class Unit { public: /// Identifies the *kind* of `this` object. /// /// \note Kind is dependent on the `rosa::System` owning `this` object. const AtomValue Kind; /// Unique identifier for `this` object. /// /// The unique identifier is assigned by the `rosa::System` owning `this` /// object and is based on `rosa::System::CountUnits` of the owning /// `rosa::System`. const id_t Id; /// Textual identifier of `this` object. /// /// The textual identifier defaults to a text referring to `Id`, unless /// otherwise defined via an argument for the constructor. /// /// \note `Name` of a `rosa::Unit` instance is not necessarily unique in the /// owning `rosa::System`. const std::string Name; protected: /// The `rosa::System` owning `this` object. System &S; public: /// Full qualified name of `this` object. const std::string FullName; public: /// Creates a new instnace. /// /// \param Kind the kind of the new instance /// \param Id the unique identifier of the new instance /// \param Name the name of the new instance /// \param S `rosa::System` owning the new instance /// /// \pre `Name` is not empty:\code /// !Name.empty() /// \endcode Unit(const AtomValue Kind, const id_t Id, const std::string &Name, System &S) noexcept; /// No copying and moving of `rosa::Unit` instances is possible. ///@{ Unit(const Unit &) = delete; Unit(Unit &&) = delete; Unit &operator=(const Unit &) = delete; Unit &operator=(Unit &&) = delete; ///@} /// Destroys `this` object. virtual ~Unit(void); /// Dumps `this` object into a `std::string` for tracing purposes. /// /// Subclasses are supposed to override this function. /// /// \return `string` representing the state of `this` object virtual std::string dump(void) const noexcept; protected: /// Returns a reference to the `rosa::System` owning `this` object. /// /// \note Subclasses may override the function to return a reference of a /// subtype of `rosa::System`. /// /// \return reference of `S` virtual System &system() const noexcept; }; /// Dumps a `rosa::Unit` isntance to a given `std::ostream`. /// -/// \param [inout] OS output stream to dump to +/// \param [in,out] OS output stream to dump to /// \param U `Unit` to dump /// /// \return `OS` after dumping `U` to it std::ostream &operator<<(std::ostream &OS, const Unit &U); } // End namespace rosa #endif // ROSA_CORE_UNIT_H diff --git a/include/rosa/support/debug.hpp b/include/rosa/support/debug.hpp index 7fb42fa..a60c05e 100644 --- a/include/rosa/support/debug.hpp +++ b/include/rosa/support/debug.hpp @@ -1,124 +1,124 @@ /***************************************************************************//** * * \file rosa/support/debug.hpp * * \author David Juhasz (david.juhasz@tuwien.ac.at) * * \date 2017 * * \brief Facility for debugging * ******************************************************************************/ #ifndef ROSA_SUPPORT_DEBUG_HPP #define ROSA_SUPPORT_DEBUG_HPP #include "rosa/config/config.h" #include "rosa/support/type_helper.hpp" #include "rosa/support/terminal_colors.h" #include #include namespace rosa { /// Returns an output stream to use for debugging. std::ostream &dbgs(void); /// Prints an `std::array` to an `std::ostream`. /// /// \tparam T type of values stored in `A` /// \tparam Size number of elements in `A` /// -/// \param [inout] OS `ostream` to print to +/// \param [in,out] OS `ostream` to print to /// \param A `array` to print to `OS` /// /// \return `OS` after printing `A` template std::ostream &operator<<(std::ostream &OS, const std::array &A) { OS << '['; for (unsigned I = 0; I < Size; ++I) { if (I) { OS << ','; } OS << PRINTABLE(A[I]); } OS << ']'; return OS; } } // End namespace rosa /// \def ASSERT(stmt) /// \brief Enforces an assertion. /// /// \note Takes effect only when `ROSA_ENABLE_ASSERTIONS` is defined. /// /// Checks if `stmt` evaluates to true. If not, prints an error message about /// violating the assertion and aborts execution. /// /// \param stmt statement to evaluate, needs to be convertable to `bool` #ifndef ROSA_ENABLE_ASSERTIONS #define ASSERT(stmt) ROSA_IGNORE_UNUSED(stmt) #elif defined(ROSA_WINDOWS) #define ASSERT(stmt) \ if (static_cast(stmt) == false) { \ rosa::dbgs() << rosa::terminal::Color::Default << __FILENAME__ << ":" \ << __LINE__ << ": requirement failed: '" << #stmt << "'" \ << std::endl; \ ::abort(); \ } \ ROSA_VOID_STMT #else // defined(ROSA_LINUX) #include #define ASSERT(stmt) \ if (static_cast(stmt) == false) { \ rosa::dbgs() << rosa::terminal::Color::Default << __FILENAME__ << ":" \ << __LINE__ << ": requirement failed: '" << #stmt << "'" \ << std::endl; \ void *array[20]; \ auto bt_size = ::backtrace(array, 20); \ ::backtrace_symbols_fd(array, bt_size, 2); \ ::abort(); \ } \ ROSA_VOID_STMT #endif // defined(ROSA_ENABLE_ASSERTIONS) /// \def DEBUG(X) /// \brief Executes the given piece of code only if `NDEBUG` is not defined. /// /// \param X the code to execute /// \def DEBUGVAR(V) /// \brief Dumps the given variable to the default debug output. /// /// \param V the variable to dump /// /// \sa rosa::dbgs() #ifndef NDEBUG #define DEBUG(X) \ do { \ X; \ } while (false) #define DEBUGVAR(V) \ do { \ rosa::dbgs() << rosa::terminal::Color::Default << #V << " (" \ << __FILENAME__ << ":" << __LINE__ << "): " << (V) \ << std::endl; \ } while (false) #else // defined(NDEBUG) #define DEBUG(X) ROSA_IGNORE_UNUSED(X) #define DEBUGVAR(X) ROSA_IGNORE_UNUSED(X) #endif // defined(NDEBUG) /// Enforces static assertion. /// /// \param COND the condition to evaluate, must be statically evaluable /// \param DIAG error message if `COND` does not evaluate to `true` #define STATIC_ASSERT(COND, DIAG) static_assert((COND), DIAG) #endif // ROSA_SUPPORT_DEBUG_HPP diff --git a/include/rosa/support/log.h b/include/rosa/support/log.h index 8561e28..9067ada 100644 --- a/include/rosa/support/log.h +++ b/include/rosa/support/log.h @@ -1,257 +1,257 @@ /***************************************************************************//** * * \file rosa/support/log.h * * \author David Juhasz (david.juhasz@tuwien.ac.at) * * \date 2017 * * \brief Facility for logging. * * \note One call for the various logging macros is supposed to be used * for registering one log entry. That goes natural with the non-stream * implementations, which accept one string as argument. A more flexible way * for printing log entries, for example for colorizing text, is to use macros * providing a log stream. It is important to note, however, that the stream * obtained from one macro evaluation fits for printing one log entry, without * nested/overlapping log entry emissions and the entry being closed with a * newline. Should this simple recommendation not being followed, the result * becomes hard to read due to missing line breaks and overlapping entries. * * \todo Thread-safety is another issue, which need to be addressed for proper * logging. * ******************************************************************************/ #ifndef ROSA_SUPPORT_LOG_H #define ROSA_SUPPORT_LOG_H #include "rosa/config/config.h" #include "rosa/support/terminal_colors.h" #include #include /* **************************************************************************** * Log Levels * * ****************************************************************************/ namespace rosa { /// Type-safe definition of log levels, use this in code. /// \note Keep values in sync with the corresponding preprocessor definitions. enum class LogLevel { Error, ///< Log errors only Warning, ///< Like `rosa::LogLevel::Error` and also log warnings Info, ///< Like `rosa::LogLevel::Warning` and also log general infos Debug, ///< Like `rosa::LogLevel::Info` and also log debug infos Trace, ///< Like `rosa::LogLevel::Debug` and also log trace infos NumLogLevels ///< Number of log levels }; /// Converts a `rosa::LogLevel` to its textual representation. /// /// \param logLevel the `LogLevel` to convert /// /// \return `string` representing `logLevel` /// /// \pre `logLevel` is valid:\code /// logLevel != LogLevel::NumLogLevels /// \endcode std::string logLevelToString(const LogLevel logLevel); /// Prints colorized tag for the given `rosa::LogLevel`. /// -/// \param [inout] OS `ostream` to print to +/// \param [in,out] OS `ostream` to print to /// \param logLevel the `LogLevel` to print tag for /// /// \return `OS` after printing a tag for `logLevel` /// /// \pre `logLevel` is valid:\code /// logLevel != LogLevel::NumLogLevels /// \endcode std::ostream &operator<<(std::ostream &OS, const LogLevel logLevel); } // End namespace rosa /// \name Valid log level constants /// \note Only for preprocessor definitions in this file. /// \note Keep the defintions in sync with the values of `rosa::LogLevel`. ///@{ #define ROSA_LOG_LEVEL_ERROR \ 0 ///< Value corresponding to `rosa::LogLevel::Error` #define ROSA_LOG_LEVEL_WARNING \ 1 ///< Value corresponding to `rosa::LogLevel::Warning` #define ROSA_LOG_LEVEL_INFO \ 2 ///< Value corresponding to `rosa::LogLevel::Info` #define ROSA_LOG_LEVEL_DEBUG \ 3 ///< Value corresponding to `rosa::LogLevel::Debug` #define ROSA_LOG_LEVEL_TRACE \ 4 ///< Value corresponding to `rosa::LogLevel::Trace` ///@} /* **************************************************************************** * Logger Implementation * * ****************************************************************************/ /// Stream to print logs to /// /// \todo Make it configurable, e.g. printing into a file. #define ROSA_LOG_OSTREAM std::clog /// Prints a log message to `ROSA_LOG_OSTREAM`. /// /// \param level `LogLevel` of the log entry /// \param output message to print #define ROSA_LOG_IMPL(level, output) \ do { \ ROSA_LOG_OSTREAM << (level) << " " << __func__ << "@" << __FILENAME__ \ << ":" << __LINE__ << ": " << (output) << std::endl; \ } while (false) /// Returns a stream to print a log message to. /// /// \param level `LogLevel`of the log entry that is about to be printed #define ROSA_LOG_STREAM_IMPL(level) \ ([](void) -> std::ostream & { \ return ROSA_LOG_OSTREAM << (level) << " " << __func__ << "@" \ << __FILENAME__ << ":" << __LINE__ << ": "; \ }()) namespace rosa { /// Dummy `std::ostream` printing to nowhere. extern std::ostream LogSink; } // End namespace rosa /// An output stream ignoring all its input. #define ROSA_LOG_STREAM_IGNORE rosa::LogSink /* **************************************************************************** * Logging Interface * * ****************************************************************************/ /// \name Logging interface /// /// Preprocesser macros for convenience. ///@{ /// \def LOG_ERROR_STREAM /// \brief Returns a stream to print a log entry of level /// `rosa::LogLevel::Error`. /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Error`. /// \def LOG_ERROR(output) /// \brief Prints a log entry of level `rosa::LogLevel::Error`. /// \param output the message to print /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Error`. /// \def LOG_WARNING_STREAM /// \brief Returns a stream to print a log entry of level /// `rosa::LogLevel::Warning`. /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Warning`. /// \def LOG_WARNING(output) /// \brief Prints a log entry of level `rosa::LogLevel::Warning`. /// \param output the message to print /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Warning`. /// \def LOG_INFO_STREAM /// \brief Returns a stream to print a log entry of level /// `rosa::LogLevel::Info`. /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Info`. /// \def LOG_INFO(output) /// \brief Prints a log entry of level `rosa::LogLevel::Info`. /// \param output the message to print /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Info`. /// \def LOG_DEBUG_STREAM /// \brief Returns a stream to print a log entry of level /// `rosa::LogLevel::Debug`. /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Debug`. /// \def LOG_DEBUG(output) /// \brief Prints a log entry of level `rosa::LogLevel::Debug`. /// \param output the message to print /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Debug`. /// \def LOG_TRACE_STREAM /// \brief Returns a stream to print a log entry of level /// `rosa::LogLevel::Trace`. /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Trace`. /// \def LOG_TRACE(output) /// \brief Prints a log entry of level `rosa::LogLevel::Trace`. /// \param output the message to print /// \note Takes effect only if RoSA is built with a log level not smaller than /// `rosa::LogLevel::Trace`. ///@} // Define logging macros if logging is enabled. #ifdef ROSA_LOG_LEVEL #define LOG_ERROR_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Error) #define LOG_ERROR(output) ROSA_LOG_IMPL(rosa::LogLevel::Error, output) #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_WARNING #define LOG_WARNING_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Warning) #define LOG_WARNING(output) ROSA_LOG_IMPL(rosa::LogLevel::Warning, output) #endif #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_INFO #define LOG_INFO_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Info) #define LOG_INFO(output) ROSA_LOG_IMPL(rosa::LogLevel::Info, output) #endif #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_DEBUG #define LOG_DEBUG_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Debug) #define LOG_DEBUG(output) ROSA_LOG_IMPL(rosa::LogLevel::Debug, output) #endif #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_TRACE #define LOG_TRACE_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Trace) #define LOG_TRACE(output) ROSA_LOG_IMPL(rosa::LogLevel::Trace, output) #endif #endif // defined ROSA_LOG_LEVEL // Define all disabled logging features as void. #ifndef LOG_ERROR #define LOG_ERROR_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_ERROR(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_WARNING #define LOG_WARNING_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_WARNING(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_INFO #define LOG_INFO_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_INFO(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_DEBUG #define LOG_DEBUG_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_DEBUG(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_TRACE #define LOG_TRACE_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_TRACE(output) ROSA_IGNORE_UNUSED(output) #endif #endif // ROSA_SUPPORT_LOG_H diff --git a/include/rosa/support/terminal_colors.h b/include/rosa/support/terminal_colors.h index 9a82feb..3deda36 100644 --- a/include/rosa/support/terminal_colors.h +++ b/include/rosa/support/terminal_colors.h @@ -1,65 +1,65 @@ /***************************************************************************//** * * \file rosa/support/terminal_colors.h * * \author David Juhasz (david.juhasz@tuwien.ac.at) * * \date 2017 * * \brief Facility for printing colorized text to terminals supporting it. * ******************************************************************************/ #ifndef ROSA_SUPPORT_TERMINAL_COLORS_H #define ROSA_SUPPORT_TERMINAL_COLORS_H #include namespace rosa { /// Encloses entities related to terminal I/O. namespace terminal { /// Text colors for colorizable terminals. enum class Color { Default, Black, Red, Green, Yellow, Blue, Magenta, Cyan, Lightgrey, Darkgrey, Lightred, Lightgreen, Lightyellow, Lightblue, LightMagenta, Lightcyan, White, NumColors ///< Number of `rosa::terminal::Color` values }; /// Handles `rosa::terminal::Color` values sent to output streams. /// /// The operator sends terminal commands through `os` to the /// associated terminal to change text color to `color`. /// /// \note If `os` is not a terminal output, the terminal commands simply appear /// as text in the stream. /// -/// \param [inout] os `ostream` to apply `color` to +/// \param [in,out] os `ostream` to apply `color` to /// \param color `Color` to apply for `os` /// /// \pre `color` is valid:\code /// color != Color::NumColors /// \endcoed std::ostream &operator<<(std::ostream &os, const Color color); } // End namespace terminal } // End namespace rosa #endif // ROSA_SUPPORT_TERMINAL_COLORS_H diff --git a/include/rosa/support/type_token.hpp b/include/rosa/support/type_token.hpp index 8ed065b..5da3911 100644 --- a/include/rosa/support/type_token.hpp +++ b/include/rosa/support/type_token.hpp @@ -1,274 +1,274 @@ /**************************************************************************//** * * \file rosa/support/type_token.hpp * * \author David Juhasz (david.juhasz@tuwien.ac.at) * * \date 2017 * * \brief Facilities for encoding TypeLists as unsigned integer values. * * \note **On the compatibility between different versions of the type token * implementation:** * Different software versions produce compatible type tokens as long as * *backward compatibility* of `rosa::BuiltinTypes` is maintained (denoted by * `rosa::TypeNumberVersion`) and the type token implementation uses the same * type as `rosa::token_t` (boiling down to the same `rosa::token::TokenBits` * value) and the same `rosa::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. * ******************************************************************************/ #ifndef ROSA_SUPPORT_TYPE_TOKEN_HPP #define ROSA_SUPPORT_TYPE_TOKEN_HPP #include "rosa/support/type_numbers.hpp" namespace rosa { /// 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 `rosa::token_t`. using token_t = uint64_t; /// Sanity check in case someone would change `rosa::token_t`. STATIC_ASSERT(std::is_unsigned::value, "token_t is not an unsigned integer"); /// Turn `rosa::token_t` into a strongly typed enumeration. /// /// Values of `rosa::token_t` casted to `rosa::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_t; /// Casts a `rosa::Token` into `rosa::printable_token_t`. #define PRINTABLE_TOKEN(T) static_cast(T) /// Converts a `rosa::Token` into `std::string`. /// /// \param T `Token` to convert /// /// \return `string` representing `T` inline std::string to_string(const Token T) { return std::to_string(static_cast(T)); } /// Encloses constants related to the implementation of `rosa::Token`. namespace token { /// The number of bits in one `rosa::Token`. constexpr size_t TokenBits = sizeof(Token) * 8; /// The number of bits a builtin type can be uniquely encoded into, that is any /// valid `rosa::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 `rosa::BuiltinTypes` /// is extended. constexpr size_t RepresentationBits = log2(NumberOfBuiltinTypes) + 1; /// Maximal size of uniquely tokenizable `rosa::TypeList`. constexpr size_t MaxTokenizableListSize = TokenBits / RepresentationBits; } // End namespace token /// \defgroup TypeListTokenImpl /// \brief Generates a `rosa::Token` for a squashed `rosa::TypeList`. /// /// \note Only to be used by the implementation of `rosa::TypeListToken`. ///@{ /// Declaration of the template. /// /// \tparam List `TypeList` to generate `Token` for template struct TypeListTokenImpl; /// Specialization for `rosa::EmptyTypeList`. template <> struct TypeListTokenImpl { static constexpr Token Value = static_cast(0); }; /// Specialization for a non-empty `rosa::TypeList`. template struct TypeListTokenImpl> { static constexpr TypeNumber TN = TypeNumberOf::Value; // Check if the generated type number is valid. STATIC_ASSERT(validTypeNumber(TN), "non-builtin type"); static constexpr Token Value = static_cast( (static_cast(TypeListTokenImpl>::Value) << token::RepresentationBits) | static_cast(TN)); }; ///@} /// \name TypeListToken /// \brief Generates a `rosa::Token` for a `rosa::TypeList`. /// /// `rosa::Token` for a `rosa::TypeList` `List` can be obtained as \code /// TypeListToken::Value /// \endcode /// /// \note The `rosa::TypeList` cannot have more than /// `rosa::token::MaxTokenizableListSize` elements and must be a subset of /// `rosa::BuiltinTypes` with respect to squashed integers. /// \note A generated `rosa::Token` uniquely represents a list of types, except /// for `rosa::AtomConstant` types. Observe that any `rosa::AtomConstant` is /// encoded as the type `rosa::AtomValue`. The type information on all separate /// `rosa::AtomConstant` types are lost and replaced by the `rosa::AtomValue` /// type whose actual value needs to be in order to obtain the /// original `rosa::AtomConstant` type and so the full type information on the /// encoded `rosa::TypeList`. /// ///@{ /// Declaration of the template. /// /// \tparam List `TypeList` to generate `Token` for template struct TypeListToken; /// Implementation using `rosa::TypeListTokenImpl`. template struct TypeListToken> { /// \note `rosa::TypeNumber` is computed against `rosa::squased_int_t` for /// integral types, so let's do the same here. using List = typename SquashedTypeList>::Type; /// Check the length of the list here. /// \note Type validation is done one-by-one in `rosa::TypeListTokenImpl`. STATIC_ASSERT((TypeListSize::Value <= token::MaxTokenizableListSize), "too long list of types"); /// The `rosa::Token` for `List`. static constexpr Token Value = TypeListTokenImpl::Value; }; ///@} /// Convenience template to generate `rosa::Token` for a list of types. template using TypeToken = TypeListToken>; /// Anonymous namespace with helper facilities, consider it private. namespace { /// Extracts the `rosa::TypeNumber` of the first encoded type of a /// `rosa::Token`. /// /// \note The returned type number is not validated. /// /// \param T `Token` to take the first `TypeNumber` from /// /// \return the first `TypeNumber` encoded in `T` inline TypeNumber typeNumberOfHeadOfToken(const Token T) { return static_cast(static_cast(T) & ((1 << token::RepresentationBits) - 1)); } } // End namespace /// Tells if a given `rosa::Token` is valid. /// /// A `rosa::Token` is considered valid if it can be decoded by the current /// software. /// /// \note Validation gives a correct result only when `T` was generated by a /// compatible software. /// /// \sa Note for type_token.hpp on compatibility. /// /// \param T `Token` to validate /// /// \return if `T` is valid bool validToken(const Token T); /// Tells if a `rosa::Token` does encode an empty list of types. /// /// \param T `Token` to check /// /// \return if `T` encodes an empty list of types bool emptyToken(const Token T); /// Tells how many types are encoded in a `rosa::Token`. /// /// \param T `Token` to check /// /// \return how many types are encoded in `T` size_t lengthOfToken(const Token T); /// Tells the full memory size of the types encoded in a `rosa::Token`. /// /// The full memory size of the types encoded in a `rosa::Token` is the sum of /// the separate memory sizes of all the types encoded in the `rosa::Token`. /// /// \param T `Token` to check /// /// \return full memory size of the types encoded in `T` /// /// \pre `T` is valid:\code /// validToken(T) /// \endcode size_t sizeOfValuesOfToken(const Token T); /// Tells the memory size of the first type encoded in a `rosa::Token`. /// /// \param T `Token` to check the first encoded type of /// /// \return memory size of the first type encoded in `T` /// /// \pre `T` is not empty and valid:\code /// !empty(T) && validToken(T) /// \endcode size_t sizeOfHeadOfToken(const Token T); /// Gives the textual representation of the first type encoded in a /// `rosa::Token`. /// /// \param T `Token` to take the name of its first encoded type /// /// \return textual representation of the first type encoded in `T` /// /// \pre `T` is not empty and valid:\code /// !empty(T) && validToken(T) /// \endcode const char *nameOfHeadOfToken(const Token T); /// Updates a `rosa::Token` by dropping its first encoded type. /// -/// \param [inout] T `Token` to drop the first encoded type of +/// \param [in,out] T `Token` to drop the first encoded type of void dropHeadOfToken(Token &T); /// Updates a `rosa::Token` by dropping a number of its first encoded types /// -/// \param [inout] T `Token` to drop the first `N` encoded types of +/// \param [in,out] T `Token` to drop the first `N` encoded types of /// \param N the number of types to drop from `T` void dropNOfToken(Token &T, const size_t N); /// Tells if the first encoded type of a `rosa::Token` is a given type. /// /// \tparam Type type to match the first encoded type of `T` against /// /// \param T `Token` whose first encoded type is to be matched against `Type` /// /// \return if the first encoded type of `T` is `Type` /// /// \pre `T` is not empty and valid:\code /// !empty(T) && validToken(T) /// \endcode template bool isHeadOfTokenTheSameType(const Token T) { ASSERT(!emptyToken(T) && validToken(T)); return TypeNumberOf::Value == typeNumberOfHeadOfToken(T); } } // End namespace rosa #endif // ROSA_SUPPORT_TYPE_TOKEN_HPP