<commit_before>#pragma once

#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <type_traits>
#include <utility> // forward

#ifdef _MSC_VER
#  define FMTXX_VISIBILITY_DEFAULT
#else
#  define FMTXX_VISIBILITY_DEFAULT __attribute__((visibility("default")))
#endif

#ifdef FMTXX_SHARED
#  ifdef _MSC_VER
#    ifdef FMTXX_EXPORT
#      define FMTXX_API __declspec(dllexport)
#    else
#      define FMTXX_API __declspec(dllimport)
#    endif
#  else
#    ifdef FMTXX_EXPORT
#      define FMTXX_API FMTXX_VISIBILITY_DEFAULT
#    else
#      define FMTXX_API
#    endif
#  endif
#else
#  define FMTXX_API
#endif

namespace fmtxx {

class StringView // A minimal replacement for std::string_view
{
    char const* data_ = nullptr;
    size_t      size_ = 0;

public:
    using pointer  = char const*;
    using iterator = char const*;

public:
    StringView() = default;
    StringView(pointer p, size_t len) : data_(p), size_(len) {}

    // Construct from null-terminated C-string.
    StringView(pointer c_str)
        : data_(c_str)
        , size_(c_str ? Length(c_str) : 0u)
    {
    }

    // Construct from iterator range.
    StringView(iterator first, iterator last)
        : data_(first)
        , size_(static_cast<size_t>(last - first))
    {
    }

    // Construct from contiguous character sequence
    template <
        typename T,
        typename DataT = decltype(std::declval<T const&>().data()),
        typename SizeT = decltype(std::declval<T const&>().size()),
        typename = typename std::enable_if<
            std::is_convertible<DataT, pointer>::value &&
            std::is_convertible<SizeT, size_t>::value
        >::type
    >
    StringView(T const& str)
        : data_(str.data())
        , size_(str.size())
    {
    }

    // Convert to string types.
    template <
        typename T,
        typename = typename std::enable_if<
            std::is_constructible<T, pointer, size_t>::value
        >::type
    >
    explicit operator T() const { return T(data(), size()); }

    // Returns a pointer to the start of the string.
    // NOTE: Not neccessarily null-terminated!
    pointer data() const { return data_; }

    // Returns the length of the string.
    size_t size() const { return size_; }

    // Returns whether the string is empty.
    bool empty() const { return size_ == 0; }

    // Returns an iterator pointing to the start of the string.
    iterator begin() const { return data_; }

    // Returns an iterator pointing past the end of the string.
    iterator end() const { return data_ + size_; }

    // Test if *this equals rhs.
    bool equal(StringView rhs) const;

    // Lexicographically compare *this and rhs.
    bool less(StringView rhs) const;

private:
    static size_t Length(char const* c_str) {
        return ::strlen(c_str);
    }

    static int Compare(char const* lhs, char const* rhs, size_t n) {
        return ::memcmp(lhs, rhs, n);
    }
};

inline bool StringView::equal(StringView rhs) const {
    return size() == rhs.size() && Compare(data(), rhs.data(), size()) == 0;
}

inline bool StringView::less(StringView rhs) const {
    int c = Compare(data(), rhs.data(), size() < rhs.size() ? size() : rhs.size());
    return c < 0 || (c == 0 && size() < rhs.size());
}

inline bool operator==(StringView lhs, StringView rhs) {
    return lhs.equal(rhs);
}

inline bool operator!=(StringView lhs, StringView rhs) {
    return !(lhs == rhs);
}

inline bool operator<(StringView lhs, StringView rhs) {
    return lhs.less(rhs);
}

inline bool operator>(StringView lhs, StringView rhs) {
    return rhs < lhs;
}

inline bool operator<=(StringView lhs, StringView rhs) {
    return !(rhs < lhs);
}

inline bool operator>=(StringView lhs, StringView rhs) {
    return !(lhs < rhs);
}

enum struct errc {
    success = 0,
    conversion_error,       // Value could not be converted to string. (E.g.: trying to format a non-existant date.)
    index_out_of_range,     // Argument index out of range
    invalid_argument,
    invalid_format_string,
    io_error,               // Writer failed. (XXX: Writer::Put() etc should probably return an error code?!)
    not_supported,          // Conversion not supported
    value_out_of_range,     // Value of integer argument out of range [INT_MIN, INT_MAX]
};

// Wraps an error code, may be checked for failure.
// Replaces err::operator bool() in most cases (and is more explicit).
struct Failed
{
    const errc ec = errc::success;<commit_msg>Inline strlen and memcmp again<commit_after>#pragma once

#include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <type_traits>
#include <utility> // forward

#ifdef _MSC_VER
#  define FMTXX_VISIBILITY_DEFAULT
#else
#  define FMTXX_VISIBILITY_DEFAULT __attribute__((visibility("default")))
#endif

#ifdef FMTXX_SHARED
#  ifdef _MSC_VER
#    ifdef FMTXX_EXPORT
#      define FMTXX_API __declspec(dllexport)
#    else
#      define FMTXX_API __declspec(dllimport)
#    endif
#  else
#    ifdef FMTXX_EXPORT
#      define FMTXX_API FMTXX_VISIBILITY_DEFAULT
#    else
#      define FMTXX_API
#    endif
#  endif
#else
#  define FMTXX_API
#endif

namespace fmtxx {

class StringView // A minimal replacement for std::string_view
{
    char const* data_ = nullptr;
    size_t      size_ = 0;

public:
    using pointer  = char const*;
    using iterator = char const*;

public:
    StringView() = default;
    StringView(pointer p, size_t len) : data_(p), size_(len) {}

