Merge topic 'refactoring-STL-erase_if'

968477517e Refactoring: suppress cmEraseIf in favor of cm::erase_if
348b60d19d STL support: add c++20 std::erase and std::erase_if functions

Acked-by: Kitware Robot <kwrobot@kitware.com>
Rejected-by: Leonid Pospelov <pospelovlm@yandex.ru>
Merge-request: !4192
This commit is contained in:
Brad King 2020-01-13 15:30:57 +00:00 committed by Kitware Robot
commit 95e3c8b440
17 changed files with 387 additions and 23 deletions

View File

@ -7,6 +7,7 @@
#include <utility>
#include <cm/memory>
#include <cm/vector>
#include "cm_static_string_view.hxx"
@ -174,7 +175,7 @@ void cmCTestSubmitCommand::CheckArguments(
this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
cmEraseIf(this->Parts, [this](std::string const& arg) -> bool {
cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
if (p == cmCTest::PartCount) {
std::ostringstream e;
@ -185,7 +186,7 @@ void cmCTestSubmitCommand::CheckArguments(
return false;
});
cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "

View File

@ -4,11 +4,11 @@
#include <set>
#include <sstream>
#include <vector>
#include <cm/vector>
#include "cm_static_string_view.hxx"
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
#include "cmMakefile.h"
@ -24,7 +24,7 @@ void cmCTestUploadCommand::BindArguments()
void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&)
{
cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
std::ostringstream e;
e << "File \"" << arg << "\" does not exist. Cannot submit "

View File

@ -37,12 +37,6 @@ FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
return first;
}
template <typename Container, typename Predicate>
void cmEraseIf(Container& cont, Predicate pred)
{
cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
}
template <typename Range, typename Key>
auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>)
-> decltype(range.exists(key))

View File

@ -2,7 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio14Generator.h"
#include "cmAlgorithms.h"
#include <cm/vector>
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
@ -303,7 +304,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
// Skip SDKs that do not contain <um/windows.h> because that indicates that
// only the UCRT MSIs were installed for them.
cmEraseIf(sdks, NoWindowsH());
cm::erase_if(sdks, NoWindowsH());
// Only use the filename, which will be the SDK version.
for (std::string& i : sdks) {
@ -313,7 +314,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
// Skip SDKs that cannot be used with our toolset.
std::string maxVersion = this->GetWindows10SDKMaxVersion();
if (!maxVersion.empty()) {
cmEraseIf(sdks, WindowsSDKTooRecent(maxVersion));
cm::erase_if(sdks, WindowsSDKTooRecent(maxVersion));
}
// Sort the results to make sure we select the most recent one.

View File

@ -9,12 +9,12 @@
#include <utility>
#include <cm/memory>
#include <cm/vector>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
#include "cmAlgorithms.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
#include "cmFileTimeCache.h"
@ -1876,7 +1876,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
std::string binaryDir = this->GetState()->GetBinaryDirectory();
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
cmEraseIf(includes, ::NotInProjectDir(sourceDir, binaryDir));
cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
}
for (std::string const& include : includes) {
cmakefileStream << " \""

View File

@ -17,6 +17,7 @@
#include <cm/iterator>
#include <cm/memory>
#include <cm/optional>
#include <cm/vector>
#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
@ -840,12 +841,12 @@ void cmMakefile::DoGenerate(cmLocalGenerator& lg)
// we don't want cmake to re-run if a configured file is created and deleted
// during processing as that would make it a transient file that can't
// influence the build process
cmEraseIf(this->OutputFiles, file_not_persistent());
cm::erase_if(this->OutputFiles, file_not_persistent());
// if a configured file is used as input for another configured file,
// and then deleted it will show up in the input list files so we
// need to scan those too
cmEraseIf(this->ListFiles, file_not_persistent());
cm::erase_if(this->ListFiles, file_not_persistent());
}
// Generate the output file

View File

@ -11,8 +11,8 @@
#include <utility>
#include <cm/memory>
#include <cm/vector>
#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
@ -243,7 +243,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
}
// If there is no ranlib the command will be ":". Skip it.
cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
@ -379,7 +379,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
}
// If there is no ranlib the command will be ":". Skip it.
cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
linkCmds.emplace_back("$POST_BUILD");

View File

