/* Copyright 2022, Contributors To LensorOS.
 * All rights reserved.
 *
 * This file is part of LensorOS.
 *
 * LensorOS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * LensorOS 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
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LensorOS. If not, see <https://www.gnu.org/licenses
 */
#ifndef _LENSOROS_STRING_
#define _LENSOROS_STRING_

#include <algorithm>
#include <bits/decls.h>
#include <cmath>
#include <concepts>
#include <cstring>
#include <iterator>
#include <stddef.h>
#include <stdio.h>
#include <utility>

__BEGIN_DECLS__
void* memcpy(void* __restrict__ __dest, const void* __restrict__ __src, size_t __n);
int memcmp(const void* src, const void* dest, size_t bytes);
__END_DECLS__

namespace std {

template <typename _Char>
class basic_string;

template <typename _Char>
class basic_string_view;

/// Remove from a string or string view all trailing characters in `chars`.
namespace __detail {
template <typename _Str, typename _Char>
constexpr void __remove_trailing(_Str& __str, basic_string_view<_Char> __chars) {
    /// String is empty, so there's nothing to do.
    if (!__str.size() || !__chars.size()) return;

    /// So long as there are characters left,
    auto __it = __str.rbegin();
    while (__it != __str.rend()) {
        bool __found = false;

        /// compare the last one against each character in `chars`
        for (_Char __c : __chars) {
            if (*__it == __c) {
                /// and move on to the next character if it matches;
                __it++;
                __found = true;
                break;
            }
        }

        /// finally, stop if we didn't find a match.
        if (!__found) break;
    }

    /// Erase everything after the last character we found.
    __str.erase(__it.base(), __str.end());
}
}

template <typename _Char>
class basic_string_view {
    using _View = basic_string_view<_Char>;

    const _Char* __data{};
    size_t __size{};

    static constexpr size_t __constexpr_strlen(const _Char* __str) {
        size_t __len = 0;
        while (*__str++) __len++;
        return __len;
    }

public:
    using const_iterator = const _Char*;

    static constexpr size_t npos = static_cast<size_t>(-1);

    constexpr basic_string_view() {}
    constexpr basic_string_view(const _Char* __data, size_t __size) : __data(__data), __size(__size) {}
    constexpr basic_string_view(const _Char* __data) : __data(__data), __size(__constexpr_strlen(__data)) {}

    template <size_t __N>
    constexpr basic_string_view(const _Char (&__data)[__N]) : __data(__data), __size(__N - 1) {}

    void __remove_trailing(basic_string_view __other) { ::std::__detail::__remove_trailing(*this, __other); }
    void remove_prefix(size_t __n) { __data += __n; __size -= __n; }
    void remove_suffix(size_t __n) { __size -= __n; }

    constexpr const _Char* data() const { return __data; }
    constexpr size_t size() const { return __size; }

    _Nodiscard int compare(_View __sv) const {
        int __cmp = memcmp(__data, __sv.__data, __size < __sv.__size ? __size : __sv.__size);
        if (__cmp == 0) {
            if (__size < __sv.__size) return -1;
            if (__size > __sv.__size) return 1;
        }
        return __cmp;
    }

    constexpr _Char operator[](size_t __i) const { return __data[__i]; }

    _Nodiscard constexpr const char* begin() const { return __data; }
    _Nodiscard constexpr const char* end() const { return __data + __size; }

    _Nodiscard constexpr reverse_iterator<const _Char*> rbegin() const { return reverse_iterator{data() + size()}; }
    _Nodiscard constexpr reverse_iterator<const _Char*> rend() const { return reverse_iterator{data()}; }

    _Nodiscard constexpr _View substr(size_t __pos = 0, size_t __len = npos) const {
        if (__pos > __size) return {};
        if (__len > __size - __pos) __len = __size - __pos;
        return {data() + __pos, __len};
    }

