stl: fake iterator concepts to make up for the lack on some platforms
This commit is contained in:
@@ -194,6 +194,7 @@ if(ENTT_INCLUDE_HEADERS)
|
||||
signal/emitter.hpp
|
||||
signal/fwd.hpp
|
||||
signal/sigh.hpp
|
||||
stl/concepts.hpp
|
||||
stl/functional.hpp
|
||||
stl/memory.hpp
|
||||
tools/davey.hpp
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "../core/iterator.hpp"
|
||||
#include "../core/memory.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "fwd.hpp"
|
||||
|
||||
namespace entt {
|
||||
@@ -547,7 +548,7 @@ public:
|
||||
* @param first An iterator to the first element of the range of elements.
|
||||
* @param last An iterator past the last element of the range of elements.
|
||||
*/
|
||||
void insert(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
void insert(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) {
|
||||
for(; first != last; ++first) {
|
||||
insert(*first);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "../core/bit.hpp"
|
||||
#include "../core/compressed_pair.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "fwd.hpp"
|
||||
|
||||
namespace entt {
|
||||
@@ -524,7 +525,7 @@ public:
|
||||
* @param first An iterator to the first element of the range of elements.
|
||||
* @param last An iterator past the last element of the range of elements.
|
||||
*/
|
||||
void insert(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
void insert(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) {
|
||||
for(; first != last; ++first) {
|
||||
insert(*first);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "../stl/functional.hpp"
|
||||
|
||||
namespace entt {
|
||||
@@ -33,7 +34,7 @@ struct std_sort {
|
||||
* @param args Arguments to forward to the sort function, if any.
|
||||
*/
|
||||
template<typename Compare = std::less<>, typename... Args>
|
||||
void operator()(std::random_access_iterator auto first, std::random_access_iterator auto last, Compare compare = Compare{}, Args &&...args) const {
|
||||
void operator()(entt::stl::random_access_iterator auto first, entt::stl::random_access_iterator auto last, Compare compare = Compare{}, Args &&...args) const {
|
||||
std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
|
||||
}
|
||||
};
|
||||
@@ -51,7 +52,7 @@ struct insertion_sort {
|
||||
* @param compare A valid comparison function object.
|
||||
*/
|
||||
template<typename Compare = std::less<>>
|
||||
void operator()(std::random_access_iterator auto first, std::random_access_iterator auto last, Compare compare = Compare{}) const {
|
||||
void operator()(entt::stl::random_access_iterator auto first, entt::stl::random_access_iterator auto last, Compare compare = Compare{}) const {
|
||||
if(first < last) {
|
||||
for(auto it = first + 1; it < last; ++it) {
|
||||
auto value = std::move(*it);
|
||||
@@ -93,7 +94,7 @@ struct radix_sort {
|
||||
* @param last An iterator past the last element of the range to sort.
|
||||
* @param getter A valid _getter_ function object.
|
||||
*/
|
||||
template<std::random_access_iterator It, typename Getter = stl::identity>
|
||||
template<entt::stl::random_access_iterator It, typename Getter = stl::identity>
|
||||
void operator()(It first, It last, Getter getter = Getter{}) const {
|
||||
if(first < last) {
|
||||
constexpr auto passes = N / Bit;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "../stl/concepts.hpp"
|
||||
|
||||
namespace entt {
|
||||
|
||||
@@ -120,7 +121,7 @@ private:
|
||||
* @tparam It Type of iterator.
|
||||
* @tparam Sentinel Type of sentinel.
|
||||
*/
|
||||
template<std::input_or_output_iterator It, std::sentinel_for<It> Sentinel = It>
|
||||
template<entt::stl::input_or_output_iterator It, entt::stl::sentinel_for<It> Sentinel = It>
|
||||
struct iterable_adaptor final {
|
||||
/*! @brief Value type. */
|
||||
using value_type = std::iterator_traits<It>::value_type;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "../core/iterator.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
void sort_as(std::input_iterator auto first, std::input_iterator auto last) const {
|
||||
void sort_as(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) const {
|
||||
if(*this) {
|
||||
descriptor->handle().sort_as(first, last);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "../core/any.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../signal/sigh.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
|
||||
@@ -362,7 +363,7 @@ public:
|
||||
* @param args Parameters to use to forward to the underlying storage.
|
||||
*/
|
||||
template<typename... Args>
|
||||
void insert(std::input_iterator auto first, std::input_iterator auto last, Args &&...args) {
|
||||
void insert(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last, Args &&...args) {
|
||||
auto from = underlying_type::size();
|
||||
underlying_type::insert(first, last, std::forward<Args>(args)...);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "../core/memory.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "../stl/functional.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
@@ -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.
|
||||
*/
|
||||
void destroy(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
void destroy(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) {
|
||||
const auto to = entities.sort_as(first, last);
|
||||
const auto from = entities.cend() - static_cast<common_type::difference_type>(entities.free_list());
|
||||
|
||||
@@ -582,7 +583,7 @@ public:
|
||||
* @param last An iterator past the last element of the range of entities.
|
||||
*/
|
||||
template<typename Type>
|
||||
void insert(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
void insert(entt::stl::input_iterator auto first, entt::stl::input_iterator auto 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));
|
||||
}
|
||||
@@ -598,7 +599,7 @@ public:
|
||||
* @param value An instance of the element to assign.
|
||||
*/
|
||||
template<typename Type>
|
||||
void insert(std::input_iterator auto first, std::input_iterator auto last, const Type &value) {
|
||||
void insert(entt::stl::input_iterator auto first, entt::stl::input_iterator auto 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);
|
||||
}
|
||||
@@ -708,7 +709,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, std::input_iterator It>
|
||||
template<typename Type, typename... Other, entt::stl::input_iterator It>
|
||||
size_type remove(It first, It last) {
|
||||
size_type count{};
|
||||
|
||||
@@ -761,7 +762,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, std::input_iterator It>
|
||||
template<typename Type, typename... Other, entt::stl::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>())...};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../config/config.h"
|
||||
#include "../container/dense_map.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
#include "view.hpp"
|
||||
@@ -137,7 +138,7 @@ public:
|
||||
* @return An object of this type to continue creating the snapshot.
|
||||
*/
|
||||
template<typename Type, typename Archive>
|
||||
const basic_snapshot &get(Archive &archive, std::input_iterator auto first, std::input_iterator auto last, const id_type id = type_hash<Type>::value()) const {
|
||||
const basic_snapshot &get(Archive &archive, entt::stl::input_iterator auto first, entt::stl::input_iterator auto last, const id_type id = type_hash<Type>::value()) const {
|
||||
static_assert(!std::is_same_v<Type, entity_type>, "Entity types not supported");
|
||||
|
||||
if(const auto *storage = reg->template storage<Type>(id); storage && !storage->empty()) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "../core/any.hpp"
|
||||
#include "../core/bit.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
|
||||
@@ -791,7 +792,7 @@ public:
|
||||
* @return Iterator pointing to the first element inserted in case of
|
||||
* success, the `end()` iterator otherwise.
|
||||
*/
|
||||
iterator push(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
iterator push(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) {
|
||||
auto curr = end();
|
||||
|
||||
for(; first != last; ++first) {
|
||||
@@ -842,7 +843,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<std::input_iterator It>
|
||||
template<entt::stl::input_iterator It>
|
||||
void erase(It first, It last) {
|
||||
if constexpr(std::is_same_v<It, basic_iterator>) {
|
||||
pop(first, last);
|
||||
@@ -869,7 +870,7 @@ public:
|
||||
* @param last An iterator past the last element of the range of entities.
|
||||
* @return The number of entities actually removed.
|
||||
*/
|
||||
template<std::input_iterator It>
|
||||
template<entt::stl::input_iterator It>
|
||||
size_type remove(It first, It last) {
|
||||
size_type count{};
|
||||
|
||||
@@ -1028,7 +1029,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<std::input_iterator It>
|
||||
template<entt::stl::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();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../core/iterator.hpp"
|
||||
#include "../core/memory.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "../stl/memory.hpp"
|
||||
#include "component.hpp"
|
||||
#include "entity.hpp"
|
||||
@@ -693,7 +694,7 @@ public:
|
||||
* @param value An instance of the object to construct.
|
||||
* @return Iterator pointing to the first element inserted, if any.
|
||||
*/
|
||||
iterator insert(std::input_iterator auto first, std::input_iterator auto last, const value_type &value = {}) {
|
||||
iterator insert(entt::stl::input_iterator auto first, entt::stl::input_iterator auto 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<std::input_iterator It>
|
||||
template<entt::stl::input_iterator It>
|
||||
void insert(It first, It last) {
|
||||
for(; first != last; ++first) {
|
||||
base_type::try_emplace(*first, true);
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace entt {}
|
||||
#include "signal/dispatcher.hpp"
|
||||
#include "signal/emitter.hpp"
|
||||
#include "signal/sigh.hpp"
|
||||
#include "stl/concepts.hpp"
|
||||
#include "stl/functional.hpp"
|
||||
#include "stl/memory.hpp"
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "../core/compressed_pair.hpp"
|
||||
#include "../core/fwd.hpp"
|
||||
#include "../core/iterator.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "../stl/functional.hpp"
|
||||
#include "adjacency_matrix.hpp"
|
||||
#include "fwd.hpp"
|
||||
@@ -288,7 +289,7 @@ public:
|
||||
* @param last An iterator past the last element of the range of elements.
|
||||
* @return This flow builder.
|
||||
*/
|
||||
basic_flow &ro(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
basic_flow &ro(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) {
|
||||
for(; first != last; ++first) {
|
||||
emplace(*first, false);
|
||||
}
|
||||
@@ -312,7 +313,7 @@ public:
|
||||
* @param last An iterator past the last element of the range of elements.
|
||||
* @return This flow builder.
|
||||
*/
|
||||
basic_flow &rw(std::input_iterator auto first, std::input_iterator auto last) {
|
||||
basic_flow &rw(entt::stl::input_iterator auto first, entt::stl::input_iterator auto last) {
|
||||
for(; first != last; ++first) {
|
||||
emplace(*first, true);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "../core/utility.hpp"
|
||||
#include "../locator/locator.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "adl_pointer.hpp"
|
||||
#include "context.hpp"
|
||||
#include "fwd.hpp"
|
||||
@@ -1617,7 +1618,7 @@ public:
|
||||
|
||||
meta_iterator() = default;
|
||||
|
||||
template<std::bidirectional_iterator It>
|
||||
template<entt::stl::bidirectional_iterator It>
|
||||
meta_iterator(const meta_ctx &area, It iter) noexcept
|
||||
: ctx{&area},
|
||||
vtable{&basic_vtable<It>},
|
||||
@@ -1698,7 +1699,7 @@ public:
|
||||
|
||||
meta_iterator() = default;
|
||||
|
||||
template<bool KeyOnly, std::forward_iterator It>
|
||||
template<bool KeyOnly, entt::stl::forward_iterator It>
|
||||
meta_iterator(const meta_ctx &area, std::bool_constant<KeyOnly>, It iter) noexcept
|
||||
: ctx{&area},
|
||||
vtable{&basic_vtable<KeyOnly, It>},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <utility>
|
||||
#include "../core/fwd.hpp"
|
||||
#include "../core/iterator.hpp"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "context.hpp"
|
||||
|
||||
namespace entt {
|
||||
@@ -111,7 +112,7 @@ private:
|
||||
* @tparam Type Type of meta objects returned.
|
||||
* @tparam It Type of forward iterator.
|
||||
*/
|
||||
template<typename Type, std::forward_iterator It>
|
||||
template<typename Type, entt::stl::forward_iterator It>
|
||||
using meta_range = iterable_adaptor<internal::meta_range_iterator<Type, It>>;
|
||||
|
||||
} // namespace entt
|
||||
|
||||
84
src/entt/stl/concepts.hpp
Normal file
84
src/entt/stl/concepts.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef ENTT_STL_CONCEPTS_HPP
|
||||
#define ENTT_STL_CONCEPTS_HPP
|
||||
|
||||
#include "../config/config.h"
|
||||
|
||||
/*! @cond ENTT_INTERNAL */
|
||||
namespace entt::stl {
|
||||
|
||||
#ifndef ENTT_FORCE_STL
|
||||
# if __has_include(<version>)
|
||||
# include <version>
|
||||
#
|
||||
# if defined(__cpp_lib_ranges)
|
||||
# define ENTT_HAS_ITERATOR_CONCEPTS
|
||||
# include <iterator>
|
||||
using std::bidirectional_iterator;
|
||||
using std::forward_iterator;
|
||||
using std::input_iterator;
|
||||
using std::input_or_output_iterator;
|
||||
using std::output_iterator;
|
||||
using std::random_access_iterator;
|
||||
using std::sentinel_for;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ENTT_HAS_ITERATOR_CONCEPTS
|
||||
# include <concepts>
|
||||
# include <iterator>
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename It>
|
||||
requires requires { typename std::iterator_traits<It>::iterator_category; }
|
||||
struct iterator_tag {
|
||||
using type = typename std::iterator_traits<It>::iterator_category;
|
||||
};
|
||||
|
||||
template<typename It>
|
||||
requires requires { typename It::iterator_concept; }
|
||||
struct iterator_tag<It> {
|
||||
using type = typename It::iterator_concept;
|
||||
};
|
||||
|
||||
template<typename It>
|
||||
using iterator_tag_t = typename iterator_tag<It>::type;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Bare minimum definitions to support broken platforms like PS4.
|
||||
// EnTT does not provide full featured definitions for iterator concepts.
|
||||
|
||||
template<typename It>
|
||||
concept input_or_output_iterator = requires(It it) {
|
||||
*it;
|
||||
{ ++it } -> std::same_as<It &>;
|
||||
it++;
|
||||
};
|
||||
|
||||
template<typename It>
|
||||
concept input_iterator = std::derived_from<internal::iterator_tag_t<It>, std::input_iterator_tag>;
|
||||
|
||||
template<typename It, typename Type>
|
||||
concept output_iterator = std::derived_from<internal::iterator_tag_t<It>, std::output_iterator_tag>;
|
||||
|
||||
template<typename It>
|
||||
concept forward_iterator = std::derived_from<internal::iterator_tag_t<It>, std::forward_iterator_tag>;
|
||||
|
||||
template<typename It>
|
||||
concept bidirectional_iterator = std::derived_from<internal::iterator_tag_t<It>, std::bidirectional_iterator_tag>;
|
||||
|
||||
template<typename It>
|
||||
concept random_access_iterator = std::derived_from<internal::iterator_tag_t<It>, std::random_access_iterator_tag>;
|
||||
|
||||
template<class Sentinel, typename It>
|
||||
concept sentinel_for = input_or_output_iterator<It> && requires(Sentinel sentinel, It it) {
|
||||
{ it == sentinel } -> std::same_as<bool>;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace entt::stl
|
||||
/*! @endcond */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user