From c99e8599785c683f3ebab35df1ca8861df073499 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 23 Dec 2020 12:27:46 +0100 Subject: [PATCH] meta: container traits not required for const T --- src/entt/meta/container.hpp | 199 +++++++--------------------------- src/entt/meta/meta.hpp | 102 +++++++++++------ src/entt/meta/type_traits.hpp | 30 ----- 3 files changed, 106 insertions(+), 225 deletions(-) diff --git a/src/entt/meta/container.hpp b/src/entt/meta/container.hpp index 265279f40..9477c43ab 100644 --- a/src/entt/meta/container.hpp +++ b/src/entt/meta/container.hpp @@ -34,7 +34,9 @@ struct meta_container_traits: public Trait... {}; template struct basic_container { /*! @brief Iterator type of the container. */ - using iterator = std::conditional_t, typename Container::const_iterator, typename Container::iterator>; + using iterator = typename Container::iterator; + /*! @brief Iterator type of the container. */ + using const_iterator = typename Container::const_iterator; /*! @brief Unsigned integer type. */ using size_type = typename Container::size_type; /*! @brief Value type of the container. */ @@ -58,6 +60,11 @@ struct basic_container { return cont.begin(); } + /*! @copydoc begin */ + [[nodiscard]] static const_iterator cbegin(const Container &cont) { + return cont.begin(); + } + /** * @brief Returns an iterator past the last element of the given container. * @param cont The container for which to return the iterator. @@ -66,6 +73,11 @@ struct basic_container { [[nodiscard]] static iterator end(Container &cont) { return cont.end(); } + + /*! @copydoc end */ + [[nodiscard]] static const_iterator cend(const Container &cont) { + return cont.end(); + } }; @@ -85,7 +97,12 @@ struct basic_associative_container { * @param key The key of the element to search. * @return An iterator to the element with the given key, if any. */ - [[nodiscard]] static std::conditional_t, typename Container::const_iterator, typename Container::iterator> find(Container &cont, const key_type &key) { + [[nodiscard]] static typename Container::iterator find(Container &cont, const key_type &key) { + return cont.find(key); + } + + /*! @copydoc find */ + [[nodiscard]] static typename Container::const_iterator cfind(const Container &cont, const key_type &key) { return cont.find(key); } }; @@ -103,11 +120,7 @@ struct basic_dynamic_container { * @return True in case of success, false otherwise. */ [[nodiscard]] static bool clear([[maybe_unused]] Container &cont) { - if constexpr(std::is_const_v) { - return false; - } else { - return cont.clear(), true; - } + return cont.clear(), true; } }; @@ -125,12 +138,8 @@ struct basic_dynamic_associative_container { * @return A bool denoting whether the removal took place. */ [[nodiscard]] static bool erase([[maybe_unused]] Container &cont, [[maybe_unused]] const typename Container::key_type &key) { - if constexpr(std::is_const_v) { - return false; - } else { - const auto sz = cont.size(); - return cont.erase(key) != sz; - } + const auto sz = cont.size(); + return cont.erase(key) != sz; } }; @@ -148,7 +157,12 @@ struct basic_sequence_container { * @param pos The position of the element to return. * @return A reference to the requested element. */ - [[nodiscard]] static constness_as_t & get(Container &cont, typename Container::size_type pos) { + [[nodiscard]] static typename Container::value_type & get(Container &cont, typename Container::size_type pos) { + return cont[pos]; + } + + /*! @copydoc get */ + [[nodiscard]] static const typename Container::value_type & cget(const Container &cont, typename Container::size_type pos) { return cont[pos]; } }; @@ -167,11 +181,7 @@ struct dynamic_associative_key_only_container { * @return A bool denoting whether the insertion took place. */ [[nodiscard]] static bool insert([[maybe_unused]] Container &cont, [[maybe_unused]] const typename Container::key_type &key) { - if constexpr(std::is_const_v) { - return false; - } else { - return cont.insert(key).second; - } + return cont.insert(key).second; } }; @@ -190,11 +200,7 @@ struct dynamic_associative_key_value_container { * @return A bool denoting whether the insertion took place. */ [[nodiscard]] static bool insert([[maybe_unused]] Container &cont, [[maybe_unused]] const typename Container::key_type &key, [[maybe_unused]] const typename Container::mapped_type &value) { - if constexpr(std::is_const_v) { - return false; - } else { - return cont.insert(std::make_pair(key, value)).second; - } + return cont.insert(std::make_pair(key, value)).second; } }; @@ -213,11 +219,7 @@ struct dynamic_sequence_container { * @return True in case of success, false otherwise. */ [[nodiscard]] static bool resize([[maybe_unused]] Container &cont, [[maybe_unused]] typename Container::size_type sz) { - if constexpr(std::is_const_v) { - return false; - } else { - return cont.resize(sz), true; - } + return cont.resize(sz), true; } /** @@ -229,13 +231,8 @@ struct dynamic_sequence_container { * @return A pair consisting of an iterator to the inserted element (in case * of success) and a bool denoting whether the insertion took place. */ - [[nodiscard]] static std::pair, typename Container::const_iterator, typename Container::iterator>, bool> - insert([[maybe_unused]] Container &cont, [[maybe_unused]] std::conditional_t, typename Container::const_iterator, typename Container::iterator> it, [[maybe_unused]] const typename Container::value_type &value) { - if constexpr(std::is_const_v) { - return { {}, false }; - } else { - return { cont.insert(it, value), true }; - } + [[nodiscard]] static std::pair insert([[maybe_unused]] Container &cont, [[maybe_unused]] typename Container::const_iterator it, [[maybe_unused]] const typename Container::value_type &value) { + return { cont.insert(it, value), true }; } /** @@ -247,13 +244,8 @@ struct dynamic_sequence_container { * element (in case of success) and a bool denoting whether the insertion * took place. */ - [[nodiscard]] static std::pair, typename Container::const_iterator, typename Container::iterator>, bool> - erase([[maybe_unused]] Container &cont, [[maybe_unused]] std::conditional_t, typename Container::const_iterator, typename Container::iterator> it) { - if constexpr(std::is_const_v) { - return { {}, false }; - } else { - return { cont.erase(it), true }; - } + [[nodiscard]] static std::pair erase([[maybe_unused]] Container &cont, [[maybe_unused]] typename Container::const_iterator it) { + return { cont.erase(it), true }; } }; @@ -285,8 +277,7 @@ struct fixed_sequence_container { * @return A pair consisting of an invalid iterator and a false value to * indicate failure in all cases. */ - [[nodiscard]] static std::pair, typename Container::const_iterator, typename Container::iterator>, bool> - insert(const Container &, std::conditional_t, typename Container::const_iterator, typename Container::iterator>, const typename Container::value_type &) { + [[nodiscard]] static std::pair insert(const Container &, typename Container::const_iterator, const typename Container::value_type &) { return { {}, false }; } @@ -295,8 +286,7 @@ struct fixed_sequence_container { * @return A pair consisting of an invalid iterator and a false value to * indicate failure in all cases. */ - [[nodiscard]] static std::pair, typename Container::const_iterator, typename Container::iterator>, bool> - erase(const Container &, std::conditional_t, typename Container::const_iterator, typename Container::iterator>) { + [[nodiscard]] static std::pair erase(const Container &, typename Container::const_iterator) { return { {}, false }; } }; @@ -319,23 +309,6 @@ struct meta_sequence_container_traits> {}; -/** - * @brief Meta sequence container traits for const `std::vector`s of any type. - * @tparam Type The type of elements. - * @tparam Args Other arguments. - */ -template -struct meta_sequence_container_traits> - : meta_container_traits< - const std::vector, - basic_container, - basic_dynamic_container, - basic_sequence_container, - dynamic_sequence_container - > -{}; - - /** * @brief Meta sequence container traits for `std::array`s of any type. * @tparam Type The type of elements. @@ -352,22 +325,6 @@ struct meta_sequence_container_traits> {}; -/** - * @brief Meta sequence container traits for const `std::array`s of any type. - * @tparam Type The type of elements. - * @tparam N The number of elements. - */ -template -struct meta_sequence_container_traits> - : meta_container_traits< - const std::array, - basic_container, - basic_sequence_container, - fixed_sequence_container - > -{}; - - /** * @brief Meta associative container traits for `std::map`s of any type. * @tparam Key The key type of elements. @@ -390,28 +347,6 @@ struct meta_associative_container_traits> }; -/** - * @brief Meta associative container traits for const `std::map`s of any type. - * @tparam Key The key type of elements. - * @tparam Value The value type of elements. - * @tparam Args Other arguments. - */ -template -struct meta_associative_container_traits> - : meta_container_traits< - const std::map, - basic_container, - basic_associative_container, - basic_dynamic_container, - basic_dynamic_associative_container, - dynamic_associative_key_value_container - > -{ - /*! @brief Mapped type of the sequence container. */ - using mapped_type = typename std::map::mapped_type; -}; - - /** * @brief Meta associative container traits for `std::unordered_map`s of any * type. @@ -435,29 +370,6 @@ struct meta_associative_container_traits }; -/** - * @brief Meta associative container traits for const `std::unordered_map`s of - * any type. - * @tparam Key The key type of elements. - * @tparam Value The value type of elements. - * @tparam Args Other arguments. - */ -template -struct meta_associative_container_traits> - : meta_container_traits< - const std::unordered_map, - basic_container, - basic_associative_container, - basic_dynamic_container, - basic_dynamic_associative_container, - dynamic_associative_key_value_container - > -{ - /*! @brief Mapped type of the sequence container. */ - using mapped_type = typename std::unordered_map::mapped_type; -}; - - /** * @brief Meta associative container traits for `std::set`s of any type. * @tparam Key The type of elements. @@ -476,24 +388,6 @@ struct meta_associative_container_traits> {}; -/** - * @brief Meta associative container traits for const `std::set`s of any type. - * @tparam Key The type of elements. - * @tparam Args Other arguments. - */ -template -struct meta_associative_container_traits> - : meta_container_traits< - const std::set, - basic_container, - basic_associative_container, - basic_dynamic_container, - basic_dynamic_associative_container, - dynamic_associative_key_only_container - > -{}; - - /** * @brief Meta associative container traits for `std::unordered_set`s of any * type. @@ -513,25 +407,6 @@ struct meta_associative_container_traits> {}; -/** - * @brief Meta associative container traits for const `std::unordered_set`s of - * any type. - * @tparam Key The type of elements. - * @tparam Args Other arguments. - */ -template -struct meta_associative_container_traits> - : meta_container_traits< - const std::unordered_set, - basic_container, - basic_associative_container, - basic_dynamic_container, - basic_dynamic_associative_container, - dynamic_associative_key_only_container - > -{}; - - } diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 51dea0b27..b09e55e66 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -49,7 +49,7 @@ public: * @param instance The container to wrap. */ template - meta_sequence_container(Type &instance) ENTT_NOEXCEPT + meta_sequence_container(std::in_place_type_t, any instance) ENTT_NOEXCEPT : value_type_fn{&meta_sequence_container_proxy::value_type}, size_fn{&meta_sequence_container_proxy::size}, resize_fn{&meta_sequence_container_proxy::resize}, @@ -59,7 +59,7 @@ public: insert_fn{&meta_sequence_container_proxy::insert}, erase_fn{&meta_sequence_container_proxy::erase}, get_fn{&meta_sequence_container_proxy::get}, - storage{std::reference_wrapper{instance}} + storage{std::move(instance)} {} [[nodiscard]] inline meta_type value_type() const ENTT_NOEXCEPT; @@ -109,7 +109,7 @@ public: * @param instance The container to wrap. */ template - meta_associative_container(Type &instance) ENTT_NOEXCEPT + meta_associative_container(std::in_place_type_t, any instance) ENTT_NOEXCEPT : key_only_container{is_key_only_meta_associative_container_v}, key_type_fn{&meta_associative_container_proxy::key_type}, mapped_type_fn{&meta_associative_container_proxy::mapped_type}, @@ -121,7 +121,7 @@ public: insert_fn{&meta_associative_container_proxy::insert}, erase_fn{&meta_associative_container_proxy::erase}, find_fn{&meta_associative_container_proxy::find}, - storage{std::reference_wrapper{instance}} + storage{std::move(instance)} {} [[nodiscard]] inline bool key_only() const ENTT_NOEXCEPT; @@ -164,7 +164,7 @@ class meta_any { switch(op) { case operation::DEREF: if constexpr(is_meta_pointer_like_v) { - *static_cast(to) = std::ref(*any_cast(from)); + *static_cast(to) = std::reference_wrapper{*any_cast(from)}; } break; case operation::CDEREF: @@ -174,26 +174,22 @@ class meta_any { break; case operation::SEQ: if constexpr(has_meta_sequence_container_traits_v) { - if(auto *instance = any_cast(&const_cast(from)); instance) { - return *static_cast(to) = *instance, void(); - } + *static_cast(to) = { std::in_place_type, as_ref(const_cast(from)) }; } - [[fallthrough]]; + break; case operation::CSEQ: if constexpr(has_meta_sequence_container_traits_v) { - *static_cast(to) = any_cast(from); + *static_cast(to) = { std::in_place_type, as_ref(from) }; } break; case operation::ASSOC: if constexpr(has_meta_associative_container_traits_v) { - if(auto *instance = any_cast(&const_cast(from)); instance) { - return *static_cast(to) = *instance, void(); - } + *static_cast(to) = { std::in_place_type, as_ref(const_cast(from)) }; } - [[fallthrough]]; + break; case operation::CASSOC: if constexpr(has_meta_associative_container_traits_v) { - *static_cast(to) = any_cast(from); + *static_cast(to) = { std::in_place_type, as_ref(from) }; } break; } @@ -1812,24 +1808,40 @@ struct meta_sequence_container::meta_sequence_container_proxy { } [[nodiscard]] static bool resize(any &container, size_type sz) { - return traits_type::resize(any_cast(container), sz); + if(auto *cont = any_cast(&container); cont) { + return traits_type::resize(*cont, sz); + } + + return false; } [[nodiscard]] static bool clear(any &container) { - return traits_type::clear(any_cast(container)); + if(auto *cont = any_cast(&container); cont) { + return traits_type::clear(*cont); + } + + return false; } [[nodiscard]] static iterator begin(any &container) { - return iterator{traits_type::begin(any_cast(container))}; + if(auto *cont = any_cast(&container); cont) { + return iterator{traits_type::begin(*cont)}; + } + + return iterator{traits_type::cbegin(any_cast(container))}; } [[nodiscard]] static iterator end(any &container) { - return iterator{traits_type::end(any_cast(container))}; + if(auto *cont = any_cast(&container); cont) { + return iterator{traits_type::end(*cont)}; + } + + return iterator{traits_type::cend(any_cast(container))}; } [[nodiscard]] static std::pair insert(any &container, iterator it, meta_any &value) { - if(value.allow_cast()) { - auto ret = traits_type::insert(any_cast(container), any_cast(it.handle), value.cast()); + if(auto *cont = any_cast(&container); cont && value.allow_cast()) { + auto ret = traits_type::insert(*cont, any_cast(it.handle), value.cast()); return { iterator{std::move(ret.first)}, ret.second }; } @@ -1837,12 +1849,20 @@ struct meta_sequence_container::meta_sequence_container_proxy { } [[nodiscard]] static std::pair erase(any &container, iterator it) { - auto ret = traits_type::erase(any_cast(container), any_cast(it.handle)); - return { iterator{std::move(ret.first)}, ret.second }; + if(auto *cont = any_cast(&container); cont) { + auto ret = traits_type::erase(*cont, any_cast(it.handle)); + return { iterator{std::move(ret.first)}, ret.second }; + } + + return {}; } [[nodiscard]] static meta_any get(any &container, size_type pos) { - return std::reference_wrapper{traits_type::get(any_cast(container), pos)}; + if(auto *cont = any_cast(&container); cont) { + return std::reference_wrapper{traits_type::get(*cont, pos)}; + } + + return std::reference_wrapper{traits_type::cget(any_cast(container), pos)}; } }; @@ -2078,24 +2098,36 @@ struct meta_associative_container::meta_associative_container_proxy { } [[nodiscard]] static bool clear(any &container) { - return traits_type::clear(any_cast(container)); + if(auto *cont = any_cast(&container); cont) { + return traits_type::clear(*cont); + } + + return false; } [[nodiscard]] static iterator begin(any &container) { - return iterator{is_key_only_meta_associative_container{}, traits_type::begin(any_cast(container))}; + if(auto *cont = any_cast(&container); cont) { + return iterator{is_key_only_meta_associative_container{}, traits_type::begin(*cont)}; + } + + return iterator{is_key_only_meta_associative_container{}, traits_type::cbegin(any_cast(container))}; } [[nodiscard]] static iterator end(any &container) { - return iterator{is_key_only_meta_associative_container{}, traits_type::end(any_cast(container))}; + if(auto *cont = any_cast(&container); cont) { + return iterator{is_key_only_meta_associative_container{}, traits_type::end(*cont)}; + } + + return iterator{is_key_only_meta_associative_container{}, traits_type::cend(any_cast(container))}; } [[nodiscard]] static bool insert(any &container, meta_any &key, meta_any &value) { - if(key.allow_cast()) { + if(auto *cont = any_cast(&container); cont && key.allow_cast()) { if constexpr(is_key_only_meta_associative_container_v) { - return traits_type::insert(any_cast(container), key.cast()); + return traits_type::insert(*cont, key.cast()); } else { if(value.allow_cast()) { - return traits_type::insert(any_cast(container), key.cast(), value.cast()); + return traits_type::insert(*cont, key.cast(), value.cast()); } } } @@ -2104,8 +2136,8 @@ struct meta_associative_container::meta_associative_container_proxy { } [[nodiscard]] static bool erase(any &container, meta_any &key) { - if(key.allow_cast()) { - return traits_type::erase(any_cast(container), key.cast()); + if(auto *cont = any_cast(&container); cont && key.allow_cast()) { + return traits_type::erase(*cont, key.cast()); } return false; @@ -2113,7 +2145,11 @@ struct meta_associative_container::meta_associative_container_proxy { [[nodiscard]] static iterator find(any &container, meta_any &key) { if(key.allow_cast()) { - return iterator{is_key_only_meta_associative_container{}, traits_type::find(any_cast(container), key.cast())}; + if(auto *cont = any_cast(&container); cont) { + return iterator{is_key_only_meta_associative_container{}, traits_type::find(*cont, key.cast())}; + } + + return iterator{is_key_only_meta_associative_container{}, traits_type::cfind(any_cast(container), key.cast())}; } return {}; diff --git a/src/entt/meta/type_traits.hpp b/src/entt/meta/type_traits.hpp index 9efb3f3bc..7f0632227 100644 --- a/src/entt/meta/type_traits.hpp +++ b/src/entt/meta/type_traits.hpp @@ -33,16 +33,6 @@ template struct has_meta_sequence_container_traits: std::false_type {}; -/** - * @brief TODO - * @tparam Type TODO - */ -template -struct has_meta_sequence_container_traits - : has_meta_sequence_container_traits -{}; - - /*! @copydoc has_meta_sequence_container_traits */ template struct has_meta_sequence_container_traits::value_type>> @@ -67,16 +57,6 @@ template struct has_meta_associative_container_traits: std::false_type {}; -/** - * @brief TODO - * @tparam Type TODO - */ -template -struct has_meta_associative_container_traits - : has_meta_associative_container_traits -{}; - - /*! @copydoc has_meta_associative_container_traits */ template struct has_meta_associative_container_traits::key_type>> @@ -101,16 +81,6 @@ template struct is_key_only_meta_associative_container: std::true_type {}; -/** - * @brief TODO - * @tparam Type TODO - */ -template -struct is_key_only_meta_associative_container - : is_key_only_meta_associative_container -{}; - - /*! @copydoc is_key_only_meta_associative_container */ template struct is_key_only_meta_associative_container::mapped_type>>