    _Nodiscard size_t find(_Char __c, size_t __pos = 0) const { return find(_View(&__c, 1), __pos); }
    _Nodiscard size_t find(_View __sv, size_t __pos = 0) const { return find(__sv, __pos); }

    _Nodiscard constexpr size_t find_first_of(_View __sv, size_t __pos = 0) const {
        for (size_t __i = __pos; __i < __size; __i++) {
            for (size_t __j = 0; __j < __sv.__size; __j++) {
                if (__data[__i] == __sv.__data[__j]) return __i;
            }
        }
        return npos;
    }

    _Nodiscard constexpr size_t find_first_not_of(_View __sv, size_t __pos = 0) const {
        for (size_t __i = __pos; __i < __size; __i++) {
            bool __found = false;
            for (size_t __j = 0; __j < __sv.__size; __j++) {
                if (__data[__i] == __sv.__data[__j]) {
                    __found = true;
                    break;
                }
            }
            if (!__found) return __i;
        }
        return npos;
    }

    _Nodiscard constexpr size_t find_last_of(_View __sv, size_t __pos = npos) const {
        if (__pos == npos) __pos = __size - 1; // start at end of string by default
        // NOTE: Relies on unsigned integer underflow
        for (size_t __i = __pos; __i <= __pos; --__i) {
            for (size_t __j = 0; __j < __sv.__size; __j++) {
                if (__data[__i] == __sv.__data[__j]) return __i;
            }
        }
        return npos;
    }

    _Nodiscard bool starts_with(_View __sv) const {
        if (__sv.size() > __size) return false;
        return memcmp((void*)__data, (void*)__sv.__data, __sv.size() * sizeof(_Char)) == 0;
    }

    _Nodiscard bool ends_with(_View __sv) const {
        if (__sv.size() > __size) return false;
        return memcmp((void*)(__data + __size - __sv.size()), (void*)__sv.__data, __sv.size() * sizeof(_Char)) == 0;
    }

    _Nodiscard bool contains(_View __sv) const {
        if (__sv.size() > __size) return false;
        return memmem(__data, __size, __sv.__data, __sv.size()) != nullptr;
    }

    _Nodiscard bool contains(_Char __c) const {
        return find(__c) != npos;
    }
};

template <typename _Char>
_Nodiscard bool operator==(basic_string_view<_Char> __a, basic_string_view<_Char> __b) {
    if (__a.size() != __b.size()) return false;
    return memcmp((void*) __a.data(), (void*) __b.data(), __a.size()) == 0;
}

/// TODO: Use operator<=>.
template <typename _Char>
_Nodiscard bool operator!=(basic_string_view<_Char> __a, basic_string_view<_Char> __b) {
    return !(__a == __b);
}

template <typename _Char>
_Nodiscard bool operator<(basic_string_view<_Char> __a, basic_string_view<_Char> __b) {
    return __a.compare(__b) < 0;
}

template <typename _Char>
_Nodiscard bool operator>(basic_string_view<_Char> __a, basic_string_view<_Char> __b) {
    return __a.compare(__b) > 0;
}

template <typename _Char>
_Nodiscard bool operator<=(basic_string_view<_Char> __a, basic_string_view<_Char> __b) {
    return __a.compare(__b) <= 0;
}

template <typename _Char>
_Nodiscard bool operator>=(basic_string_view<_Char> __a, basic_string_view<_Char> __b) {
    return __a.compare(__b) >= 0;
}


/// Dynamically resiseable string with small string optimisation. Small strings
/// are stored directly in the string object and are not heap allocated.
template <typename _Char>
class basic_string {
    using _Str = basic_string<_Char>;
    using _View = basic_string_view<_Char>;

    static constexpr size_t __repr_size = sizeof(_Char*) + sizeof(size_t) + sizeof(size_t);

