فهرست منبع

meta: container traits not required for const T

Michele Caini 5 سال پیش
والد
کامیت
c99e859978
3فایلهای تغییر یافته به همراه106 افزوده شده و 225 حذف شده
  1. 37 162
      src/entt/meta/container.hpp
  2. 69 33
      src/entt/meta/meta.hpp
  3. 0 30
      src/entt/meta/type_traits.hpp

+ 37 - 162
src/entt/meta/container.hpp

@@ -34,7 +34,9 @@ struct meta_container_traits: public Trait<Container>... {};
 template<typename Container>
 struct basic_container {
     /*! @brief Iterator type of the container. */
-    using iterator = std::conditional_t<std::is_const_v<Container>, 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<std::is_const_v<Container>, 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<Container>) {
-            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<Container>) {
-            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<typename Container::value_type, Container> & 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<Container>) {
-            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<Container>) {
-            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<Container>) {
-            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<std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator>, bool>
-    insert([[maybe_unused]] Container &cont, [[maybe_unused]] std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator> it, [[maybe_unused]] const typename Container::value_type &value) {
-        if constexpr(std::is_const_v<Container>) {
-            return { {}, false };
-        } else {
-            return { cont.insert(it, value), true };
-        }
+    [[nodiscard]] static std::pair<typename Container::iterator, bool> 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<std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator>, bool>
-    erase([[maybe_unused]] Container &cont, [[maybe_unused]] std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator> it) {
-        if constexpr(std::is_const_v<Container>) {
-            return { {}, false };
-        } else {
-            return { cont.erase(it), true };
-        }
+    [[nodiscard]] static std::pair<typename Container::iterator, bool> 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<std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator>, bool>
-    insert(const Container &, std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator>, const typename Container::value_type &) {
+    [[nodiscard]] static std::pair<typename Container::iterator, bool> 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<std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator>, bool>
-    erase(const Container &, std::conditional_t<std::is_const_v<Container>, typename Container::const_iterator, typename Container::iterator>) {
+    [[nodiscard]] static std::pair<typename Container::iterator, bool> erase(const Container &, typename Container::const_iterator) {
         return { {}, false };
     }
 };
@@ -319,23 +309,6 @@ struct meta_sequence_container_traits<std::vector<Type, Args...>>
 {};
 
 
-/**
- * @brief Meta sequence container traits for const `std::vector`s of any type.
- * @tparam Type The type of elements.
- * @tparam Args Other arguments.
- */
-template<typename Type, typename... Args>
-struct meta_sequence_container_traits<const std::vector<Type, Args...>>
-        : meta_container_traits<
-              const std::vector<Type, Args...>,
-              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<std::array<Type, N>>
 {};
 
 
-/**
- * @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<typename Type, auto N>
-struct meta_sequence_container_traits<const std::array<Type, N>>
-        : meta_container_traits<
-              const std::array<Type, N>,
-              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<std::map<Key, Value, Args...>>
 };
 
 
-/**
- * @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<typename Key, typename Value, typename... Args>
-struct meta_associative_container_traits<const std::map<Key, Value, Args...>>
-        : meta_container_traits<
-              const std::map<Key, Value, Args...>,
-              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<Key, Value, Args...>::mapped_type;
-};
-
-
 /**
  * @brief Meta associative container traits for `std::unordered_map`s of any
  * type.
@@ -435,29 +370,6 @@ struct meta_associative_container_traits<std::unordered_map<Key, Value, Args...>
 };
 
 
-/**
- * @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<typename Key, typename Value, typename... Args>
-struct meta_associative_container_traits<const std::unordered_map<Key, Value, Args...>>
-        : meta_container_traits<
-              const std::unordered_map<Key, Value, Args...>,
-              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<Key, Value, Args...>::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<std::set<Key, Args...>>
 {};
 
 
-/**
- * @brief Meta associative container traits for const `std::set`s of any type.
- * @tparam Key The type of elements.
- * @tparam Args Other arguments.
- */
-template<typename Key, typename... Args>
-struct meta_associative_container_traits<const std::set<Key, Args...>>
-        : meta_container_traits<
-              const std::set<Key, Args...>,
-              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<std::unordered_set<Key, Args...>>
 {};
 
 
-/**
- * @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<typename Key, typename... Args>
-struct meta_associative_container_traits<const std::unordered_set<Key, Args...>>
-        : meta_container_traits<
-              const std::unordered_set<Key, Args...>,
-              basic_container,
-              basic_associative_container,
-              basic_dynamic_container,
-              basic_dynamic_associative_container,
-              dynamic_associative_key_only_container
-          >
-{};
-
-
 }
 
 

+ 69 - 33
src/entt/meta/meta.hpp

@@ -49,7 +49,7 @@ public:
      * @param instance The container to wrap.
      */
     template<typename Type>
-    meta_sequence_container(Type &instance) ENTT_NOEXCEPT
+    meta_sequence_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
         : 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},
@@ -59,7 +59,7 @@ public:
           insert_fn{&meta_sequence_container_proxy<Type>::insert},
           erase_fn{&meta_sequence_container_proxy<Type>::erase},
           get_fn{&meta_sequence_container_proxy<Type>::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<typename Type>
-    meta_associative_container(Type &instance) ENTT_NOEXCEPT
+    meta_associative_container(std::in_place_type_t<Type>, any instance) ENTT_NOEXCEPT
         : key_only_container{is_key_only_meta_associative_container_v<Type>},
           key_type_fn{&meta_associative_container_proxy<Type>::key_type},
           mapped_type_fn{&meta_associative_container_proxy<Type>::mapped_type},
@@ -121,7 +121,7 @@ public:
           insert_fn{&meta_associative_container_proxy<Type>::insert},
           erase_fn{&meta_associative_container_proxy<Type>::erase},
           find_fn{&meta_associative_container_proxy<Type>::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<Type>) {
-                *static_cast<meta_any *>(to) = std::ref(*any_cast<const Type>(from));
+                *static_cast<meta_any *>(to) = std::reference_wrapper{*any_cast<const Type>(from)};
             }
             break;
         case operation::CDEREF:
@@ -174,26 +174,22 @@ class meta_any {
             break;
         case operation::SEQ:
             if constexpr(has_meta_sequence_container_traits_v<Type>) {
-                if(auto *instance = any_cast<Type>(&const_cast<any &>(from)); instance) {
-                    return *static_cast<meta_sequence_container *>(to) = *instance, void();
-                }
+                *static_cast<meta_sequence_container *>(to) = { std::in_place_type<Type>, as_ref(const_cast<any &>(from)) };
             }
-            [[fallthrough]];
+            break;
         case operation::CSEQ:
             if constexpr(has_meta_sequence_container_traits_v<Type>) {
-                *static_cast<meta_sequence_container *>(to) = any_cast<const Type &>(from);
+                *static_cast<meta_sequence_container *>(to) = { std::in_place_type<Type>, as_ref(from) };
             }
             break;
         case operation::ASSOC:
             if constexpr(has_meta_associative_container_traits_v<Type>) {
-                if(auto *instance = any_cast<Type>(&const_cast<any &>(from)); instance) {
-                    return *static_cast<meta_associative_container *>(to) = *instance, void();
-                }
+                *static_cast<meta_associative_container *>(to) = { std::in_place_type<Type>, as_ref(const_cast<any &>(from)) };
             }
-            [[fallthrough]];
+            break;
         case operation::CASSOC:
             if constexpr(has_meta_associative_container_traits_v<Type>) {
-                *static_cast<meta_associative_container *>(to) = any_cast<const Type &>(from);
+                *static_cast<meta_associative_container *>(to) = { std::in_place_type<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<Type &>(container), sz);
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return traits_type::resize(*cont, sz);
+        }
+
+        return false;
     }
 
     [[nodiscard]] static bool clear(any &container) {
-        return traits_type::clear(any_cast<Type &>(container));
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return traits_type::clear(*cont);
+        }
+
+        return false;
     }
 
     [[nodiscard]] static iterator begin(any &container) {
-        return iterator{traits_type::begin(any_cast<Type &>(container))};
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return iterator{traits_type::begin(*cont)};
+        }
+
+        return iterator{traits_type::cbegin(any_cast<const Type &>(container))};
     }
 
     [[nodiscard]] static iterator end(any &container) {
-        return iterator{traits_type::end(any_cast<Type &>(container))};
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return iterator{traits_type::end(*cont)};
+        }
+
+        return iterator{traits_type::cend(any_cast<const Type &>(container))};
     }
 
     [[nodiscard]] static std::pair<iterator, bool> insert(any &container, iterator it, meta_any &value) {
-        if(value.allow_cast<const typename traits_type::value_type &>()) {
-            auto ret = traits_type::insert(any_cast<Type &>(container), any_cast<const typename traits_type::iterator &>(it.handle), value.cast<const typename traits_type::value_type &>());
+        if(auto *cont = any_cast<Type>(&container); cont && value.allow_cast<const typename traits_type::value_type &>()) {
+            auto ret = traits_type::insert(*cont, any_cast<const typename traits_type::iterator &>(it.handle), value.cast<const typename traits_type::value_type &>());
             return { iterator{std::move(ret.first)}, ret.second };
         }
 
@@ -1837,12 +1849,20 @@ struct meta_sequence_container::meta_sequence_container_proxy {
     }
 
     [[nodiscard]] static std::pair<iterator, bool> erase(any &container, iterator it) {
-        auto ret = traits_type::erase(any_cast<Type &>(container), any_cast<const typename traits_type::iterator &>(it.handle));
-        return { iterator{std::move(ret.first)}, ret.second };
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            auto ret = traits_type::erase(*cont, any_cast<const typename traits_type::iterator &>(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<Type &>(container), pos)};
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return std::reference_wrapper{traits_type::get(*cont, pos)};
+        }
+
+        return std::reference_wrapper{traits_type::cget(any_cast<const Type &>(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<Type &>(container));
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return traits_type::clear(*cont);
+        }
+
+        return false;
     }
 
     [[nodiscard]] static iterator begin(any &container) {
-        return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::begin(any_cast<Type &>(container))};
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::begin(*cont)};
+        }
+
+        return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::cbegin(any_cast<const Type &>(container))};
     }
 
     [[nodiscard]] static iterator end(any &container) {
-        return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::end(any_cast<Type &>(container))};
+        if(auto *cont = any_cast<Type>(&container); cont) {
+            return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::end(*cont)};
+        }
+
+        return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::cend(any_cast<const Type &>(container))};
     }
 
     [[nodiscard]] static bool insert(any &container, meta_any &key, meta_any &value) {
-        if(key.allow_cast<const typename traits_type::key_type &>()) {
+        if(auto *cont = any_cast<Type>(&container); cont && key.allow_cast<const typename traits_type::key_type &>()) {
             if constexpr(is_key_only_meta_associative_container_v<Type>) {
-                return traits_type::insert(any_cast<Type &>(container), key.cast<const typename traits_type::key_type &>());
+                return traits_type::insert(*cont, key.cast<const typename traits_type::key_type &>());
             } else {
                 if(value.allow_cast<const typename traits_type::mapped_type &>()) {
-                    return traits_type::insert(any_cast<Type &>(container), key.cast<const typename traits_type::key_type &>(), value.cast<const typename traits_type::mapped_type &>());
+                    return traits_type::insert(*cont, key.cast<const typename traits_type::key_type &>(), value.cast<const typename traits_type::mapped_type &>());
                 }
             }
         }
@@ -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<const typename traits_type::key_type &>()) {
-            return traits_type::erase(any_cast<Type &>(container), key.cast<const typename traits_type::key_type &>());
+        if(auto *cont = any_cast<Type>(&container); cont && key.allow_cast<const typename traits_type::key_type &>()) {
+            return traits_type::erase(*cont, key.cast<const typename traits_type::key_type &>());
         }
 
         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<const typename traits_type::key_type &>()) {
-            return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::find(any_cast<Type &>(container), key.cast<const typename traits_type::key_type &>())};
+            if(auto *cont = any_cast<Type>(&container); cont) {
+                return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::find(*cont, key.cast<const typename traits_type::key_type &>())};
+            }
+
+            return iterator{is_key_only_meta_associative_container<Type>{}, traits_type::cfind(any_cast<const Type &>(container), key.cast<const typename traits_type::key_type &>())};
         }
 
         return {};

