diff --git a/include/orm/tiny/concerns/hasattributes.hpp b/include/orm/tiny/concerns/hasattributes.hpp index 4f98286aa..62a82667d 100644 --- a/include/orm/tiny/concerns/hasattributes.hpp +++ b/include/orm/tiny/concerns/hasattributes.hpp @@ -521,8 +521,9 @@ namespace Orm::Tiny::Concerns removeSerializableHiddenAttributes(QVariantMap &&attributes, const std::set &hidden); /*! Get an attributes vector without hidden attributes. */ + template requires AttributesContainerConcept // requires is needed to select the correct overload static QList - removeSerializableHiddenAttributes(QList &&attributes, + removeSerializableHiddenAttributes(T &&attributes, const std::set &hidden); /* Serialization - Appends */ @@ -2198,8 +2199,10 @@ namespace Orm::Tiny::Concerns if (attributes.empty()) return {}; + const auto isVisibleEmpty = visible.empty(); + // Nothing to do, the visible and hidden attributes are not defined - if (visible.empty() && hidden.empty()) { + if (isVisibleEmpty && hidden.empty()) { if constexpr (std::is_same_v) return AttributeUtils::convertVectorToMap(attributes); @@ -2209,6 +2212,20 @@ namespace Orm::Tiny::Concerns } // Pass the visible and hidden down to avoid obtaining these references twice + + // Compute the hidden attributes only (to serialize) as the visible set is empty + // No need to compute the visible attributes (also allows forwarding reference) + if (isVisibleEmpty) { + if constexpr (std::is_same_v) + return removeSerializableHiddenAttributes( + AttributeUtils::convertVectorToMap(attributes), hidden); + + // QList + else + return removeSerializableHiddenAttributes(attributes, hidden); + } + + // Compute both visible and also hidden attributes to serialize return removeSerializableHiddenAttributes( getSerializableVisibleAttributes(attributes, visible, appends), hidden); @@ -2633,16 +2650,6 @@ namespace Orm::Tiny::Concerns const QList &attributes, const std::set &visible, const std::set &appends) { - // Nothing to do - if (visible.empty()) { - if constexpr (std::is_same_v) - return AttributeUtils::convertVectorToMap(attributes); - - // QList - else - return attributes; - } - // Get visible attributes only /* Compute visible keys on attributes map/vector, the intersection is needed to compute only keys that really exists. */ @@ -2699,13 +2706,14 @@ namespace Orm::Tiny::Concerns } template + template requires AttributesContainerConcept QList HasAttributes::removeSerializableHiddenAttributes( - QList &&attributes, const std::set &hidden) + T &&attributes, const std::set &hidden) { // Nothing to do if (hidden.empty()) - return std::move(attributes); + return std::forward(attributes); /* Remove hidden attributes, from the vector container returned by the getSerializableVisibleAttributes()! */ @@ -2718,9 +2726,17 @@ namespace Orm::Tiny::Concerns QList serializableAttributes; serializableAttributes.reserve(attributes.size()); +#if defined(_MSC_VER) && !defined(__clang__) +# pragma warning(push) +# pragma warning(disable : 26800) +#endif for (auto &&[key, value] : attributes) if (!hiddenKeys.contains(key)) - serializableAttributes.emplaceBack(std::move(key), std::move(value)); + serializableAttributes.emplaceBack(std::forward(key), + std::forward(value)); +#if defined(_MSC_VER) && !defined(__clang__) +# pragma warning(pop) +#endif return serializableAttributes; } diff --git a/include/orm/tiny/tinyconcepts.hpp b/include/orm/tiny/tinyconcepts.hpp index d7086a0f6..f738d57bf 100644 --- a/include/orm/tiny/tinyconcepts.hpp +++ b/include/orm/tiny/tinyconcepts.hpp @@ -52,6 +52,10 @@ namespace Orm::Tiny struct AttributeItem; + /*! Concept for Attributes vector container. */ + template + concept AttributesContainerConcept = std::convertible_to>; + /*! Concept to check the container for serialized model attributes. */ template concept SerializedAttributes = std::same_as ||