entity: constrain iterator types

This commit is contained in:
skypjack
2026-01-19 13:56:39 +01:00
parent d447f8c14a
commit 682f6b2392
6 changed files with 26 additions and 20 deletions

View File

@@ -2,6 +2,7 @@
#define ENTT_ENTITY_GROUP_HPP
#include <array>
#include <concepts>
#include <cstddef>
#include <iterator>
#include <tuple>
@@ -642,7 +643,7 @@ public:
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
*/
template<typename It>
template<std::input_iterator It>
void sort_as(It first, It last) const {
if(*this) {
descriptor->handle().sort_as(first, last);

View File

@@ -1,6 +1,7 @@
#ifndef ENTT_ENTITY_MIXIN_HPP
#define ENTT_ENTITY_MIXIN_HPP
#include <concepts>
#include <type_traits>
#include <utility>
#include "../config/config.h"
@@ -309,11 +310,11 @@ public:
/**
* @brief Assigns each element in a range an identifier.
* @tparam It Type of mutable forward iterator.
* @tparam It Type of output iterator.
* @param first An iterator to the first element of the range to generate.
* @param last An iterator past the last element of the range to generate.
*/
template<typename It>
template<std::output_iterator<entity_type> It>
void generate(It first, It last) {
underlying_type::generate(first, last);
@@ -361,7 +362,7 @@ public:
* @param last An iterator past the last element of the range of entities.
* @param args Parameters to use to forward to the underlying storage.
*/
template<typename It, typename... Args>
template<std::input_iterator It, typename... Args>
void insert(It first, It last, Args &&...args) {
auto from = underlying_type::size();
underlying_type::insert(first, last, std::forward<Args>(args)...);

View File

@@ -4,6 +4,7 @@
#include <algorithm>
#include <array>
#include <compare>
#include <concepts>
#include <cstddef>
#include <functional>
#include <iterator>
@@ -485,11 +486,11 @@ public:
*
* @sa create
*
* @tparam It Type of forward iterator.
* @tparam It Type of output iterator.
* @param first An iterator to the first element of the range to generate.
* @param last An iterator past the last element of the range to generate.
*/
template<typename It>
template<std::output_iterator<entity_type> It>
void create(It first, It last) {
entities.generate(std::move(first), std::move(last));
}
@@ -540,7 +541,7 @@ public:
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
*/
template<typename It>
template<std::input_iterator It>
void destroy(It first, It last) {
const auto to = entities.sort_as(first, last);
const auto from = entities.cend() - static_cast<common_type::difference_type>(entities.free_list());
@@ -583,7 +584,7 @@ public:
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
*/
template<typename Type, typename It>
template<typename Type, std::input_iterator It>
void insert(It first, It last) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
assure<Type>().insert(std::move(first), std::move(last));
@@ -600,7 +601,7 @@ public:
* @param last An iterator past the last element of the range of entities.
* @param value An instance of the element to assign.
*/
template<typename Type, typename It>
template<typename Type, std::input_iterator It>
void insert(It first, It last, const Type &value) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
assure<Type>().insert(std::move(first), std::move(last), value);
@@ -711,7 +712,7 @@ public:
* @param last An iterator past the last element of the range of entities.
* @return The number of elements actually removed.
*/
template<typename Type, typename... Other, typename It>
template<typename Type, typename... Other, std::input_iterator It>
size_type remove(It first, It last) {
size_type count{};
@@ -764,7 +765,7 @@ public:
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
*/
template<typename Type, typename... Other, typename It>
template<typename Type, typename... Other, std::input_iterator It>
void erase(It first, It last) {
if constexpr(std::is_same_v<It, typename common_type::iterator>) {
std::array cpools{static_cast<common_type *>(&assure<Type>()), static_cast<common_type *>(&assure<Other>())...};

View File

@@ -1,6 +1,7 @@
#ifndef ENTT_ENTITY_SNAPSHOT_HPP
#define ENTT_ENTITY_SNAPSHOT_HPP
#include <concepts>
#include <cstddef>
#include <iterator>
#include <tuple>
@@ -136,7 +137,7 @@ public:
* @param id Optional name used to map the storage within the registry.
* @return An object of this type to continue creating the snapshot.
*/
template<typename Type, typename Archive, typename It>
template<typename Type, typename Archive, std::input_iterator It>
const basic_snapshot &get(Archive &archive, It first, It last, const id_type id = type_hash<Type>::value()) const {
static_assert(!std::is_same_v<Type, entity_type>, "Entity types not supported");

View File

@@ -2,6 +2,7 @@
#define ENTT_ENTITY_SPARSE_SET_HPP
#include <compare>
#include <concepts>
#include <cstddef>
#include <iterator>
#include <memory>
@@ -791,7 +792,7 @@ public:
* @return Iterator pointing to the first element inserted in case of
* success, the `end()` iterator otherwise.
*/
template<typename It>
template<std::input_iterator It>
iterator push(It first, It last) {
auto curr = end();
@@ -843,7 +844,7 @@ public:
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
*/
template<typename It>
template<std::input_iterator It>
void erase(It first, It last) {
if constexpr(std::is_same_v<It, basic_iterator>) {
pop(first, last);
@@ -870,7 +871,7 @@ public:
* @param last An iterator past the last element of the range of entities.
* @return The number of entities actually removed.
*/
template<typename It>
template<std::input_iterator It>
size_type remove(It first, It last) {
size_type count{};
@@ -1029,7 +1030,7 @@ public:
* @param last An iterator past the last element of the range of entities.
* @return An iterator past the last of the elements actually shared.
*/
template<typename It>
template<std::input_iterator It>
iterator sort_as(It first, It last) {
ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed");
const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size();

View File

@@ -2,6 +2,7 @@
#define ENTT_ENTITY_STORAGE_HPP
#include <compare>
#include <concepts>
#include <cstddef>
#include <iterator>
#include <memory>
@@ -693,7 +694,7 @@ public:
* @param value An instance of the object to construct.
* @return Iterator pointing to the first element inserted, if any.
*/
template<typename It>
template<std::input_iterator It>
iterator insert(It first, It last, const value_type &value = {}) {
for(; first != last; ++first) {
emplace_element(*first, true, value);
@@ -901,7 +902,7 @@ public:
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
*/
template<typename It>
template<std::input_iterator It>
void insert(It first, It last) {
for(; first != last; ++first) {
base_type::try_emplace(*first, true);
@@ -1131,11 +1132,11 @@ public:
/**
* @brief Assigns each element in a range an identifier.
* @tparam It Type of mutable forward iterator.
* @tparam It Type of output iterator.
* @param first An iterator to the first element of the range to generate.
* @param last An iterator past the last element of the range to generate.
*/
template<typename It>
template<std::output_iterator<entity_type> It>
void generate(It first, It last) {
for(const auto sz = base_type::size(); first != last && base_type::free_list() != sz; ++first) {
*first = *base_type::try_emplace(base_type::data()[base_type::free_list()], true);