meta: added meta sequence container resize + [[nodiscard]] here and there

This commit is contained in:
Michele Caini
2020-06-21 23:08:14 +02:00
parent ab16680cc8
commit 0369ac450e
3 changed files with 105 additions and 64 deletions

View File

@@ -39,6 +39,16 @@ struct meta_sequence_container_traits_t<std::vector<Type, Args...>> {
return vec.size();
}
/**
* @brief Resizes a given container to contain a certain number of elements.
* @param vec The container to resize.
* @param sz The new size of the container.
* @return True in case of success, false otherwise.
*/
[[nodiscard]] static bool resize(std::vector<Type, Args...> &vec, size_type sz) ENTT_NOEXCEPT {
return (vec.resize(sz), true);
}
/**
* @brief Clears the content of a given container.
* @param vec The container of which to clear the content.
@@ -130,7 +140,15 @@ struct meta_sequence_container_traits_t<std::array<Type, N>> {
* @brief Does nothing.
* @return False to indicate failure in all cases.
*/
[[nodiscard]] static bool clear(std::array<Type, N> &) {
[[nodiscard]] static bool resize(const std::array<Type, N> &, size_type) ENTT_NOEXCEPT {
return false;
}
/**
* @brief Does nothing.
* @return False to indicate failure in all cases.
*/
[[nodiscard]] static bool clear(const std::array<Type, N> &) {
return false;
}
@@ -157,7 +175,7 @@ struct meta_sequence_container_traits_t<std::array<Type, N>> {
* @return A pair consisting of an invalid iterator and a false value to
* indicate failure in all cases.
*/
[[nodiscard]] static std::pair<iterator, bool> insert(std::array<Type, N> &, iterator, const Type &) {
[[nodiscard]] static std::pair<iterator, bool> insert(const std::array<Type, N> &, iterator, const Type &) {
return { {}, false };
}
@@ -166,7 +184,7 @@ struct meta_sequence_container_traits_t<std::array<Type, N>> {
* @return A pair consisting of an invalid iterator and a false value to
* indicate failure in all cases.
*/
[[nodiscard]] static std::pair<iterator, bool> erase(std::array<Type, N> &, iterator) {
[[nodiscard]] static std::pair<iterator, bool> erase(const std::array<Type, N> &, iterator) {
return { {}, false };
}

View File

@@ -41,20 +41,22 @@ public:
inline meta_sequence_container();
inline meta_type value_type() const ENTT_NOEXCEPT;
inline size_type size() const ENTT_NOEXCEPT;
[[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
[[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
inline bool resize(size_type) const ENTT_NOEXCEPT;
inline bool clear();
inline iterator begin();
inline iterator end();
[[nodiscard]] inline iterator begin();
[[nodiscard]] inline iterator end();
inline std::pair<iterator, bool> insert(iterator, meta_any);
inline std::pair<iterator, bool> erase(iterator);
inline meta_any operator[](size_type);
[[nodiscard]] inline meta_any operator[](size_type);
inline explicit operator bool() const ENTT_NOEXCEPT;
[[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
private:
meta_type(* value_type_fn)();
size_type(* size_fn)(const void *);
bool(* resize_fn)(void *, size_type);
bool(* clear_fn)(void *);
iterator(* begin_fn)(void *);
iterator(* end_fn)(void *);
@@ -89,19 +91,19 @@ public:
inline meta_associative_container();
inline bool key_only() const ENTT_NOEXCEPT;
inline meta_type key_type() const ENTT_NOEXCEPT;
inline meta_type mapped_type() const ENTT_NOEXCEPT;
inline meta_type value_type() const ENTT_NOEXCEPT;
inline size_type size() const ENTT_NOEXCEPT;
[[nodiscard]] inline bool key_only() const ENTT_NOEXCEPT;
[[nodiscard]] inline meta_type key_type() const ENTT_NOEXCEPT;
[[nodiscard]] inline meta_type mapped_type() const ENTT_NOEXCEPT;
[[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT;
[[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
inline bool clear();
inline iterator begin();
inline iterator end();
[[nodiscard]] inline iterator begin();
[[nodiscard]] inline iterator end();
inline bool insert(meta_any, meta_any);
inline bool erase(meta_any);
inline iterator find(meta_any);
[[nodiscard]] inline iterator find(meta_any);
inline explicit operator bool() const ENTT_NOEXCEPT;
[[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
private:
bool key_only_container;
@@ -129,7 +131,7 @@ class meta_any {
using dereference_operator_type = meta_any(meta_any &);
template<typename Type>
static meta_any dereference_operator(meta_any &any) {
[[nodiscard]] static meta_any dereference_operator(meta_any &any) {
meta_any other{};
if constexpr(is_dereferenceable_v<Type>) {
@@ -1499,7 +1501,7 @@ class meta_iterator {
}
template<typename Type>
static meta_any deref(meta_any any) {
[[nodiscard]] static meta_any deref(meta_any any) {
if constexpr(std::is_const_v<std::remove_reference_t<decltype(*std::declval<typename Type::iterator>())>>) {
return *any.cast<typename Type::iterator>();
} else {
@@ -1602,27 +1604,31 @@ private:
template<typename Type>
struct meta_sequence_container::meta_sequence_container_proxy {
static meta_type value_type() {
[[nodiscard]] static meta_type value_type() {
return internal::meta_info<typename meta_sequence_container_traits_t<Type>::value_type>::resolve();
}
static meta_sequence_container::size_type size(const void *container) {
[[nodiscard]] static size_type size(const void *container) {
return meta_sequence_container_traits_t<Type>::size(*static_cast<const Type *>(container));
}
static bool clear(void *container) {
[[nodiscard]] static bool resize(void *container, size_type sz) {
return meta_sequence_container_traits_t<Type>::resize(*static_cast<Type *>(container), sz);
}
[[nodiscard]] static bool clear(void *container) {
return meta_sequence_container_traits_t<Type>::clear(*static_cast<Type *>(container));
}
static iterator begin(void *container) {
[[nodiscard]] static iterator begin(void *container) {
return iterator{std::in_place_type<Type>, meta_sequence_container_traits_t<Type>::begin(*static_cast<Type *>(container))};
}
static iterator end(void *container) {
[[nodiscard]] static iterator end(void *container) {
return iterator{std::in_place_type<Type>, meta_sequence_container_traits_t<Type>::end(*static_cast<Type *>(container))};
}
static std::pair<iterator, bool> insert(void *container, iterator it, meta_any any) {
[[nodiscard]] static std::pair<iterator, bool> insert(void *container, iterator it, meta_any any) {
std::pair<typename meta_sequence_container_traits_t<Type>::iterator, bool> ret{{}, false};
if(const auto *value = any.try_cast<typename meta_sequence_container_traits_t<Type>::value_type>(); value) {
@@ -1632,12 +1638,12 @@ struct meta_sequence_container::meta_sequence_container_proxy {
return {iterator{std::in_place_type<Type>, std::move(ret.first)}, ret.second};
}
static std::pair<iterator, bool> erase(void *container, iterator it) {
[[nodiscard]] static std::pair<iterator, bool> erase(void *container, iterator it) {
auto ret = meta_sequence_container_traits_t<Type>::erase(*static_cast<Type *>(container), it.handle().cast<typename meta_sequence_container_traits_t<Type>::iterator>());
return {iterator{std::in_place_type<Type>, std::move(ret.first)}, ret.second};
}
static meta_any get(void *container, meta_sequence_container::size_type pos) {
[[nodiscard]] static meta_any get(void *container, size_type pos) {
return std::ref(meta_sequence_container_traits_t<Type>::get(*static_cast<Type *>(container), pos));
}
};
@@ -1652,6 +1658,7 @@ template<typename Type>
meta_sequence_container::meta_sequence_container(Type &container)
: value_type_fn{&meta_sequence_container_proxy<Type>::value_type},
size_fn{&meta_sequence_container_proxy<Type>::size},
resize_fn{&meta_sequence_container_proxy<Type>::resize},
clear_fn{&meta_sequence_container_proxy<Type>::clear},
begin_fn{&meta_sequence_container_proxy<Type>::begin},
end_fn{&meta_sequence_container_proxy<Type>::end},
@@ -1666,6 +1673,7 @@ meta_sequence_container::meta_sequence_container(Type &container)
inline meta_sequence_container::meta_sequence_container()
: value_type_fn{nullptr},
size_fn{nullptr},
resize_fn{nullptr},
clear_fn{nullptr},
begin_fn{nullptr},
end_fn{nullptr},
@@ -1680,7 +1688,7 @@ inline meta_sequence_container::meta_sequence_container()
* @brief Returns the value meta type of the wrapped container type.
* @return The value meta type of the wrapped container type.
*/
inline meta_type meta_sequence_container::value_type() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_type meta_sequence_container::value_type() const ENTT_NOEXCEPT {
return value_type_fn();
}
@@ -1689,11 +1697,21 @@ inline meta_type meta_sequence_container::value_type() const ENTT_NOEXCEPT {
* @brief Returns the size of the wrapped container.
* @return The size of the wrapped container.
*/
inline meta_sequence_container::size_type meta_sequence_container::size() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const ENTT_NOEXCEPT {
return size_fn(instance);
}
/**
* @brief Resizes the wrapped container to contain a given number of elements.
* @param sz The new size of the container.
* @return True in case of success, false otherwise.
*/
inline bool meta_sequence_container::resize(size_type sz) const ENTT_NOEXCEPT {
return resize_fn(instance, sz);
}
/**
* @brief Clears the content of the wrapped container.
* @return True in case of success, false otherwise.
@@ -1707,7 +1725,7 @@ inline bool meta_sequence_container::clear() {
* @brief Returns a meta iterator to the first element of the wrapped container.
* @return A meta iterator to the first element of the wrapped container.
*/
inline meta_sequence_container::iterator meta_sequence_container::begin() {
[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
return begin_fn(instance);
}
@@ -1718,7 +1736,7 @@ inline meta_sequence_container::iterator meta_sequence_container::begin() {
* @return A meta iterator that is past the last element of the wrapped
* container.
*/
inline meta_sequence_container::iterator meta_sequence_container::end() {
[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
return end_fn(instance);
}
@@ -1753,7 +1771,7 @@ inline std::pair<meta_sequence_container::iterator, bool> meta_sequence_containe
* @param pos The position of the element to return.
* @return A reference to the requested element properly wrapped.
*/
inline meta_any meta_sequence_container::operator[](size_type pos) {
[[nodiscard]] inline meta_any meta_sequence_container::operator[](size_type pos) {
return get_fn(instance, pos);
}
@@ -1762,7 +1780,7 @@ inline meta_any meta_sequence_container::operator[](size_type pos) {
* @brief Returns false if a proxy is invalid, true otherwise.
* @return False if the proxy is invalid, true otherwise.
*/
inline meta_sequence_container::operator bool() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_sequence_container::operator bool() const ENTT_NOEXCEPT {
return (instance != nullptr);
}
@@ -1771,11 +1789,11 @@ template<typename Type>
struct meta_associative_container::meta_associative_container_proxy {
static constexpr auto has_mapped_type = meta_associative_container::has_mapped_type<Type>::value;
static meta_type key_type() {
[[nodiscard]] static meta_type key_type() {
return internal::meta_info<typename meta_associative_container_traits_t<Type>::key_type>::resolve();
}
static meta_type mapped_type() {
[[nodiscard]] static meta_type mapped_type() {
if constexpr(has_mapped_type) {
return internal::meta_info<typename meta_associative_container_traits_t<Type>::mapped_type>::resolve();
} else {
@@ -1783,27 +1801,27 @@ struct meta_associative_container::meta_associative_container_proxy {
}
}
static meta_type value_type() {
[[nodiscard]] static meta_type value_type() {
return internal::meta_info<typename meta_associative_container_traits_t<Type>::value_type>::resolve();
}
static meta_associative_container::size_type size(const void *container) {
[[nodiscard]] static size_type size(const void *container) {
return meta_associative_container_traits_t<Type>::size(*static_cast<const Type *>(container));
}
static bool clear(void *container) {
[[nodiscard]] static bool clear(void *container) {
return meta_associative_container_traits_t<Type>::clear(*static_cast<Type *>(container));
}
static iterator begin(void *container) {
[[nodiscard]] static iterator begin(void *container) {
return iterator{std::in_place_type<Type>, meta_associative_container_traits_t<Type>::begin(*static_cast<Type *>(container))};
}
static iterator end(void *container) {
[[nodiscard]] static iterator end(void *container) {
return iterator{std::in_place_type<Type>, meta_associative_container_traits_t<Type>::end(*static_cast<Type *>(container))};
}
static bool insert(void *container, meta_any key, meta_any value) {
[[nodiscard]] static bool insert(void *container, meta_any key, meta_any value) {
bool ret = false;
if(const auto *k_ptr = key.try_cast<typename meta_associative_container_traits_t<Type>::key_type>(); k_ptr) {
@@ -1819,7 +1837,7 @@ struct meta_associative_container::meta_associative_container_proxy {
return ret;
}
static bool erase(void *container, meta_any key) {
[[nodiscard]] static bool erase(void *container, meta_any key) {
bool ret = false;
if(const auto *k_ptr = key.try_cast<typename meta_associative_container_traits_t<Type>::key_type>(); k_ptr) {
@@ -1829,7 +1847,7 @@ struct meta_associative_container::meta_associative_container_proxy {
return ret;
}
static iterator find(void *container, meta_any key) {
[[nodiscard]] static iterator find(void *container, meta_any key) {
iterator ret{};
if(const auto *k_ptr = key.try_cast<typename meta_associative_container_traits_t<Type>::key_type>(); k_ptr) {
@@ -1885,7 +1903,7 @@ inline meta_associative_container::meta_associative_container()
* otherwise.
* @return True if the associative container is also key-only, false otherwise.
*/
inline bool meta_associative_container::key_only() const ENTT_NOEXCEPT {
[[nodiscard]] inline bool meta_associative_container::key_only() const ENTT_NOEXCEPT {
return key_only_container;
}
@@ -1894,7 +1912,7 @@ inline bool meta_associative_container::key_only() const ENTT_NOEXCEPT {
* @brief Returns the key meta type of the wrapped container type.
* @return The key meta type of the wrapped container type.
*/
inline meta_type meta_associative_container::key_type() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_type meta_associative_container::key_type() const ENTT_NOEXCEPT {
return key_type_fn();
}
@@ -1903,19 +1921,19 @@ inline meta_type meta_associative_container::key_type() const ENTT_NOEXCEPT {
* @brief Returns the mapped meta type of the wrapped container type.
* @return The mapped meta type of the wrapped container type.
*/
inline meta_type meta_associative_container::mapped_type() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_type meta_associative_container::mapped_type() const ENTT_NOEXCEPT {
return mapped_type_fn();
}
/*! @copydoc meta_sequence_container::value_type */
inline meta_type meta_associative_container::value_type() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_type meta_associative_container::value_type() const ENTT_NOEXCEPT {
return value_type_fn();
}
/*! @copydoc meta_sequence_container::size */
inline meta_associative_container::size_type meta_associative_container::size() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const ENTT_NOEXCEPT {
return size_fn(instance);
}
@@ -1927,13 +1945,13 @@ inline bool meta_associative_container::clear() {
/*! @copydoc meta_sequence_container::begin */
inline meta_associative_container::iterator meta_associative_container::begin() {
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
return begin_fn(instance);
}
/*! @copydoc meta_sequence_container::end */
inline meta_associative_container::iterator meta_associative_container::end() {
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
return end_fn(instance);
}
@@ -1965,7 +1983,7 @@ inline bool meta_associative_container::erase(meta_any key) {
* @param key The key of the element to search.
* @return An iterator to the element with the given key, if any.
*/
inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
return find_fn(instance, key.ref());
}
@@ -1974,7 +1992,7 @@ inline meta_associative_container::iterator meta_associative_container::find(met
* @brief Returns false if a proxy is invalid, true otherwise.
* @return False if the proxy is invalid, true otherwise.
*/
inline meta_associative_container::operator bool() const ENTT_NOEXCEPT {
[[nodiscard]] inline meta_associative_container::operator bool() const ENTT_NOEXCEPT {
return (instance != nullptr);
}

View File

@@ -18,15 +18,22 @@ TEST(MetaSequenceContainer, Empty) {
}
TEST(MetaSequenceContainer, StdVector) {
std::vector<int> vec{2, 3, 4};
std::vector<int> vec{};
entt::meta_any any{std::ref(vec)};
auto view = any.as_sequence_container();
ASSERT_TRUE(view);
ASSERT_EQ(view.value_type(), entt::resolve<int>());
ASSERT_EQ(view.size(), 0u);
ASSERT_TRUE(view.resize(3u));
ASSERT_EQ(view.size(), 3u);
view[0].cast<int>() = 2;
view[1].cast<int>() = 3;
view[2].cast<int>() = 4;
auto first = view.begin();
const auto last = view.end();
@@ -61,14 +68,10 @@ TEST(MetaSequenceContainer, StdVector) {
ASSERT_TRUE(ret.second);
ASSERT_EQ(view.size(), 4u);
ASSERT_EQ((*ret.first).cast<int>(), 1);
view[0].cast<int>() = 5;
ASSERT_EQ((*view.begin()).cast<int>(), 5);
}
TEST(MetaSequenceContainer, StdArray) {
std::array<int, 3> arr{2, 3, 4};
std::array<int, 3> arr{};
entt::meta_any any{std::ref(arr)};
auto view = any.as_sequence_container();
@@ -77,6 +80,13 @@ TEST(MetaSequenceContainer, StdArray) {
ASSERT_EQ(view.value_type(), entt::resolve<int>());
ASSERT_EQ(view.size(), 3u);
ASSERT_FALSE(view.resize(5u));
ASSERT_EQ(view.size(), 3u);
view[0].cast<int>() = 2;
view[1].cast<int>() = 3;
view[2].cast<int>() = 4;
auto first = view.begin();
const auto last = view.end();
@@ -108,14 +118,9 @@ TEST(MetaSequenceContainer, StdArray) {
it = view.begin();
ret = view.erase(it);
ASSERT_FALSE(ret.second);
ASSERT_EQ(view.size(), 3u);
ASSERT_EQ((*it).cast<int>(), 2);
view[0].cast<int>() = 5;
ASSERT_EQ((*view.begin()).cast<int>(), 5);
}
TEST(MetaAssociativeContainer, StdMap) {