diff --git a/TODO b/TODO index dc70d7a25..ce0f439ff 100644 --- a/TODO +++ b/TODO @@ -12,6 +12,7 @@ DOC: * update entity doc when the storage based model is in place WIP: +* meta: add deque support as sequence container * sparse set/storage support for move-only types, internal rework required * get rid of observers, storage based views made them pointless - document alternatives * add storage getter for filters to views and groups diff --git a/src/entt/meta/container.hpp b/src/entt/meta/container.hpp index 8b2cf5bcb..dc63d8c8a 100644 --- a/src/entt/meta/container.hpp +++ b/src/entt/meta/container.hpp @@ -2,6 +2,8 @@ #define ENTT_META_CONTAINER_HPP #include +#include +#include #include #include #include @@ -70,12 +72,12 @@ struct basic_meta_sequence_container_traits { // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector if(value.allow_cast() || value.allow_cast()) { const auto *element = value.try_cast>(); - const auto curr = cont->insert(cont->begin() + offset, element ? *element : value.cast()); - return iterator{*cont, curr - cont->begin()}; + const auto curr = cont->insert(std::next(cont->begin(), offset), element ? *element : value.cast()); + return iterator{*cont, static_cast(offset)}; } } else { - const auto curr = cont->erase(cont->begin() + offset); - return iterator{*cont, curr - cont->begin()}; + const auto curr = cont->erase(std::next(cont->begin(), offset)); + return iterator{*cont, static_cast(offset)}; } } } @@ -167,6 +169,15 @@ template struct meta_sequence_container_traits> : internal::basic_meta_sequence_container_traits> {}; +/** + * @brief Meta sequence container traits for `std::list`s of any type. + * @tparam Type The type of elements. + * @tparam Args Other arguments. + */ +template +struct meta_sequence_container_traits> + : internal::basic_meta_sequence_container_traits> {}; + /** * @brief Meta associative container traits for `std::map`s of any type. * @tparam Key The key type of elements. diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 8b05e1028..ed2bb3825 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -1471,7 +1471,7 @@ class meta_sequence_container::meta_iterator final { template static meta_any deref_fn(const any &value, const std::ptrdiff_t pos) { - return meta_any{std::in_place_type::reference>, any_cast(value)[pos]}; + return meta_any{std::in_place_type::reference>, *std::next(any_cast(value), pos)}; } public: diff --git a/test/entt/meta/meta_container.cpp b/test/entt/meta/meta_container.cpp index 17861101f..0f2293d25 100644 --- a/test/entt/meta/meta_container.cpp +++ b/test/entt/meta/meta_container.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -204,6 +205,53 @@ TEST_F(MetaContainer, StdArray) { ASSERT_EQ(view.size(), 3u); } +TEST_F(MetaContainer, StdList) { + std::list list{}; + auto any = entt::forward_as_meta(list); + auto view = any.as_sequence_container(); + + ASSERT_TRUE(view); + ASSERT_EQ(view.value_type(), entt::resolve()); + + ASSERT_EQ(view.size(), 0u); + ASSERT_EQ(view.begin(), view.end()); + ASSERT_TRUE(view.resize(3u)); + ASSERT_EQ(view.size(), 3u); + ASSERT_NE(view.begin(), view.end()); + + view[0].cast() = 2; + view[1].cast() = 3; + view[2].cast() = 4; + + ASSERT_EQ(view[1u].cast(), 3); + + auto it = view.begin(); + auto ret = view.insert(it, 0); + + ASSERT_TRUE(ret); + ASSERT_FALSE(view.insert(ret, invalid_type{})); + ASSERT_TRUE(view.insert(++ret, 1.)); + + ASSERT_EQ(view.size(), 5u); + ASSERT_EQ(view.begin()->cast(), 0); + ASSERT_EQ((++view.begin())->cast(), 1); + + ret = view.insert(view.end(), 42); + + ASSERT_TRUE(ret); + ASSERT_EQ(*ret, 42); + + it = view.begin(); + ret = view.erase(it); + + ASSERT_TRUE(ret); + ASSERT_EQ(view.size(), 5u); + ASSERT_EQ(ret->cast(), 1); + + ASSERT_TRUE(view.clear()); + ASSERT_EQ(view.size(), 0u); +} + TEST_F(MetaContainer, StdMap) { std::map map{{2, 'c'}, {3, 'd'}, {4, 'e'}}; auto any = entt::forward_as_meta(map);