From 3bf42c6ff3805a0d42bbc661794a95ff31bedc26 Mon Sep 17 00:00:00 2001 From: untodesu Date: Sat, 15 Mar 2025 16:22:09 +0500 Subject: Add whatever I was working on for the last month --- deps/include/entt/meta/container.hpp | 388 +++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 deps/include/entt/meta/container.hpp (limited to 'deps/include/entt/meta/container.hpp') diff --git a/deps/include/entt/meta/container.hpp b/deps/include/entt/meta/container.hpp new file mode 100644 index 0000000..ee90c7d --- /dev/null +++ b/deps/include/entt/meta/container.hpp @@ -0,0 +1,388 @@ +// IWYU pragma: always_keep + +#ifndef ENTT_META_CONTAINER_HPP +#define ENTT_META_CONTAINER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../container/dense_map.hpp" +#include "../container/dense_set.hpp" +#include "context.hpp" +#include "meta.hpp" +#include "type_traits.hpp" + +namespace entt { + +/*! @cond TURN_OFF_DOXYGEN */ +namespace internal { + +template +struct fixed_size_sequence_container: std::true_type {}; + +template +struct fixed_size_sequence_container>: std::false_type {}; + +template +inline constexpr bool fixed_size_sequence_container_v = fixed_size_sequence_container::value; + +template +struct key_only_associative_container: std::true_type {}; + +template +struct key_only_associative_container>: std::false_type {}; + +template +inline constexpr bool key_only_associative_container_v = key_only_associative_container::value; + +template +struct reserve_aware_container: std::false_type {}; + +template +struct reserve_aware_container>: std::true_type {}; + +template +inline constexpr bool reserve_aware_container_v = reserve_aware_container::value; + +} // namespace internal +/*! @endcond */ + +/** + * @brief General purpose implementation of meta sequence container traits. + * @tparam Type Type of underlying sequence container. + */ +template +struct basic_meta_sequence_container_traits { + static_assert(std::is_same_v>>, "Unexpected type"); + + /*! @brief Unsigned integer type. */ + using size_type = typename meta_sequence_container::size_type; + /*! @brief Meta iterator type. */ + using iterator = typename meta_sequence_container::iterator; + + /*! @brief True in case of key-only containers, false otherwise. */ + static constexpr bool fixed_size = internal::fixed_size_sequence_container_v; + + /** + * @brief Returns the number of elements in a container. + * @param container Opaque pointer to a container of the given type. + * @return Number of elements. + */ + [[nodiscard]] static size_type size(const void *container) { + return static_cast(container)->size(); + } + + /** + * @brief Clears a container. + * @param container Opaque pointer to a container of the given type. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool clear([[maybe_unused]] void *container) { + if constexpr(fixed_size) { + return false; + } else { + static_cast(container)->clear(); + return true; + } + } + + /** + * @brief Increases the capacity of a container. + * @param container Opaque pointer to a container of the given type. + * @param sz Desired capacity. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) { + if constexpr(internal::reserve_aware_container_v) { + static_cast(container)->reserve(sz); + return true; + } else { + return false; + } + } + + /** + * @brief Resizes a container. + * @param container Opaque pointer to a container of the given type. + * @param sz The new number of elements. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) { + if constexpr(fixed_size || !std::is_default_constructible_v) { + return false; + } else { + static_cast(container)->resize(sz); + return true; + } + } + + /** + * @brief Returns a possibly const iterator to the beginning. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @return An iterator to the first element of the container. + */ + static iterator begin(const meta_ctx &area, void *container, const void *as_const) { + return container ? iterator{area, static_cast(container)->begin()} + : iterator{area, static_cast(as_const)->begin()}; + } + + /** + * @brief Returns a possibly const iterator to the end. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @return An iterator that is past the last element of the container. + */ + static iterator end(const meta_ctx &area, void *container, const void *as_const) { + return container ? iterator{area, static_cast(container)->end()} + : iterator{area, static_cast(as_const)->end()}; + } + + /** + * @brief Assigns one element to a container and constructs its object from + * a given opaque instance. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param value Optional opaque instance of the object to construct (as + * value type). + * @param cref Optional opaque instance of the object to construct (as + * decayed const reference type). + * @param it Iterator before which the element will be inserted. + * @return A possibly invalid iterator to the inserted element. + */ + [[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) { + if constexpr(fixed_size) { + return iterator{}; + } else { + auto *const non_const = any_cast(&it.base()); + return {area, static_cast(container)->insert( + non_const ? *non_const : any_cast(it.base()), + value ? *static_cast(value) : *static_cast *>(cref))}; + } + } + + /** + * @brief Erases an element from a container. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param it An opaque iterator to the element to erase. + * @return A possibly invalid iterator following the last removed element. + */ + [[nodiscard]] static iterator erase([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) { + if constexpr(fixed_size) { + return iterator{}; + } else { + auto *const non_const = any_cast(&it.base()); + return {area, static_cast(container)->erase(non_const ? *non_const : any_cast(it.base()))}; + } + } +}; + +/** + * @brief General purpose implementation of meta associative container traits. + * @tparam Type Type of underlying associative container. + */ +template +struct basic_meta_associative_container_traits { + static_assert(std::is_same_v>>, "Unexpected type"); + + /*! @brief Unsigned integer type. */ + using size_type = typename meta_associative_container::size_type; + /*! @brief Meta iterator type. */ + using iterator = typename meta_associative_container::iterator; + + /*! @brief True in case of key-only containers, false otherwise. */ + static constexpr bool key_only = internal::key_only_associative_container_v; + + /** + * @brief Returns the number of elements in a container. + * @param container Opaque pointer to a container of the given type. + * @return Number of elements. + */ + [[nodiscard]] static size_type size(const void *container) { + return static_cast(container)->size(); + } + + /** + * @brief Clears a container. + * @param container Opaque pointer to a container of the given type. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool clear(void *container) { + static_cast(container)->clear(); + return true; + } + + /** + * @brief Increases the capacity of a container. + * @param container Opaque pointer to a container of the given type. + * @param sz Desired capacity. + * @return True in case of success, false otherwise. + */ + [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) { + if constexpr(internal::reserve_aware_container_v) { + static_cast(container)->reserve(sz); + return true; + } else { + return false; + } + } + + /** + * @brief Returns a possibly const iterator to the beginning. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @return An iterator to the first element of the container. + */ + static iterator begin(const meta_ctx &area, void *container, const void *as_const) { + return container ? iterator{area, std::bool_constant{}, static_cast(container)->begin()} + : iterator{area, std::bool_constant{}, static_cast(as_const)->begin()}; + } + + /** + * @brief Returns a possibly const iterator to the end. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @return An iterator that is past the last element of the container. + */ + static iterator end(const meta_ctx &area, void *container, const void *as_const) { + return container ? iterator{area, std::bool_constant{}, static_cast(container)->end()} + : iterator{area, std::bool_constant{}, static_cast(as_const)->end()}; + } + + /** + * @brief Inserts an element into a container, if the key does not exist. + * @param container Opaque pointer to a container of the given type. + * @param key An opaque key value of an element to insert. + * @param value Optional opaque value to insert (key-value containers). + * @return True if the insertion took place, false otherwise. + */ + [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) { + if constexpr(key_only) { + return static_cast(container)->insert(*static_cast(key)).second; + } else { + return static_cast(container)->emplace(*static_cast(key), *static_cast(value)).second; + } + } + + /** + * @brief Removes an element from a container. + * @param container Opaque pointer to a container of the given type. + * @param key An opaque key value of an element to remove. + * @return Number of elements removed (either 0 or 1). + */ + [[nodiscard]] static size_type erase(void *container, const void *key) { + return static_cast(container)->erase(*static_cast(key)); + } + + /** + * @brief Finds an element with a given key. + * @param area The context to pass to the newly created iterator. + * @param container Opaque pointer to a container of the given type. + * @param as_const Const opaque pointer fallback. + * @param key Opaque key value of an element to search for. + * @return An iterator to the element with the given key, if any. + */ + static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key) { + return container ? iterator{area, std::bool_constant{}, static_cast(container)->find(*static_cast(key))} + : iterator{area, std::bool_constant{}, static_cast(as_const)->find(*static_cast(key))}; + } +}; + +/** + * @brief Meta sequence container traits for `std::vector`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta sequence container traits for `std::array`s of any type. + * @tparam Type Template arguments for the container. + * @tparam N Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta sequence container traits for `std::list`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta sequence container traits for `std::deque`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_sequence_container_traits> + : basic_meta_sequence_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::map`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::unordered_map`s of any + * type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::set`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `std::unordered_set`s of any + * type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `dense_map`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +/** + * @brief Meta associative container traits for `dense_set`s of any type. + * @tparam Args Template arguments for the container. + */ +template +struct meta_associative_container_traits> + : basic_meta_associative_container_traits> {}; + +} // namespace entt + +#endif -- cgit