    /// String data. __flag is 0 if the string is small, and 1 otherwise.
    union {
        /// Large string representation. __data points to a heap allocated buffer
        /// that contains __sz characters and a null terminator.
        struct {
            _Char* __data;
            size_t __sz;
            size_t __cap : (sizeof(size_t) * __CHAR_BIT__) - 1;
            size_t __is_large : 1;
        } __large;

        /// Small string representation.
        ///
        /// __rem_cap is the number of free characters in the buffer. If the string is
        /// full, it and the flag will act as the null terminator.
        struct {
            _Char __data[__repr_size - sizeof(_Char)];
            _Char __rem_cap : (sizeof(_Char) * __CHAR_BIT__) - 1;
            _Char __is_large : 1;
        } __small;
    };

    /// PRAY this is correct.
    static_assert(sizeof(__small) == __repr_size);
    static_assert(sizeof(__large) == __repr_size);

    /// The maximum number of characters we can store in a small string.
    static constexpr size_t __max_chars_small = (sizeof(__small) / sizeof(_Char)) - 1;

    /// Check if a string is large.
    _Nodiscard constexpr bool __is_large() const { return __small.__is_large; }

    /// Get a string view of the string.
    _Nodiscard _View __view() const { return _View(data(), size()); };

    /// Compute the number of bytes required the string should be resized to
    /// to be able to store at least __size + __n many characters including
    /// the null terminator.
    ///
    /// This function will always round up to the next power of two that is
    /// *greater than* the number of bytes required.
    _Nodiscard size_t __new_size(size_t __n) {
        return (1 << (sizeof(size_t) - static_cast<size_t>(__builtin_clzll(size() + __n)))) * sizeof(_Char);
    }

public:
    using iterator = const char*;

    /// Invalid index.
    static constexpr size_t npos = static_cast<size_t>(-1);

    /// =======================================================================
    ///  Constructors.
    /// =======================================================================
    /// Construct an empty string.
    constexpr basic_string() {
        __small.__data[0] = 0;
        __small.__rem_cap = __max_chars_small;
        __small.__is_large = false;
    }

    explicit constexpr basic_string(_Char __c) {
        __small.__data[0] = __c;
        __small.__data[1] = 0;
        __small.__rem_cap = __max_chars_small - 1;
        __small.__is_large = false;
    }

    constexpr basic_string(const _Str& __other) {
        /// Copy the contents of the other string.
        if (__other.__is_large()) {
            __large.__data = new _Char[(__other.__large.__sz + 1)];
            __large.__sz = __other.__large.__sz;
            __large.__cap = __other.__large.__cap;
            __large.__is_large = true;
            memcpy(__large.__data, __other.__large.__data, (__other.__large.__sz + 1) * sizeof(_Char));
        }

        /// The other string is small. Shallow-copy it.
        else { __small = __other.__small; }
    }

    constexpr basic_string(_View __sv) {
        const _Char* __cstr = __sv.data();
        const size_t __size = __sv.size();

        if (__size > __max_chars_small) {
            __large.__data = new _Char[(__size + 1)];
            __large.__sz = __size;

            _PushIgnoreWarning("-Wconversion")
            __large.__cap = __size;
            _PopWarnings()

            __large.__is_large = true;
            memcpy(__large.__data, __cstr, __size * sizeof(_Char));
            __large.__data[__size] = 0;
        }

        else {
            memcpy(&__small, __cstr, __size * sizeof(_Char));
            _PushIgnoreWarning("-Wconversion")
            __small.__rem_cap = _Char(__max_chars_small - __size);
            _PopWarnings()
            __small.__data[__size] = 0;
            __small.__is_large = false;
        }
    }

    constexpr basic_string(const _Char* __cstr) : basic_string(_View(__cstr)) {}

    constexpr basic_string(const _Char* __cstr, size_t __sz) : basic_string(_View{__cstr, __sz}) {}

    constexpr basic_string(_Str&& __other) {
        __small = __other.__small;
        __other.__small.__data[0] = 0;
        __other.__small.__rem_cap = __max_chars_small;
        __other.__small.__is_large = false;
    }

