33#ifndef ENTT_META_CONTAINER_HPP
44#define ENTT_META_CONTAINER_HPP
55
6- #include < array>
76#include < concepts>
87#include < cstddef>
9- #include < deque>
108#include < iterator>
11- #include < list>
12- #include < map>
13- #include < set>
149#include < type_traits>
15- #include < unordered_map>
16- #include < unordered_set>
17- #include < vector>
18- #include " ../container/dense_map.hpp"
19- #include " ../container/dense_set.hpp"
10+ #include < utility>
2011#include " ../core/concepts.hpp"
2112#include " ../core/type_traits.hpp"
2213#include " context.hpp"
@@ -39,15 +30,27 @@ struct sequence_container_extent<Type>: integral_constant<std::tuple_size_v<Type
3930template <typename Type>
4031inline constexpr std::size_t sequence_container_extent_v = sequence_container_extent<Type>::value;
4132
42- template <typename >
43- struct key_only_associative_container : std::true_type {};
44-
4533template <typename Type>
46- requires requires { typename Type::mapped_type; }
47- struct key_only_associative_container <Type>: std::false_type {};
34+ concept meta_sequence_container_like = requires (Type elem) {
35+ typename Type::value_type;
36+ typename Type::iterator;
37+ requires std::forward_iterator<typename Type::iterator>;
38+ { elem.begin () } -> std::same_as<typename Type::iterator>;
39+ { elem.end () } -> std::same_as<typename Type::iterator>;
40+ requires !requires { typename Type::key_type; };
41+ requires !requires { elem.substr (); };
42+ };
4843
4944template <typename Type>
50- inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
45+ concept meta_associative_container_like = requires (Type value) {
46+ typename Type::key_type;
47+ typename Type::value_type;
48+ typename Type::iterator;
49+ requires std::forward_iterator<typename Type::iterator>;
50+ { value.begin () } -> std::same_as<typename Type::iterator>;
51+ { value.end () } -> std::same_as<typename Type::iterator>;
52+ value.find (std::declval<typename Type::key_type>());
53+ };
5154
5255} // namespace internal
5356/* ! @endcond */
@@ -81,7 +84,7 @@ struct basic_meta_sequence_container_traits {
8184 * @return True in case of success, false otherwise.
8285 */
8386 [[nodiscard]] static bool clear ([[maybe_unused]] void *container) {
84- if constexpr (extent == meta_dynamic_extent ) {
87+ if constexpr (requires (Type elem) { elem. clear (); } ) {
8588 static_cast <Type *>(container)->clear ();
8689 return true ;
8790 } else {
@@ -96,7 +99,7 @@ struct basic_meta_sequence_container_traits {
9699 * @return True in case of success, false otherwise.
97100 */
98101 [[nodiscard]] static bool reserve ([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
99- if constexpr (requires (Type elem) { { elem.reserve (sz) } ; }) {
102+ if constexpr (requires (Type elem) { elem.reserve (sz); }) {
100103 static_cast <Type *>(container)->reserve (sz);
101104 return true ;
102105 } else {
@@ -111,7 +114,7 @@ struct basic_meta_sequence_container_traits {
111114 * @return True in case of success, false otherwise.
112115 */
113116 [[nodiscard]] static bool resize ([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
114- if constexpr ((extent == meta_dynamic_extent) && std::is_default_constructible_v<typename Type::value_type>) {
117+ if constexpr (std::is_default_constructible_v<typename Type::value_type> && requires (Type elem) { elem. resize (sz); } ) {
115118 static_cast <Type *>(container)->resize (sz);
116119 return true ;
117120 } else {
@@ -147,7 +150,7 @@ struct basic_meta_sequence_container_traits {
147150 * @return A possibly invalid iterator to the inserted element.
148151 */
149152 [[nodiscard]] static iterator insert ([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] const iterator &it) {
150- if constexpr (extent == meta_dynamic_extent ) {
153+ if constexpr (requires (Type elem, typename Type::const_iterator it, Type::value_type instance) { elem. insert (it, instance); } ) {
151154 auto *const non_const = any_cast<typename Type::iterator>(&it.base ());
152155 return {area, static_cast <Type *>(container)->insert (
153156 non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base ()),
@@ -165,7 +168,7 @@ struct basic_meta_sequence_container_traits {
165168 * @return A possibly invalid iterator following the last removed element.
166169 */
167170 [[nodiscard]] static iterator erase ([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) {
168- if constexpr (extent == meta_dynamic_extent ) {
171+ if constexpr (requires (Type elem, typename Type::const_iterator it) { elem. erase (it); } ) {
169172 auto *const non_const = any_cast<typename Type::iterator>(&it.base ());
170173 return {area, static_cast <Type *>(container)->erase (non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base ()))};
171174 } else {
@@ -186,7 +189,7 @@ struct basic_meta_associative_container_traits {
186189 using iterator = meta_associative_container::iterator;
187190
188191 /* ! @brief True in case of key-only containers, false otherwise. */
189- static constexpr bool key_only = internal::key_only_associative_container_v<Type> ;
192+ static constexpr bool key_only = ! requires { typename Type::mapped_type; } ;
190193
191194 /* *
192195 * @brief Returns the number of elements in a container.
@@ -214,7 +217,7 @@ struct basic_meta_associative_container_traits {
214217 * @return True in case of success, false otherwise.
215218 */
216219 [[nodiscard]] static bool reserve ([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
217- if constexpr (requires (Type elem) { { elem.reserve (sz) } ; }) {
220+ if constexpr (requires (Type elem) { elem.reserve (sz); }) {
218221 static_cast <Type *>(container)->reserve (sz);
219222 return true ;
220223 } else {
@@ -277,87 +280,18 @@ struct basic_meta_associative_container_traits {
277280};
278281
279282/* *
280- * @brief Meta sequence container traits for `std::vector`s of any type.
281- * @tparam Args Template arguments for the container.
282- */
283- template <typename ... Args>
284- struct meta_sequence_container_traits <std::vector<Args...>>
285- : basic_meta_sequence_container_traits<std::vector<Args...>> {};
286-
287- /* *
288- * @brief Meta sequence container traits for `std::array`s of any type.
289- * @tparam Type Template arguments for the container.
290- * @tparam N Template arguments for the container.
291- */
292- template <typename Type, auto N>
293- struct meta_sequence_container_traits <std::array<Type, N>>
294- : basic_meta_sequence_container_traits<std::array<Type, N>> {};
295-
296- /* *
297- * @brief Meta sequence container traits for `std::list`s of any type.
298- * @tparam Args Template arguments for the container.
299- */
300- template <typename ... Args>
301- struct meta_sequence_container_traits <std::list<Args...>>
302- : basic_meta_sequence_container_traits<std::list<Args...>> {};
303-
304- /* *
305- * @brief Meta sequence container traits for `std::deque`s of any type.
306- * @tparam Args Template arguments for the container.
307- */
308- template <typename ... Args>
309- struct meta_sequence_container_traits <std::deque<Args...>>
310- : basic_meta_sequence_container_traits<std::deque<Args...>> {};
311-
312- /* *
313- * @brief Meta associative container traits for `std::map`s of any type.
314- * @tparam Args Template arguments for the container.
315- */
316- template <typename ... Args>
317- struct meta_associative_container_traits <std::map<Args...>>
318- : basic_meta_associative_container_traits<std::map<Args...>> {};
319-
320- /* *
321- * @brief Meta associative container traits for `std::unordered_map`s of any
322- * type.
323- * @tparam Args Template arguments for the container.
324- */
325- template <typename ... Args>
326- struct meta_associative_container_traits <std::unordered_map<Args...>>
327- : basic_meta_associative_container_traits<std::unordered_map<Args...>> {};
328-
329- /* *
330- * @brief Meta associative container traits for `std::set`s of any type.
331- * @tparam Args Template arguments for the container.
332- */
333- template <typename ... Args>
334- struct meta_associative_container_traits <std::set<Args...>>
335- : basic_meta_associative_container_traits<std::set<Args...>> {};
336-
337- /* *
338- * @brief Meta associative container traits for `std::unordered_set`s of any
339- * type.
340- * @tparam Args Template arguments for the container.
341- */
342- template <typename ... Args>
343- struct meta_associative_container_traits <std::unordered_set<Args...>>
344- : basic_meta_associative_container_traits<std::unordered_set<Args...>> {};
345-
346- /* *
347- * @brief Meta associative container traits for `dense_map`s of any type.
348- * @tparam Args Template arguments for the container.
283+ * @brief Traits meta sequence container like types.
284+ * @tparam Type Container type to inspect.
349285 */
350- template <typename ... Args>
351- struct meta_associative_container_traits <dense_map<Args...>>
352- : basic_meta_associative_container_traits<dense_map<Args...>> {};
286+ template <internal::meta_sequence_container_like Type>
287+ struct meta_sequence_container_traits <Type>: basic_meta_sequence_container_traits<Type> {};
353288
354289/* *
355- * @brief Meta associative container traits for `dense_set`s of any type .
356- * @tparam Args Template arguments for the container .
290+ * @brief Traits for meta associative container like types .
291+ * @tparam Type Container type to inspect .
357292 */
358- template <typename ... Args>
359- struct meta_associative_container_traits <dense_set<Args...>>
360- : basic_meta_associative_container_traits<dense_set<Args...>> {};
293+ template <internal::meta_associative_container_like Type>
294+ struct meta_associative_container_traits <Type>: basic_meta_associative_container_traits<Type> {};
361295
362296} // namespace entt
363297
0 commit comments