meta: minimal (and still inefficient) support for lists as sequence containers
This commit is contained in:
1
TODO
1
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
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define ENTT_META_CONTAINER_HPP
|
||||
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
@@ -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<bool>
|
||||
if(value.allow_cast<typename Type::const_reference>() || value.allow_cast<typename Type::value_type>()) {
|
||||
const auto *element = value.try_cast<std::remove_reference_t<typename Type::const_reference>>();
|
||||
const auto curr = cont->insert(cont->begin() + offset, element ? *element : value.cast<typename Type::value_type>());
|
||||
return iterator{*cont, curr - cont->begin()};
|
||||
const auto curr = cont->insert(std::next(cont->begin(), offset), element ? *element : value.cast<typename Type::value_type>());
|
||||
return iterator{*cont, static_cast<std::ptrdiff_t>(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<std::ptrdiff_t>(offset)};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,6 +169,15 @@ template<typename Type, auto N>
|
||||
struct meta_sequence_container_traits<std::array<Type, N>>
|
||||
: internal::basic_meta_sequence_container_traits<std::array<Type, N>> {};
|
||||
|
||||
/**
|
||||
* @brief Meta sequence container traits for `std::list`s of any type.
|
||||
* @tparam Type The type of elements.
|
||||
* @tparam Args Other arguments.
|
||||
*/
|
||||
template<typename Type, typename... Args>
|
||||
struct meta_sequence_container_traits<std::list<Type, Args...>>
|
||||
: internal::basic_meta_sequence_container_traits<std::list<Type, Args...>> {};
|
||||
|
||||
/**
|
||||
* @brief Meta associative container traits for `std::map`s of any type.
|
||||
* @tparam Key The key type of elements.
|
||||
|
||||
@@ -1471,7 +1471,7 @@ class meta_sequence_container::meta_iterator final {
|
||||
|
||||
template<typename It>
|
||||
static meta_any deref_fn(const any &value, const std::ptrdiff_t pos) {
|
||||
return meta_any{std::in_place_type<typename std::iterator_traits<It>::reference>, any_cast<const It &>(value)[pos]};
|
||||
return meta_any{std::in_place_type<typename std::iterator_traits<It>::reference>, *std::next(any_cast<const It &>(value), pos)};
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
@@ -204,6 +205,53 @@ TEST_F(MetaContainer, StdArray) {
|
||||
ASSERT_EQ(view.size(), 3u);
|
||||
}
|
||||
|
||||
TEST_F(MetaContainer, StdList) {
|
||||
std::list<int> list{};
|
||||
auto any = entt::forward_as_meta(list);
|
||||
auto view = any.as_sequence_container();
|
||||
|
||||
ASSERT_TRUE(view);
|
||||
ASSERT_EQ(view.value_type(), entt::resolve<int>());
|
||||
|
||||
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<int &>() = 2;
|
||||
view[1].cast<int &>() = 3;
|
||||
view[2].cast<int &>() = 4;
|
||||
|
||||
ASSERT_EQ(view[1u].cast<int>(), 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<int>(), 0);
|
||||
ASSERT_EQ((++view.begin())->cast<int>(), 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<int>(), 1);
|
||||
|
||||
ASSERT_TRUE(view.clear());
|
||||
ASSERT_EQ(view.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(MetaContainer, StdMap) {
|
||||
std::map<int, char> map{{2, 'c'}, {3, 'd'}, {4, 'e'}};
|
||||
auto any = entt::forward_as_meta(map);
|
||||
|
||||
Reference in New Issue
Block a user