Skip to content

Instantly share code, notes, and snippets.

@hikarin522
Last active March 27, 2020 06:02
Show Gist options
  • Save hikarin522/68660a830c44697075739cd195f3f87c to your computer and use it in GitHub Desktop.
Save hikarin522/68660a830c44697075739cd195f3f87c to your computer and use it in GitHub Desktop.
#pragma once
// C++20 統一コンテナ削除
// https://ja.cppreference.com/w/cpp/experimental/lib_extensions_2#Uniform_container_erasure
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1209r0.html
#include <utility>
#include <iterator>
#include <algorithm>
#include <type_traits>
namespace std {
template <class T, class Allocator>
class vector;
template <class T, class Allocator>
class deque;
template <class charT, class traits, class Allocator>
class basic_string;
template <class T, class Allocator>
class list;
template <class T, class Allocator>
class forward_list;
template <class Key, class T, class Compare, class Allocator>
class map;
template <class Key, class T, class Compare, class Allocator>
class multimap;
template <class Key, class Compare, class Allocator>
class set;
template <class Key, class Compare, class Allocator>
class multiset;
template <class Key, class T, class Hash, class Pred, class Allocator>
class unordered_map;
template <class Key, class T, class Hash, class Pred, class Allocator>
class unordered_multimap;
template <class Key, class Hash, class Pred, class Allocator>
class unordered_set;
template <class Key, class Hash, class Pred, class Allocator>
class unordered_multiset;
}
namespace std_erase_detail {
template <class T>
struct is_vector: std::false_type { };
#ifndef __cpp_lib_erase_if
template <class ...T>
struct is_vector<std::vector<T...>>: std::true_type { };
template <class ...T>
struct is_vector<std::deque<T...>>: std::true_type { };
template <class ...T>
struct is_vector<std::basic_string<T...>>: std::true_type { };
#endif // __cpp_lib_erase_if
template <class T>
struct is_list: std::false_type { };
#ifndef __cpp_lib_erase_if
template <class ...T>
struct is_list<std::list<T...>>: std::true_type { };
template <class ...T>
struct is_list<std::forward_list<T...>>: std::true_type { };
#endif // __cpp_lib_erase_if
template <class T>
struct is_map: std::false_type { };
#ifndef __cpp_lib_erase_if
template <class ...T>
struct is_map<std::map<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::multimap<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::set<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::multiset<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::unordered_map<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::unordered_multimap<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::unordered_set<T...>>: std::true_type { };
template <class ...T>
struct is_map<std::unordered_multiset<T...>>: std::true_type { };
#endif // __cpp_lib_erase_if
} // namespace std_erase_detail
namespace std {
template <class C, class U, std::enable_if_t<std_erase_detail::is_vector<C>::value, std::nullptr_t> = nullptr>
auto erase(C &c, const U &val) {
return c.erase(std::remove(std::begin(c), std::end(c), val), std::end(c));
}
template <class C, class Pred, std::enable_if_t<std_erase_detail::is_vector<C>::value, std::nullptr_t> = nullptr>
auto erase_if(C &c, const Pred &pred) {
return c.erase(std::remove_if(std::begin(c), std::end(c), pred), std::end(c));
}
template <class C, class U, std::enable_if_t<std_erase_detail::is_list<C>::value, std::nullptr_t> = nullptr>
auto erase(C &c, const U &val) {
return c.remove(val);
}
template <class C, class Pred, std::enable_if_t<std_erase_detail::is_list<C>::value, std::nullptr_t> = nullptr>
auto erase_if(C &c, const Pred &pred) {
return c.remove_if(pred);
}
template <class C, class Pred, std::enable_if_t<std_erase_detail::is_map<C>::value, std::nullptr_t> = nullptr>
auto erase_if(C &c, const Pred &pred) {
auto count = 0;
for (auto i = std::begin(c), last = std::end(c); i != last;) {
if (pred(*i)) {
i = c.erase(i);
++count;
} else {
++i;
}
}
return count;
}
} // namespace std
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment