From cdff7f4e2a255e083e5a19ac541b4de2874785af Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Sun, 12 May 2019 13:11:51 +0200 Subject: cmSystemTools: Add ExpandedListArgument and ExpandedLists methods Changes ------- In `cmSystemTools` this - renames the method `ExpandList` to `ExpandLists` and makes it iterator based and adds the methods - `std::vector ExpandedLists(InputIt first, InputIt last)` - `std::vector ExpandedListArgument(const std::string& arg, bool emptyArgs)` Both return the `std::vector` instead of taking a return vector reference like `cmSystemTools::ExpandLists` and `cmSystemTools::ExpandListArgument`. Motivation ---------- Since C++17 return value optimization is mandatory, so returning a `std:vector` from a function should be (at least) as fast as passing a return vector reference to the function. The new methods can replace `cmSystemTools::ExpandLists` and `cmSystemTools::ExpandListArgument` in many cases, which leads to shorter and simpler syntax. E.g. the commonly used pattern ``` if (const char* value = X->GetProperty("A_KEY_STRING")) { std::vector valuesList; cmSystemTools::ExpandListArgument(value, valuesList); for (std::string const& i : valuesList) { doSomething(i); } } ``` becomes ``` if (const char* value = X->GetProperty("A_KEY_STRING")) { for (std::string const& i : cmSystemTools::ExpandedListArgument(value)) { doSomething(i); } } ``` --- Source/cmGlobalXCodeGenerator.cxx | 10 ++++----- Source/cmRemoveCommand.cxx | 10 ++++----- Source/cmSystemTools.cxx | 24 +++++++++++----------- Source/cmSystemTools.h | 43 ++++++++++++++++++++++++++++++++++----- 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index db673bb..6cbdefa 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2485,12 +2485,10 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget( std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target, cmGeneratorTarget* gtgt) { - std::string configTypes = - this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES"); - std::vector configVectorIn; - std::vector configVector; - configVectorIn.push_back(configTypes); - cmSystemTools::ExpandList(configVectorIn, configVector); + std::vector const configVector = + cmSystemTools::ExpandedListArgument( + this->CurrentMakefile->GetRequiredDefinition( + "CMAKE_CONFIGURATION_TYPES")); cmXCodeObject* configlist = this->CreateObject(cmXCodeObject::XCConfigurationList); cmXCodeObject* buildConfigurations = diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index bb14e68..a64ad8c 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -25,15 +25,13 @@ bool cmRemoveCommand::InitialPass(std::vector const& args, } // expand the variable - std::vector varArgsExpanded; - cmSystemTools::ExpandListArgument(cacheValue, varArgsExpanded); + std::vector const varArgsExpanded = + cmSystemTools::ExpandedListArgument(cacheValue); // expand the args // check for REMOVE(VAR v1 v2 ... vn) - std::vector argsExpanded; - std::vector temp; - temp.insert(temp.end(), args.begin() + 1, args.end()); - cmSystemTools::ExpandList(temp, argsExpanded); + std::vector const argsExpanded = + cmSystemTools::ExpandedLists(args.begin() + 1, args.end()); // now create the new value std::string value; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 17ed3f6..545e6c5 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1208,16 +1208,8 @@ void cmSystemTools::GlobDirs(const std::string& path, } } -void cmSystemTools::ExpandList(std::vector const& arguments, - std::vector& newargs) -{ - for (std::string const& arg : arguments) { - cmSystemTools::ExpandListArgument(arg, newargs); - } -} - void cmSystemTools::ExpandListArgument(const std::string& arg, - std::vector& newargs, + std::vector& argsOut, bool emptyArgs) { // If argument is empty, it is an empty list. @@ -1226,7 +1218,7 @@ void cmSystemTools::ExpandListArgument(const std::string& arg, } // if there are no ; in the name then just copy the current string if (arg.find(';') == std::string::npos) { - newargs.push_back(arg); + argsOut.push_back(arg); return; } std::string newArg; @@ -1260,7 +1252,7 @@ void cmSystemTools::ExpandListArgument(const std::string& arg, last = c + 1; if (!newArg.empty() || emptyArgs) { // Add the last argument if the string is not empty. - newargs.push_back(newArg); + argsOut.push_back(newArg); newArg.clear(); } } @@ -1273,10 +1265,18 @@ void cmSystemTools::ExpandListArgument(const std::string& arg, newArg.append(last); if (!newArg.empty() || emptyArgs) { // Add the last argument if the string is not empty. - newargs.push_back(newArg); + argsOut.push_back(newArg); } } +std::vector cmSystemTools::ExpandedListArgument( + const std::string& arg, bool emptyArgs) +{ + std::vector argsOut; + ExpandListArgument(arg, argsOut, emptyArgs); + return argsOut; +} + bool cmSystemTools::SimpleGlob(const std::string& glob, std::vector& files, int type /* = 0 */) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 8a87a37..d145d47 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -29,17 +29,50 @@ public: typedef cmsys::SystemTools Superclass; typedef cmProcessOutput::Encoding Encoding; - /** Expand out any arguments in the vector that have ; separated - * strings into multiple arguments. A new vector is created - * containing the expanded versions of all arguments in argsIn. + /** + * Expand the ; separated string @a arg into multiple arguments. + * All found arguments are appended to @a argsOut. */ - static void ExpandList(std::vector const& argsIn, - std::vector& argsOut); static void ExpandListArgument(const std::string& arg, std::vector& argsOut, bool emptyArgs = false); /** + * Expand out any arguments in the string range [@a first, @a last) that have + * ; separated strings into multiple arguments. All found arguments are + * appended to @a argsOut. + */ + template + static void ExpandLists(InputIt first, InputIt last, + std::vector& argsOut) + { + for (; first != last; ++first) { + cmSystemTools::ExpandListArgument(*first, argsOut); + } + } + + /** + * Same as ExpandListArgument but a new vector is created containing + * the expanded arguments from the string @a arg. + */ + static std::vector ExpandedListArgument(const std::string& arg, + bool emptyArgs = false); + + /** + * Same as ExpandList but a new vector is created containing the expanded + * versions of all arguments in the string range [@a first, @a last). + */ + template + static std::vector ExpandedLists(InputIt first, InputIt last) + { + std::vector argsOut; + for (; first != last; ++first) { + cmSystemTools::ExpandListArgument(*first, argsOut); + } + return argsOut; + } + + /** * Look for and replace registry values in a string */ static void ExpandRegistryValues(std::string& source, -- cgit v0.12