From e0a23664aafad2a215df4c43e85a47c4a006e693 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Sat, 16 Dec 2017 20:39:33 +0100 Subject: Utils::transform: Allow usage with non-const source containers Makes it possible to e.g. transform to list of reference_wrappers. Change-Id: Ib608034fc3f296824c289edd27563bc7a196ac6d Reviewed-by: hjk --- src/libs/utils/algorithm.h | 114 ++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 43 deletions(-) (limited to 'src/libs/utils/algorithm.h') diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 7c6fad0d9a..90405f0129 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -334,11 +334,10 @@ inserter(QSet &container) // function without result type deduction: template class SC, // input container type - typename F, // function type - typename... SCArgs> // Arguments to SC + typename SC, // input container type + typename F> // function type Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, F function) +decltype(auto) transform(SC &&container, F function) { ResultContainer result; result.reserve(container.size()); @@ -348,79 +347,74 @@ decltype(auto) transform(const SC &container, F function) // function with result type deduction: template class C, // result container type - template class SC, // input container type + typename SC, // input container type typename F, // function type - typename... SCArgs, // Arguments to SC - typename Value = typename SC::value_type, - typename ResultContainer = C>>> + typename Value = typename std::decay_t::value_type, + typename Result = std::decay_t>, + typename ResultContainer = C> Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, F function) +decltype(auto) transform(SC &&container, F function) { - return transform(container, function); + return transform(std::forward(container), function); } template class C, // result container type - template class SC, // input container type + typename SC, // input container type typename F, // function type - typename... SCArgs, // Arguments to SC - typename Value = typename SC::value_type, - typename Result = std::decay_t>, + typename Value = typename std::decay_t::value_type, + typename Result = std::decay_t>, typename ResultContainer = C>> Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, F function) +decltype(auto) transform(SC &&container, F function) { - return transform(container, function); + return transform(std::forward(container), function); } // member function without result type deduction: template class C, // result container type - template class SC, // input container type + typename SC, // input container type typename R, - typename S, - typename... SCArgs> // Arguments to SC + typename S> Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, R (S::*p)() const) +decltype(auto) transform(SC &&container, R (S::*p)() const) { - return transform(container, std::mem_fn(p)); + return transform(std::forward(container), std::mem_fn(p)); } // member function with result type deduction: template class SC, // input container type + typename SC, // input container type typename R, - typename S, - typename... SCArgs> // Arguments to SC + typename S> Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, R (S::*p)() const) +decltype(auto) transform(SC &&container, R (S::*p)() const) { - return transform(container, std::mem_fn(p)); + return transform(std::forward(container), std::mem_fn(p)); } // member without result type deduction: template class SC, // input container + typename SC, // input container typename R, - typename S, - typename... SCArgs> // Arguments to SC + typename S> Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, R S::*p) +decltype(auto) transform(SC &&container, R S::*p) { - return transform(container, std::mem_fn(p)); + return transform(std::forward(container), std::mem_fn(p)); } // member with result type deduction: template class C, // result container - template class SC, // input container + typename SC, // input container typename R, - typename S, - typename... SCArgs> // Arguments to SC + typename S> Q_REQUIRED_RESULT -decltype(auto) transform(const SC &container, R S::*p) +decltype(auto) transform(SC &&container, R S::*p) { - return transform(container, std::mem_fn(p)); + return transform(std::forward(container), std::mem_fn(p)); } -// different container types for input and output, e.g. transforming a QList into a QSet +// same container types for input and output, const input // function: template class C, // container type @@ -429,7 +423,7 @@ template class C, // container type Q_REQUIRED_RESULT decltype(auto) transform(const C &container, F function) { - return transform(container, function); + return transform &>(container, function); } // member function: @@ -440,7 +434,7 @@ template class C, // container type Q_REQUIRED_RESULT decltype(auto) transform(const C &container, R (S::*p)() const) { - return transform(container, std::mem_fn(p)); + return transform &>(container, std::mem_fn(p)); } // members: @@ -451,7 +445,41 @@ template class C, // container Q_REQUIRED_RESULT decltype(auto) transform(const C &container, R S::*p) { - return transform(container, std::mem_fn(p)); + return transform &>(container, std::mem_fn(p)); +} + +// same container types for input and output, non-const input + +// function: +template class C, // container type + typename F, // function type + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT +decltype(auto) transform(C &container, F function) +{ + return transform &>(container, function); +} + +// member function: +template class C, // container type + typename R, + typename S, + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT +decltype(auto) transform(C &container, R (S::*p)() const) +{ + return transform &>(container, std::mem_fn(p)); +} + +// members: +template class C, // container + typename R, + typename S, + typename... CArgs> // Arguments to SC +Q_REQUIRED_RESULT +decltype(auto) transform(C &container, R S::*p) +{ + return transform &>(container, std::mem_fn(p)); } // Specialization for QStringList: @@ -461,7 +489,7 @@ template class C = QList, // result container Q_REQUIRED_RESULT decltype(auto) transform(const QStringList &container, F function) { - return transform(static_cast>(container), function); + return transform &>(static_cast>(container), function); } // member function: @@ -471,7 +499,7 @@ template class C = QList, // result container type Q_REQUIRED_RESULT decltype(auto) transform(const QStringList &container, R (S::*p)() const) { - return transform(static_cast>(container), std::mem_fn(p)); + return transform &>(static_cast>(container), std::mem_fn(p)); } // members: @@ -481,7 +509,7 @@ template class C = QList, // result container Q_REQUIRED_RESULT decltype(auto) transform(const QStringList &container, R S::*p) { - return transform(static_cast>(container), std::mem_fn(p)); + return transform &>(static_cast>(container), std::mem_fn(p)); } ////////////////// -- cgit v1.2.1