    constexpr ~basic_string() {
        if (__is_large()) { delete[] __large.__data; }
    }

    constexpr basic_string& operator=(const _Str& __other) {
        if (__is_large()) { delete[] __large.__data; }
        __small = __other.__small;
        return *this;
    }

    constexpr basic_string& operator=(_Str&& __other)  noexcept {
        if (__is_large()) { delete[] __large.__data; }
        __small = __other.__small;
        __other.__small.__data[0] = 0;
        __other.__small.__rem_cap = __max_chars_small;
        __other.__small.__is_large = false;
        return *this;
    }

    _Nodiscard constexpr basic_string substr(size_t __pos = 0, size_t __len = npos) const {
        auto __size = size();
        if (__pos > __size) return {};
        if (__len > __size - __pos) __len = __size - __pos;
        return {data() + __pos, __len};
    }

    /// =======================================================================
    ///  Accessing elements.
    /// =======================================================================
    _Nodiscard constexpr const _Char* data() const { return __is_large() ? __large.__data : __small.__data; }
    _Nodiscard constexpr  _Char* data() { return __is_large() ? __large.__data : __small.__data; }

    _Nodiscard constexpr _Char* c_str() { return data(); }
    _Nodiscard constexpr const _Char* c_str() const { return data(); }

    _Nodiscard constexpr size_t size() const {
        return __is_large() ? __large.__sz : __max_chars_small - size_t(__small.__rem_cap);
    }

    _Nodiscard constexpr size_t capacity() const {
        return __is_large() ? __large.__cap : __max_chars_small;
    }

    _Nodiscard constexpr bool empty() const { return size() == 0; }

    _Nodiscard constexpr _Char& operator[](size_t __i) { return data()[__i]; }
    _Nodiscard constexpr const _Char& operator[](size_t __i) const { return data()[__i]; }

    constexpr _Char& front() { return data()[0]; }
    constexpr const _Char& front() const { return data()[0]; }

    constexpr _Char& back() { return data()[size() - 1]; }
    constexpr const _Char& back() const { return data()[size() - 1]; }

    constexpr operator basic_string_view<_Char>() const { return __view(); }

    /// =======================================================================
    ///  Iterators.
    /// =======================================================================
    _Nodiscard constexpr _Char* begin() { return data(); }
    _Nodiscard constexpr const _Char* begin() const { return data(); }
    _Nodiscard constexpr const _Char* cbegin() const { return data(); }

    _Nodiscard constexpr _Char* end() { return data() + size(); }
    _Nodiscard constexpr const _Char* end() const { return data() + size(); }
    _Nodiscard constexpr const _Char* cend() const { return data() + size(); }

    _Nodiscard constexpr reverse_iterator<_Char*> rbegin() { return reverse_iterator{data() + size()}; }
    _Nodiscard constexpr reverse_iterator<const _Char*> rbegin() const { return reverse_iterator{data() + size()}; }
    _Nodiscard constexpr reverse_iterator<const _Char*> crbegin() const { return reverse_iterator{data() + size()}; }

    _Nodiscard constexpr reverse_iterator<_Char*> rend() { return reverse_iterator{data()}; }
    _Nodiscard constexpr reverse_iterator<const _Char*> rend() const { return reverse_iterator{data()}; }
    _Nodiscard constexpr reverse_iterator<const _Char*> crend() const { return reverse_iterator{data()}; }

    /// =======================================================================
    ///  Adding elements.
    /// =======================================================================
    void append(basic_string_view<_Char> __sv) {
        const auto __size = size();
        const auto __chars = __sv.data();
        const auto __n = __sv.size();

        if (!__is_large()) {
            /// Char fits in the small string.
            if (__n <= size_t(__small.__rem_cap)) {
                auto __data = __small.__data;
                memcpy(__data + __size, __chars, __n * sizeof(_Char));
                // NOTE: The _Char that stores remaining capacity and
                // is_large will be zero when there is zero remaining
                // capacity. This means that the last _Char can act as a
                // NULL terminator, even though it isn't part of the
                // __small data span.
                if (__size + __n < __max_chars_small)
                    __data[__size + __n] = 0;
                _PushIgnoreWarning("-Wconversion");
                __small.__rem_cap -= __n;
                _PopWarnings();
                return;
            }

            /// Char would overflow the small string. Move it to the heap.
            const auto __new_cap = __new_size(__n);
            auto __p = new _Char[__new_cap];
            memcpy(__p, __small.__data, __max_chars_small * sizeof(_Char));
            memcpy(__p + __size, __chars, __n * sizeof(_Char));
            __p[__size + __n] = 0;

            __large.__data = __p;
            __large.__sz = __size + __n;
            _PushIgnoreWarning("-Wconversion");
            __large.__cap = __new_cap;
            _PopWarnings();
            __large.__is_large = true;
        }

        else {
            /// Char fits in the large string.
            if (__large.__sz + __n < capacity()) {
                memcpy(__large.__data + __size, __chars, __n * sizeof(_Char));
                __large.__data[__size + __n] = 0;
                __large.__sz += __n;
                return;
            }

            /// Char would overflow the large string. Reallocate.
            auto __new_cap = __new_size(__n);
            auto __p = new _Char[__new_cap];
            memcpy(__p, __large.__data, __large.__sz * sizeof(_Char));
            memcpy(__p + __size, __chars, __n * sizeof(_Char));
            __p[__size + __n] = 0;
            delete[] __large.__data;

            __large.__data = __p;
            __large.__sz += __n;
            _PushIgnoreWarning("-Wconversion");
            __large.__cap = __new_cap;
            _PopWarnings();
        }
    }

    void append(const _Char* __chars, size_t __n) { append(basic_string_view<_Char>(__chars, __n)); }

    void reserve(size_t __n) {
        if (__n <= capacity()) return;

        /// If the string is small, move it to the heap.
        auto __size = size();
        auto __new_cap = __new_size(__n);
        auto __p = new _Char[__new_cap];

        if (!__is_large()) {
            memcpy(__p, __small.__data, (__max_chars_small + 1) * sizeof(_Char));
            __large.__data = __p;
            __large.__sz = __size;
            __large.__cap = __new_cap;
            __large.__is_large = true;
        } else {
            memcpy(__p, __large.__data, (__size + 1) * sizeof(_Char));
            delete[] __large.__data;
            __large.__data = __p;
            __large.__cap = __new_cap;
        }
    }

    void shrink_to_fit() {
        if (!__is_large()) return;

        auto __size = size();
        auto __capacity = capacity();
        if (__size + 1 == __capacity) return;

        auto __p = new _Char[__size + 1];
        memcpy(__p, __large.__data, (__size + 1) * sizeof(_Char));
        delete[] __large.__data;
        __large.__data = __p;
        __large.__cap = __size + 1;
    }

    basic_string& operator+=(const _Str& __s) {
        append(__s);
        return *this;
    }

    basic_string& operator+=(const char* __s) {
        append(__s);
        return *this;
    }

    basic_string& operator+=(char __c) {
        append({&__c, 1});
        return *this;
    }

    basic_string operator+(const _Str& __s) const {
        basic_string __result(*this);
        __result.append(__s);
        return __result;
    }

    basic_string operator+(const char* __s) const {
        basic_string __result(*this);
        __result.append(__s);
        return __result;
    }

    basic_string operator+(char __c) const {
        basic_string __result(*this);
        __result.append(__c);
        return __result;
    }

    /// =======================================================================
    ///  Removing elements.
    /// =======================================================================
    void __remove_trailing(basic_string_view<_Char> __other) { ::std::__detail::__remove_trailing(*this, __other); }