@ -1,2 +1,2 @@
cm/* our-c-style
cmext/* our-c-style
cm/** our-c-style
cmext/** our-c-style

View File

@ -0,0 +1,29 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_bits_erase_if_hxx
#define cm_bits_erase_if_hxx
namespace cm {
namespace internals {
template <typename Container, typename Predicate>
void erase_if(Container& cont, Predicate pred)
{
for (typename Container::iterator iter = cont.begin(), last = cont.end();
iter != last;) {
if (pred(*iter)) {
iter = cont.erase(iter);
} else {
++iter;
}
}
}
} // namespace internals
} // namespace cm
#endif

40
Utilities/std/cm/deque Normal file
View File

@ -0,0 +1,40 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_deque
#define cm_deque
#include <algorithm>
#include <deque> // IWYU pragma: export
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase;
using std::erase_if;
#else
template <typename T, typename Allocator, typename V>
inline void erase(std::deque<T, Allocator>& cont, const V& value)
{
cont.erase(std::remove(cont.begin(), cont.end(), value), cont.end());
}
template <typename T, typename Allocator, typename Predicate>
inline void erase_if(std::deque<T, Allocator>& cont, Predicate pred)
{
cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
}
#endif
} // namespace cm
#endif

39
Utilities/std/cm/list Normal file
View File

@ -0,0 +1,39 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_list
#define cm_list
#include <list> // IWYU pragma: export
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase;
using std::erase_if;
#else
template <typename T, typename Allocator, typename V>
inline void erase(std::list<T, Allocator>& cont, const V& value)
{
cont.remove_if([&](auto& elem) { return elem == value; });
}
template <typename T, typename Allocator, typename Predicate>
inline void erase_if(std::list<T, Allocator>& cont, Predicate pred)
{
cont.remove_if(pred);
}
#endif
} // namespace cm
#endif

44
Utilities/std/cm/map Normal file
View File

@ -0,0 +1,44 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_map
#define cm_map
#include <map> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase_if;
#else
template <typename Key, typename T, typename Compare, typename Allocator,
typename Predicate>
inline void erase_if(std::map<Key, T, Compare, Allocator>& cont,
Predicate pred)
{
internals::erase_if(cont, pred);
}
template <typename Key, typename T, typename Compare, typename Allocator,
typename Predicate>
inline void erase_if(std::multimap<Key, T, Compare, Allocator>& cont,
Predicate pred)
{
internals::erase_if(cont, pred);
}
#endif
} // namespace cm
#endif

43
Utilities/std/cm/set Normal file
View File

@ -0,0 +1,43 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_set
#define cm_set
#include <set> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase_if;
#else
template <typename Key, typename Compare, typename Allocator,
typename Predicate>
inline void erase_if(std::set<Key, Compare, Allocator>& cont, Predicate pred)
{
internals::erase_if(cont, pred);
}
template <typename Key, typename Compare, typename Allocator,
typename Predicate>
inline void erase_if(std::multiset<Key, Compare, Allocator>& cont,
Predicate pred)
{
internals::erase_if(cont, pred);
}
#endif
} // namespace cm
#endif

42
Utilities/std/cm/string Normal file
View File

@ -0,0 +1,42 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_string
#define cm_string
#include <algorithm>
#include <string> // IWYU pragma: export
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase;
using std::erase_if;
#else
template <typename T, typename Traits, typename Allocator, typename V>
inline void erase(std::basic_string<T, Traits, Allocator>& cont,
const V& value)
{
cont.erase(std::remove(cont.begin(), cont.end(), value), cont.end());
}
template <typename T, typename Traits, typename Allocator, typename Predicate>
inline void erase_if(std::basic_string<T, Traits, Allocator>& cont,
Predicate pred)
{
cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
}
#endif
} // namespace cm
#endif

View File

@ -0,0 +1,45 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_unordered_map
#define cm_unordered_map
#include <unordered_map> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase_if;
#else
template <typename Key, typename T, typename Hash, typename KeyEqual,
typename Allocator, typename Predicate>
inline void erase_if(
std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& cont, Predicate pred)
{
internals::erase_if(cont, pred);
}
template <typename Key, typename T, typename Hash, typename KeyEqual,
typename Allocator, typename Predicate>
inline void erase_if(
std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>& cont,
Predicate pred)
{
internals::erase_if(cont, pred);
}
#endif
} // namespace cm
#endif

View File

@ -0,0 +1,45 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_unordered_set
#define cm_unordered_set
#include <unordered_set> // IWYU pragma: export
#include <cm/bits/erase_if.hxx>
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase_if;
#else
template <typename Key, typename Hash, typename KeyEqual, typename Allocator,
typename Predicate>
inline void erase_if(std::unordered_set<Key, Hash, KeyEqual, Allocator>& cont,
Predicate pred)
{
internals::erase_if(cont, pred);
}
template <typename Key, typename Hash, typename KeyEqual, typename Allocator,
typename Predicate>
inline void erase_if(
std::unordered_multiset<Key, Hash, KeyEqual, Allocator>& cont,
Predicate pred)
{
internals::erase_if(cont, pred);
}
#endif
} // namespace cm
#endif

40
Utilities/std/cm/vector Normal file
View File

@ -0,0 +1,40 @@
// -*-c++-*-
// vim: set ft=cpp:
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cm_vector
#define cm_vector
#include <algorithm>
#include <vector> // IWYU pragma: export
namespace cm {
// should be updated when C++20 is finalized
#if (__cplusplus > 201703L || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \
defined(__cpp_lib_erase_if)
using std::erase;
using std::erase_if;
#else
template <typename T, typename Allocator, typename V>
inline void erase(std::vector<T, Allocator>& cont, const V& value)
{
cont.erase(std::remove(cont.begin(), cont.end(), value), cont.end());
}
template <typename T, typename Allocator, typename Predicate>
inline void erase_if(std::vector<T, Allocator>& cont, Predicate pred)
{
cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
}
#endif
} // namespace cm
#endif