+ 0 - 30
src/entt/meta/type_traits.hpp

@@ -33,16 +33,6 @@ template<typename Type, typename = void>
 struct has_meta_sequence_container_traits: std::false_type {};
 
 
-/**
- * @brief TODO
- * @tparam Type TODO
- */
-template<typename Type>
-struct has_meta_sequence_container_traits<const Type>
-    : has_meta_sequence_container_traits<Type>
-{};
-
-
 /*! @copydoc has_meta_sequence_container_traits */
 template<typename Type>
 struct has_meta_sequence_container_traits<Type, std::void_t<typename meta_sequence_container_traits<Type>::value_type>>
@@ -67,16 +57,6 @@ template<typename, typename = void>
 struct has_meta_associative_container_traits: std::false_type {};
 
 
-/**
- * @brief TODO
- * @tparam Type TODO
- */
-template<typename Type>
-struct has_meta_associative_container_traits<const Type>
-    : has_meta_associative_container_traits<Type>
-{};
-
-
 /*! @copydoc has_meta_associative_container_traits */
 template<typename Type>
 struct has_meta_associative_container_traits<Type, std::void_t<typename meta_associative_container_traits<Type>::key_type>>
@@ -101,16 +81,6 @@ template<typename, typename = void>
 struct is_key_only_meta_associative_container: std::true_type {};
 
 
-/**
- * @brief TODO
- * @tparam Type TODO
- */
-template<typename Type>
-struct is_key_only_meta_associative_container<const Type>
-    : is_key_only_meta_associative_container<Type>
-{};
-
-
 /*! @copydoc is_key_only_meta_associative_container */
 template<typename Type>
 struct is_key_only_meta_associative_container<Type, std::void_t<typename meta_associative_container_traits<Type>::mapped_type>>