    void clear() {
        if (!__is_large()) {
            __small.__data[0] = 0;
            __small.__rem_cap = __max_chars_small;
        }

        else {
            __large.__data[0] = 0;
            __large.__sz = 0;
        }
    }

    void erase(size_t __pos = 0, size_t __n = npos) {
        const auto __size = size();
        if (__pos >= __size) { return; }
        if (__n >= __size || __pos + __n >= __size) { __n = __size - __pos; }

        /// Truncate if we're erasing up to the end of the string.
        if (__pos + __n == __size) {
            if (!__is_large()) {
                __small.__data[__pos] = 0;
                __small.__rem_cap += __n;
            } else {
                __large.__data[__pos] = 0;
                __large.__sz = __pos;
            }
            return;
        }

        /// Otherwise, we need to move the remaining characters to the left.
        if (!__is_large()) {
            memmove(__small.__data + __pos, __small.__data + __pos + __n, (__size - __pos - __n + 1) * sizeof(_Char));
            __small.__rem_cap += __n;
        } else {
            memmove(__large.__data + __pos, __large.__data + __pos + __n, (__size - __pos - __n + 1) * sizeof(_Char));
            __large.__sz -= __n;
        }
    }

    void erase(iterator __first, iterator __last) {
        auto __begin = begin();
        auto __end = end();

        /// FIXME: Should throw or something.
        if (__first < __begin) { __first = __begin; }
        if (__last < __begin) { __last = __begin; }
        else if (__last > __end) { __last = __end; }

        erase(size_t(__first - __begin), size_t(__last - __first));
    }

    void erase(iterator __first) { erase(__first, __first + 1); }

    /// =======================================================================
    ///  Comparisons, searches, and checks.
    /// =======================================================================
    _Nodiscard int compare(basic_string_view<_Char> __sv) const { return __sv.compare(__view()); }

    _Nodiscard size_t find(_Char __c, size_t __pos = 0) const { return __view().find(__c, __pos); }
    _Nodiscard size_t find(_View __sv, size_t __pos = 0) const { return __view().find(__sv, __pos); }

    _Nodiscard size_t find_first_of(_View __sv, size_t __pos = 0) const { return __view().find_first_of(__sv, __pos); }
    _Nodiscard size_t find_first_not_of(_View __sv, size_t __pos = 0) const { return __view().find_first_not_of(__sv, __pos); }
    _Nodiscard size_t find_last_of(_View __sv, size_t __pos = npos) const { return __view().find_last_of(__sv, __pos); }

    _Nodiscard bool starts_with(_View __sv) const { return __view().starts_with(__sv); }
    _Nodiscard bool ends_with(_View __sv) const { return __view().ends_with(__sv); }

