<commit_before>#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
#define ENTT_RESOURCE_RESOURCE_CACHE_HPP

#include <cstddef>
#include <functional>
#include <iterator>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include "../config/config.h"
#include "../container/dense_map.hpp"
#include "../core/compressed_pair.hpp"
#include "../core/fwd.hpp"
#include "../core/iterator.hpp"
#include "../core/utility.hpp"
#include "fwd.hpp"
#include "loader.hpp"
#include "resource.hpp"

namespace entt {

/**
 * @cond TURN_OFF_DOXYGEN
 * Internal details not to be documented.
 */

namespace internal {

template<typename Type, typename It>
class resource_cache_iterator final {
    template<typename, typename>
    friend class resource_cache_iterator;

public:
    using value_type = std::pair<id_type, resource<Type>>;
    using pointer = input_iterator_pointer<value_type>;
    using reference = value_type;
    using difference_type = std::ptrdiff_t;
    using iterator_category = std::input_iterator_tag;

    resource_cache_iterator() ENTT_NOEXCEPT = default;

    resource_cache_iterator(const It iter) ENTT_NOEXCEPT
        : it{iter} {}

    template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
    resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) ENTT_NOEXCEPT
        : it{other.it} {}

    resource_cache_iterator &operator++() ENTT_NOEXCEPT {
        return ++it, *this;
    }

    resource_cache_iterator operator++(int) ENTT_NOEXCEPT {
        resource_cache_iterator orig = *this;
        return ++(*this), orig;
    }

    resource_cache_iterator &operator--() ENTT_NOEXCEPT {
        return --it, *this;
    }

    resource_cache_iterator operator--(int) ENTT_NOEXCEPT {
        resource_cache_iterator orig = *this;
        return operator--(), orig;
    }

    resource_cache_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
        it += value;
        return *this;
    }

    resource_cache_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
        resource_cache_iterator copy = *this;
        return (copy += value);
    }

    resource_cache_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
        return (*this += -value);
    }

    resource_cache_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
        return (*this + -value);
    }

    [[nodiscard]] reference operator[](const difference_type value) const ENTT_NOEXCEPT {
        return {it[value].first, resource<Type>{it[value].second}};
    }

    [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
        return (*this)[0];
    }

    [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
        return operator*();
    }

    template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
    friend std::ptrdiff_t operator-(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;

    template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
    friend bool operator==(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;

    template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
    friend bool operator<(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;

private:
    It it;
};

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] std::ptrdiff_t operator-(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return lhs.it - rhs.it;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] bool operator==(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return lhs.it == rhs.it;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] bool operator!=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return !(lhs == rhs);
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] bool operator<(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return lhs.it < rhs.it;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] bool operator>(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return rhs < lhs;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] bool operator<=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return !(lhs > rhs);
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] bool operator>=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return !(lhs < rhs);
}

} // namespace internal

/**
 * Internal details not to be documented.
 * @endcond
 */

/**
 * @brief Basic cache for resources of any type.
 * @tparam Type Type of resources managed by a cache.<commit_msg>resource_cache: constexpr all the way (see #883)<commit_after>#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
#define ENTT_RESOURCE_RESOURCE_CACHE_HPP

#include <cstddef>
#include <functional>
#include <iterator>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include "../config/config.h"
#include "../container/dense_map.hpp"
#include "../core/compressed_pair.hpp"
#include "../core/fwd.hpp"
#include "../core/iterator.hpp"
#include "../core/utility.hpp"
#include "fwd.hpp"
#include "loader.hpp"
#include "resource.hpp"

namespace entt {

/**
 * @cond TURN_OFF_DOXYGEN
 * Internal details not to be documented.
 */

namespace internal {

template<typename Type, typename It>
class resource_cache_iterator final {
    template<typename, typename>
    friend class resource_cache_iterator;

public:
    using value_type = std::pair<id_type, resource<Type>>;
    using pointer = input_iterator_pointer<value_type>;
    using reference = value_type;
    using difference_type = std::ptrdiff_t;
    using iterator_category = std::input_iterator_tag;

    constexpr resource_cache_iterator() ENTT_NOEXCEPT = default;

    constexpr resource_cache_iterator(const It iter) ENTT_NOEXCEPT
        : it{iter} {}

    template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
    constexpr resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) ENTT_NOEXCEPT
        : it{other.it} {}

    constexpr resource_cache_iterator &operator++() ENTT_NOEXCEPT {
        return ++it, *this;
    }

    constexpr resource_cache_iterator operator++(int) ENTT_NOEXCEPT {
        resource_cache_iterator orig = *this;
        return ++(*this), orig;
    }

    constexpr resource_cache_iterator &operator--() ENTT_NOEXCEPT {
        return --it, *this;
    }

    constexpr resource_cache_iterator operator--(int) ENTT_NOEXCEPT {
        resource_cache_iterator orig = *this;
        return operator--(), orig;
    }

    constexpr resource_cache_iterator &operator+=(const difference_type value) ENTT_NOEXCEPT {
        it += value;
        return *this;
    }

    constexpr resource_cache_iterator operator+(const difference_type value) const ENTT_NOEXCEPT {
        resource_cache_iterator copy = *this;
        return (copy += value);
    }

    constexpr resource_cache_iterator &operator-=(const difference_type value) ENTT_NOEXCEPT {
        return (*this += -value);
    }

    constexpr resource_cache_iterator operator-(const difference_type value) const ENTT_NOEXCEPT {
        return (*this + -value);
    }

    [[nodiscard]] constexpr reference operator[](const difference_type value) const ENTT_NOEXCEPT {
        return {it[value].first, resource<Type>{it[value].second}};
    }

    [[nodiscard]] constexpr reference operator*() const ENTT_NOEXCEPT {
        return (*this)[0];
    }

    [[nodiscard]] constexpr pointer operator->() const ENTT_NOEXCEPT {
        return operator*();
    }

    template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
    friend constexpr std::ptrdiff_t operator-(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;

    template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
    friend constexpr bool operator==(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;

    template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
    friend constexpr bool operator<(const resource_cache_iterator<TLhs, ILhs> &, const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;

private:
    It it;
};

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr std::ptrdiff_t operator-(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return lhs.it - rhs.it;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr bool operator==(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return lhs.it == rhs.it;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr bool operator!=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return !(lhs == rhs);
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr bool operator<(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return lhs.it < rhs.it;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr bool operator>(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return rhs < lhs;
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr bool operator<=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return !(lhs > rhs);
}

template<typename TLhs, typename ILhs, typename TRhs, typename IRhs>
[[nodiscard]] constexpr bool operator>=(const resource_cache_iterator<TLhs, ILhs> &lhs, const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
    return !(lhs < rhs);
}

} // namespace internal

/**
 * Internal details not to be documented.
 * @endcond
 */

/**
 * @brief Basic cache for resources of any type.
 * @tparam Type Type of resources managed by a cache.
{'fraction_non_alphanumeric': 0.1120493961681649, 'fraction_numerical': 0.0004540088985744121, 'mean_word_length': 4.7454355764214915, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 109, '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': '4010730', 'n_tokens_mistral': 3641, 'n_tokens_neox': 3431, 'n_words': 877}