#ifndef ENTT_STL_ITERATOR_HPP #define ENTT_STL_ITERATOR_HPP /*! @cond ENTT_INTERNAL */ #if __has_include() # include #else # include # include # include "../config/config.h" namespace entt::stl { using std::advance; using std::bidirectional_iterator_tag; using std::distance; using std::forward_iterator_tag; using std::input_iterator_tag; using std::iterator_traits; using std::make_reverse_iterator; using std::random_access_iterator_tag; using std::reverse_iterator; # ifndef ENTT_FORCE_STL # if defined(__cpp_lib_ranges) # define ENTT_HAS_ITERATOR_CONCEPTS 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 # ifndef ENTT_HAS_ITERATOR_CONCEPTS # include # include namespace internal { template concept has_iterator_category = requires { typename std::iterator_traits::iterator_category; }; template concept has_iterator_concept = has_iterator_category && requires { typename It::iterator_concept; }; template struct iterator_tag { using type = typename std::iterator_traits::iterator_category; }; template struct iterator_tag { using type = typename It::iterator_concept; }; template concept has_iterator_tag = std::derived_from::type, Tag>; } // namespace internal // Bare minimum definitions to support broken platforms like PS4. // EnTT does not provide full featured definitions for iterator concepts. template concept input_or_output_iterator = requires(It it) { *it; { ++it } -> std::same_as; it++; }; template concept input_iterator = input_or_output_iterator && internal::has_iterator_tag; template concept output_iterator = input_or_output_iterator && requires(It it, Type &&value) { *it++ = std::forward(value); }; template concept forward_iterator = input_iterator && internal::has_iterator_tag; template concept bidirectional_iterator = forward_iterator && internal::has_iterator_tag; template concept random_access_iterator = bidirectional_iterator && internal::has_iterator_tag; template concept sentinel_for = input_or_output_iterator && requires(Sentinel sentinel, It it) { { it == sentinel } -> std::same_as; }; # endif } // namespace entt::stl #endif /*! @endcond */ #undef ENTT_HAS_ITERATOR_CONCEPTS #endif