    _Nodiscard bool contains(_View __sv) const { return __view().contains(__sv); }
    _Nodiscard bool contains(_Char __c) const { return __view().contains(__c); }
};

template <typename _Char>
_Nodiscard bool operator==(const basic_string<_Char>& __a, const basic_string<_Char>& __b) {
    return basic_string_view<_Char>(__a) == basic_string_view<_Char>(__b);
}

template <typename _Char>
_Nodiscard bool operator==(const basic_string<_Char>& __a, const _Char* __b) {
    return basic_string_view<_Char>(__a) == basic_string_view<_Char>(__b);
}

/// TODO: Use operator<=>.
template <typename _Char>
_Nodiscard bool operator!=(const basic_string<_Char>& __a, const basic_string<_Char>& __b) {
    return basic_string_view<_Char>(__a) != basic_string_view<_Char>(__b);
}

template <typename _Char>
_Nodiscard bool operator<(const basic_string<_Char>& __a, const basic_string<_Char>& __b) {
    return basic_string_view<_Char>(__a) < basic_string_view<_Char>(__b);
}

template <typename _Char>
_Nodiscard bool operator>(const basic_string<_Char>& __a, const basic_string<_Char>& __b) {
    return basic_string_view<_Char>(__a) > basic_string_view<_Char>(__b);
}

template <typename _Char>
_Nodiscard bool operator<=(const basic_string<_Char>& __a, const basic_string<_Char>& __b) {
    return basic_string_view<_Char>(__a) <= basic_string_view<_Char>(__b);
}

template <typename _Char>
_Nodiscard bool operator>=(const basic_string<_Char>& __a, const basic_string<_Char>& __b) {
    return basic_string_view<_Char>(__a) >= basic_string_view<_Char>(__b);
}

using string_view = basic_string_view<char>;
using wstring_view = basic_string_view<wchar_t>;
using u16string_view = basic_string_view<char16_t>;
using u32string_view = basic_string_view<char32_t>;

using string = basic_string<char>;
using wstring = basic_string<wchar_t>;
using u16string = basic_string<char16_t>;
using u32string = basic_string<char32_t>;

template <typename _Char, integral _Int>
__forceinline basic_string<_Char> __to_string(_Int __i, uint8_t __base = 10, bool __uppercase = false) {
    basic_string<_Char> __result;

    /// Append a '-' if the number is negative.
    if constexpr (std::is_signed_v<_Int>) {
        if (__i < 0) {
            __result += _Char('-');
            __i = -__i;
        }
    }

    /// If the number is 0, we're done.
    if (__i == 0) {
        __result += _Char('0');
        return __result;
    }

    /// Otherwise, append the digits.
    while (__i) {
        auto __digit = __i % __base;
        __i /= __base;

        if (__digit > 9) { __result += _Char((__uppercase ? 'A' : 'a') + __digit - 10); }
        else { __result += _Char('0' + __digit); }
    }

    /// Reverse the string manually.
    auto __size = __result.size();
    for (size_t __j = 0; __j < __size / 2; ++__j) {
        auto __tmp = __result[__j];
        __result[__j] = __result[__size - __j - 1];
        __result[__size - __j - 1] = __tmp;
    }

    return __result;
}

template <typename _Char, floating_point _Float>
__forceinline basic_string<_Char> __to_string(_Float __f, size_t __prec = 16) {
#ifdef __SSE__
    basic_string<_Char> __result;

    /// Handle nan, inf, and -inf.
    if (isnan(__f)) { return "nan"; }
    if (isinf(__f)) { return __f < 0 ? "-inf" : "inf"; }

    /// Append a '-' if the number is negative.
    if (__f < 0) {
        __result += _Char('-');
        __f = -__f;
    }

    /// Append the integer part.
    __result += __to_string<_Char>(int64_t(__f));
    __f -= static_cast<int64_t>(__f);
    __prec = std::min(__prec, size_t(16));

    /// Append the fractional part.
    /// TODO: Find a better way to do this.
    if (__prec && (__f < -1e-7 || __f > 1e-7)) {
        __result += _Char('.');

        while (__prec-- && (__f < -1e-7 || __f > 1e-7)) {
            __f *= 10;
            __result += _Char('0' + static_cast<int64_t>(__f));
            __f -= static_cast<int64_t>(__f);
        }
    }

    return __result;
#else
    return "(FLOAT)";
#endif
}

inline string to_string(int __i) { return __to_string<char>(__i); }
inline string to_string(long __i) { return __to_string<char>(__i); }
inline string to_string(long long __i) { return __to_string<char>(__i); }
inline string to_string(unsigned __i) { return __to_string<char>(__i); }
inline string to_string(unsigned long __i) { return __to_string<char>(__i); }
inline string to_string(unsigned long long __i) { return __to_string<char>(__i); }
inline string to_string(float __f) { return __to_string<char>(__f); }
inline string to_string(double __f) { return __to_string<char>(__f); }
inline string to_string(long double __f) { return __to_string<char>(__f); }

} // namespace std
#endif // _LENSOROS_STRING_
