ソースを参照

STL support: add c++20 std::erase and std::erase_if functions

Marc Chevrier 5 年 前
コミット
348b60d19d

+ 2 - 2
Utilities/std/.gitattributes

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

+ 29 - 0
Utilities/std/cm/bits/erase_if.hxx

@@ -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 - 0
Utilities/std/cm/deque

@@ -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 - 0
Utilities/std/cm/list

@@ -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 - 0
Utilities/std/cm/map

@@ -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 - 0
Utilities/std/cm/set

@@ -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 - 0
Utilities/std/cm/string

@@ -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

+ 45 - 0
Utilities/std/cm/unordered_map

@@ -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

+ 45 - 0
Utilities/std/cm/unordered_set

@@ -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 - 0
Utilities/std/cm/vector

@@ -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