#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2023 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_SUPPORT_TEXT_LEXICALAPPEND_H #define NUCLEX_SUPPORT_TEXT_LEXICALAPPEND_H #include "Nuclex/Support/Config.h" #include "Nuclex/Support/Text/StringConverter.h" // UTF-8 and wide char conversion #include // for std::string #include // for std::uint8_t namespace Nuclex { namespace Support { namespace Text { // ------------------------------------------------------------------------------------------- // /// Appends strings and numeric types as text to an UTF-8 string /// String to which the UTF-8 characters will be appended /// What will be appended to the UTF-8 string /// /// The number of bytes appended to the UTF-8 string or the number of bytes needed /// /// /// /// This method conveniently appends various data types, lexically converted into /// UTF-8 strings, to another UTF-8 string. It is useful if you want to avoid /// allocations and unneccessary copies. /// /// /// /// int currentScore = 31241; /// std::string scoreText(14 + 11 + 1, '\0'); // optional: reserve exact length /// /// scoreText.append(u8"The score is: "); /// lexical_append(scoreText, currentScore); /// /// /// /// Compared to lexical_cast and/or std::to_string(), using this method avoids any /// temporary string copies and/or memory allocations. /// /// /// /// No iostreams dependency /// Ignores system locale /// No memory allocations (if string capacity suffices) /// /// /// template inline void lexical_append(std::string &target, const TValue &from) = delete; // ------------------------------------------------------------------------------------------- // /// Appends strings and numeric types as text to an UTF-8 string /// Address at which the UTF-8 characters will be stored /// Number of bytes available at the provided address /// What will be appended to the UTF-8 string /// /// The number of bytes appended to the UTF-8 string or the number of bytes needed /// /// /// /// This method conveniently appends various data types, lexically converted into /// UTF-8 strings, to another UTF-8 string. It is useful if you want to avoid /// allocations and unneccessary copies. /// /// /// In this variant, the text is written to a caller-provided memory address. If there /// is not enough space available, the method instead returns the number of bytes /// that would be required. /// /// /// In the latter case, the contents of the caller-provided memory may or may not have /// been overwritten with a portion of the generated text (in short: neither rely on /// them staying unchanged nor realy on getting a partial result). /// /// /// /// int currentScore = 31241; /// std::vector<char> scoreCharacters(14 + 11 = 1); /// /// { /// static const std::string message(u8"The score is: "); /// /// std::copy_n(message.c_str(), 14, scoreCharacters.data()); /// std::size_t characterCount = lexical_append( /// scoreCharacters.data() + 14, scoreCharacters.size() - 14, currentScore /// ); /// assert(characterCount < scoreCharacters.size() - 14); /// /// scoreCharacters[charactersCount + 14] = '\0'; /// } /// /// /// /// Note that only the characters written to the user-provided memory block. /// No terminating zero byte is appended. /// /// /// /// No iostreams dependency /// Ignores system locale /// No memory allocations /// No terminating zero byte appended(!) /// /// /// template inline std::size_t lexical_append( char *target, std::size_t availableBytes, const TValue &from ) = delete; // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast boolean to an existing string /// String to which the boolean will be appended /// Boolean that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>(std::string &target, const bool &from); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast boolean to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Boolean that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const bool &from ); // ------------------------------------------------------------------------------------------- // /// Appends a zero-terminated string to an existing string /// String to which to append /// Zero-terminated string that will be appended NUCLEX_SUPPORT_API void lexical_append(std::string &target, const char *from); // ------------------------------------------------------------------------------------------- // /// Appends a zero-terminated string to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Zero-terminated string that will be appended /// The number of bytes written at the provided address NUCLEX_SUPPORT_API std::size_t lexical_append( char *target, std::size_t availableBytes, const char *from ); // ------------------------------------------------------------------------------------------- // /// Appends another string to an existing string /// String to which to append /// Other string that will be appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::string &from ); // ------------------------------------------------------------------------------------------- // /// Appends another string to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Other string that will be appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::string &from ); // ------------------------------------------------------------------------------------------- // /// Appends an 8 bit unsigned integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::uint8_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 8 bit unsigned integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::uint8_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends an 8 bit signed integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::int8_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 8 bit signed integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::int8_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a 16 bit unsigned integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::uint16_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 16 bit unsigned integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::uint16_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a 16 bit signed integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::int16_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 16 bit signed integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::int16_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a 32 bit unsigned integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::uint32_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 32 bit unsigned integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::uint32_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a 32 bit signed integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::int32_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 32 bit signed integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::int32_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a 64 bit unsigned integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::uint64_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 64 bit unsigned integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::uint64_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a 64 bit signed integer to an existing string /// String to which the integer will be appended /// Integer that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const std::int64_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast 64 bit signed integer to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Integer that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const std::int64_t &from ); // ------------------------------------------------------------------------------------------- // /// Appends a floating point value to an existing string /// String to which the integer will be appended /// Floating point value that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const float &from ); // ------------------------------------------------------------------------------------------- // /// Appends a lexically cast floating point value to an existing string /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Floating point value that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const float &from ); // ------------------------------------------------------------------------------------------- // /// Appends a double precision floating point value to an existing string /// String to which the integer will be appended /// Floating point value that will be lexically cast and appended template<> NUCLEX_SUPPORT_API void lexical_append<>( std::string &target, const double &from ); // ------------------------------------------------------------------------------------------- // /// /// Appends a lexically cast double precision floating point value to an existing string /// /// Memory address at which text will be stored /// Number of bytes available at that memory address /// Floating point value that will be lexically cast and appended /// The number of bytes written at the provided address template<> NUCLEX_SUPPORT_API std::size_t lexical_append<>( char *target, std::size_t availableBytes, const double &from ); // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Support::Text #endif // NUCLEX_SUPPORT_TEXT_LEXICALAPPEND_H