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

This commit is contained in:
Marc Chevrier 2020-01-02 17:51:35 +01:00
parent d020ed99e9
commit 348b60d19d
10 changed files with 369 additions and 2 deletions

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