    // Construct from null-terminated C-string.
    StringView(pointer c_str)
        : data_(c_str)
        , size_(c_str ? ::strlen(c_str) : 0u)
    {
    }

    // Construct from iterator range.
    StringView(iterator first, iterator last)
        : data_(first)
        , size_(static_cast<size_t>(last - first))
    {
    }

    // Construct from contiguous character sequence
    template <
        typename T,
        typename DataT = decltype(std::declval<T const&>().data()),
        typename SizeT = decltype(std::declval<T const&>().size()),
        typename = typename std::enable_if<
            std::is_convertible<DataT, pointer>::value &&
            std::is_convertible<SizeT, size_t>::value
        >::type
    >
    StringView(T const& str)
        : data_(str.data())
        , size_(str.size())
    {
    }

    // Convert to string types.
    template <
        typename T,
        typename = typename std::enable_if<
            std::is_constructible<T, pointer, size_t>::value
        >::type
    >
    explicit operator T() const { return T(data(), size()); }

    // Returns a pointer to the start of the string.
    // NOTE: Not neccessarily null-terminated!
    pointer data() const { return data_; }

    // Returns the length of the string.
    size_t size() const { return size_; }

    // Returns whether the string is empty.
    bool empty() const { return size_ == 0; }

    // Returns an iterator pointing to the start of the string.
    iterator begin() const { return data_; }

    // Returns an iterator pointing past the end of the string.
    iterator end() const { return data_ + size_; }
};

inline bool operator==(StringView lhs, StringView rhs) {
    return lhs.size() == rhs.size() && ::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}

inline bool operator!=(StringView lhs, StringView rhs) {
    return !(lhs == rhs);
}

inline bool operator<(StringView lhs, StringView rhs) {
    int c = ::memcmp(lhs.data(), rhs.data(), lhs.size() < rhs.size() ? lhs.size() : rhs.size());
    return c < 0 || (c == 0 && lhs.size() < rhs.size());
}

inline bool operator>(StringView lhs, StringView rhs) {
    return rhs < lhs;
}

inline bool operator<=(StringView lhs, StringView rhs) {
    return !(rhs < lhs);
}

inline bool operator>=(StringView lhs, StringView rhs) {
    return !(lhs < rhs);
}

enum struct errc {
    success = 0,
    conversion_error,       // Value could not be converted to string. (E.g.: trying to format a non-existant date.)
    index_out_of_range,     // Argument index out of range
    invalid_argument,
    invalid_format_string,
    io_error,               // Writer failed. (XXX: Writer::Put() etc should probably return an error code?!)
    not_supported,          // Conversion not supported
    value_out_of_range,     // Value of integer argument out of range [INT_MIN, INT_MAX]
};

// Wraps an error code, may be checked for failure.
// Replaces err::operator bool() in most cases (and is more explicit).
struct Failed
{
    const errc ec = errc::success;
{'fraction_non_alphanumeric': 0.11870712707824671, 'fraction_numerical': 0.0016277177072433438, 'mean_word_length': 2.9029038112522687, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 43, 'https://': 0, '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': '3337452', 'n_tokens_mistral': 2764, 'n_tokens_neox': 2672, 'n_words': 823}