<commit_before>#pragma once

#include <util/digest/crc.h>

namespace util {

struct TypeInfo {
    uint32_t hash;
    uint32_t size;
    const void* serde;
};

template<typename T>
class TypeName {
    struct NamePtr {
        static constexpr const char* _getPtr() {
            const char* p = __PRETTY_FUNCTION__;
            while (*p++ != '=') { }
            return p + 1;
        }

        static constexpr const char* p = _getPtr();
    };

    static constexpr size_t _length() {
        const char* p = NamePtr::p;
        size_t length = 0;
        for (; !(*p == '\0' || *p == ']'); p++) {
            if (*p == ' ' && p[-1] == '>')
                continue;

            ++length;
        }
        return length;
    }

public:
    static constexpr size_t length = _length();

private:
    template<size_t length>
    struct Name {
        char a[length + 1]{};
    };

    static constexpr Name<length> _name() {
        Name<length> name;
        char* dest = name.a;
        const char* p = NamePtr::p;
        for (; !(*p == '\0' || *p == ']'); p++) {
            if (*p == ' ' && p[-1] == '>')
                continue;

            *dest++ = *p;
        }
        return name;
    }

    static constexpr Name<length> _nameStore = _name();

public:
    static constexpr const char* name = _nameStore.a;
};

template<typename T>
class TypeHash {
    static constexpr unsigned int _hash() noexcept {
        util::digest::CRC32 crc;
        const char* p = TypeName<T>::name;
        for (size_t i = 0; i < TypeName<T>::length; i++, p++)
            crc.put(*p);

        return crc.finish();
    }

public:
    static constexpr uint32_t hash = _hash();
};

// convenience functions
template<typename T>
constexpr uint32_t typeHash() noexcept {
    return TypeHash<T>::hash;
}

template<typename T>
constexpr uint32_t typeHash(const T&) noexcept {
    return TypeHash<T>::hash;
}

template<typename T>
constexpr const char* typeName() noexcept {
    return TypeName<T>::name;
}

template<typename T>
constexpr const char* typeName(const T&) noexcept {
    return TypeName<T>::name;
}

} // namespace util

<commit_msg>Make TypeName usable with GCC >= 5.4<commit_after>#pragma once

#include <util/digest/crc.h>

namespace util {

struct TypeInfo {
    uint32_t hash;
    uint32_t size;
    const void* serde;
};

template<typename T>
class TypeName {
private:
    static constexpr unsigned int _length() {
        const char* p = __PRETTY_FUNCTION__;
        while (*p != '=')
            p++;
        p += 2;

        unsigned int length = 0;
        for (; *p != ']'; p++) {
            if (*p == ' ' && p[-1] == '>')
                continue;

            ++length;
        }
        return length;
    }

public:
    static constexpr size_t length = _length();

private:
    template<size_t length>
    struct Name {
        char a[length + 1]{};
    };

    static constexpr Name<length> _name() {
        const char* p = __PRETTY_FUNCTION__;
        while (*p != '=')
            p++;
        p += 2;

        Name<length> name;
        char* dest = name.a;
        for (; *p != ']'; p++) {
            if (*p == ' ' && p[-1] == '>')
                continue;

            *dest++ = *p;
        }
        return name;
    }

    static constexpr Name<length> _nameStore = _name();

public:
    static constexpr const char* name = _nameStore.a;
};

template<typename T>
class TypeHash {
private:
    static constexpr unsigned int _hash() noexcept {
        util::digest::CRC32 crc;
        const char* p = TypeName<T>::name;
        for (size_t i = 0; i < TypeName<T>::length; i++, p++)
            crc.put(*p);

        return crc.finish();
    }

public:
    static constexpr uint32_t hash = _hash();
};

// convenience functions
template<typename T>
constexpr uint32_t typeHash() noexcept {
    return TypeHash<T>::hash;
}

template<typename T>
constexpr uint32_t typeHash(const T&) noexcept {
    return TypeHash<T>::hash;
}

template<typename T>
constexpr const char* typeName() noexcept {
    return TypeName<T>::name;
}

template<typename T>
constexpr const char* typeName(const T&) noexcept {
    return TypeName<T>::name;
}

} // namespace util


{'fraction_non_alphanumeric': 0.14285714285714285, 'fraction_numerical': 0.009810959559703278, 'mean_word_length': 2.1835491241431835, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 42, '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': '1262433', 'n_tokens_mistral': 1401, 'n_tokens_neox': 1327, 'n_words': 371}