<commit_before>/*
 * Copyright (c) 2016 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: <NAME> <<EMAIL>>
 */

/*
 * Collection of heap-less containers and functions.
 */

#pragma once

#include <type_traits>
#include <algorithm>
#include <cassert>
#include <cstdarg>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <cctype>


namespace os
{
namespace heapless
{
/**
 * Converts any signed or unsigned integer or boolean to string and returns it by value.
 * The argument must be of integral type, otherwise the call will be rejected by SFINAE.
 * Usage examples:
 *      intToString(var)
 *      intToString<16>(var)
 *      intToString<2>(var).c_str()
 * It is safe to obtain a reference to the returned string and pass it to another function as an argument,
 * which enables use cases like this (this example is somewhat made up, but it conveys the idea nicely):
 *      print("%s", intToString(123).c_str());
 * More info on rvalue references:
 *      https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
 *      http://stackoverflow.com/questions/584824/guaranteed-lifetime-of-temporary-in-c
 */
template <
    int Radix = 10,
    typename T,
    typename std::enable_if<std::is_integral<T>::value>::type...
    >
inline auto intToString(T number)
{
    constexpr char Alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";

    static_assert(Radix >= 1, "Radix must be positive");
    static_assert(Radix <= (sizeof(Alphabet) / sizeof(Alphabet[0])), "Radix is too large");

    // Plus 1 to round up, see the standard for details.
    constexpr unsigned MaxChars =
        ((Radix >= 10) ? std::numeric_limits<T>::digits10 : std::numeric_limits<T>::digits) +
        1 + (std::is_signed<T>::value ? 1 : 0);

    class Container
    {
        std::uint_fast16_t offset_;
        char storage_[MaxChars + 1];   // Plus 1 because of zero termination.

    public:
#ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wbool-compare"
#endif
        Container(T x) :
            offset_(MaxChars)          // Field initialization is not working in GCC in this context, not sure why.
        {
            storage_[offset_] = '\0';

            do
            {
                assert(offset_ > 0);

                if (std::is_signed<T>::value)  // Should be converted to constexpr if.
                {
                    // We can't just do "x = -x", because it would break on int8_t(-128), int16_t(-32768), etc.
                    auto residual = std::int_fast8_t(x % Radix);
                    if (residual < 0)
                    {
                        // Should never happen - since C++11, neg % pos --> pos
                        residual = -residual;
                    }

                    storage_[--offset_] = Alphabet[residual];

                    // Signed integers are really tricky sometimes.
                    // We must not mix negative with positive to avoid implementation-defined behaviors.
                    x = (x < 0) ? -(x / -Radix) : (x / Radix);
                }
                else
                {
                    // Fast branch for unsigned arguments.
                    storage_[--offset_] = Alphabet[x % Radix];
                    x /= Radix;
                }
            }
            while (x != 0);

            if (std::is_signed<T>::value && (x < 0))    // Should be optimized with constexpr if.
            {
                assert(offset_ > 0);
                storage_[--offset_] = '-';
            }

            assert(offset_ < MaxChars);                 // Making sure there was no overflow.
        }
#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif

        const char* c_str() const { return &storage_[offset_]; }

        operator const char* () const { return this->c_str(); }

        std::uint_fast16_t length() const { return std::uint_fast16_t(MaxChars - offset_); }
        std::uint_fast16_t size() const { return length(); }
    };

    return Container(number);
}
<commit_msg>Where are unit tests when you need them?<commit_after>/*
 * Copyright (c) 2016 Zubax, zubax.com
 * Distributed under the MIT License, available in the file LICENSE.
 * Author: <NAME> <<EMAIL>>
 */

/*
 * Collection of heap-less containers and functions.
 */

#pragma once

#include <type_traits>
#include <algorithm>
#include <cassert>
#include <cstdarg>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <limits>
#include <cctype>


namespace os
{
namespace heapless
{
/**
 * Converts any signed or unsigned integer or boolean to string and returns it by value.
 * The argument must be of integral type, otherwise the call will be rejected by SFINAE.
 * Usage examples:
 *      intToString(var)
 *      intToString<16>(var)
 *      intToString<2>(var).c_str()
 * It is safe to obtain a reference to the returned string and pass it to another function as an argument,
 * which enables use cases like this (this example is somewhat made up, but it conveys the idea nicely):
 *      print("%s", intToString(123).c_str());
 * More info on rvalue references:
 *      https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
 *      http://stackoverflow.com/questions/584824/guaranteed-lifetime-of-temporary-in-c
 */
template <
    int Radix = 10,
    typename T,
    typename std::enable_if<std::is_integral<T>::value>::type...
    >
inline auto intToString(T number)
{
    constexpr char Alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";

    static_assert(Radix >= 1, "Radix must be positive");
    static_assert(Radix <= (sizeof(Alphabet) / sizeof(Alphabet[0])), "Radix is too large");

    // Plus 1 to round up, see the standard for details.
    constexpr unsigned MaxChars =
        ((Radix >= 10) ? std::numeric_limits<T>::digits10 : std::numeric_limits<T>::digits) +
        1 + (std::is_signed<T>::value ? 1 : 0);

    class Container
    {
        std::uint_fast16_t offset_;
        char storage_[MaxChars + 1];   // Plus 1 because of zero termination.

    public:
#ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wbool-compare"
#endif
        Container(T x) :
            offset_(MaxChars)          // Field initialization is not working in GCC in this context, not sure why.
        {
            storage_[offset_] = '\0';
            const bool negative = std::is_signed<T>::value && (x < 0);

            do
            {
                assert(offset_ > 0);

                if (std::is_signed<T>::value)  // Should be converted to constexpr if.
                {
                    // We can't just do "x = -x", because it would break on int8_t(-128), int16_t(-32768), etc.
                    auto residual = std::int_fast8_t(x % Radix);
                    if (residual < 0)
                    {
                        // Should never happen - since C++11, neg % pos --> pos
                        residual = -residual;
                    }

                    storage_[--offset_] = Alphabet[residual];

                    // Signed integers are really tricky sometimes.
                    // We must not mix negative with positive to avoid implementation-defined behaviors.
                    x = T((x < 0) ? -(x / -Radix) : (x / Radix));
                }
                else
                {
                    // Fast branch for unsigned arguments.
                    storage_[--offset_] = Alphabet[x % Radix];
                    x = T(x / Radix);
                }
            }
            while (x != 0);

            if (negative)
            {
                assert(offset_ > 0);
                storage_[--offset_] = '-';
            }

            assert(offset_ < MaxChars);                 // Making sure there was no overflow.
        }
#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif

        const char* c_str() const { return &storage_[offset_]; }

        operator const char* () const { return this->c_str(); }

        std::uint_fast16_t length() const { return std::uint_fast16_t(MaxChars - offset_); }
        std::uint_fast16_t size() const { return length(); }
    };

    return Container(number);
}

{'fraction_non_alphanumeric': 0.11510095514448071, 'fraction_numerical': 0.019102889614315076, 'mean_word_length': 2.01238164603059, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 61, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4869523', 'n_tokens_mistral': 2554, 'n_tokens_neox': 2309, 'n_words': 730}