Add td::remove.

GitOrigin-RevId: 410df2c90132c9056d71f5fabe69607891b295c9
This commit is contained in:
levlam 2019-10-22 01:14:00 +03:00
parent 31e8975be5
commit c69beaf037
2 changed files with 55 additions and 10 deletions

View File

@ -53,10 +53,10 @@ string implode(const vector<string> &v, char delimiter = ' ');
namespace detail { namespace detail {
template <typename T> template <typename V>
struct transform_helper { struct transform_helper {
template <class Func> template <class Func>
auto transform(const T &v, const Func &f) { auto transform(const V &v, const Func &f) {
vector<decltype(f(*v.begin()))> result; vector<decltype(f(*v.begin()))> result;
result.reserve(v.size()); result.reserve(v.size());
for (auto &x : v) { for (auto &x : v) {
@ -66,7 +66,7 @@ struct transform_helper {
} }
template <class Func> template <class Func>
auto transform(T &&v, const Func &f) { auto transform(V &&v, const Func &f) {
vector<decltype(f(std::move(*v.begin())))> result; vector<decltype(f(std::move(*v.begin())))> result;
result.reserve(v.size()); result.reserve(v.size());
for (auto &x : v) { for (auto &x : v) {
@ -78,13 +78,13 @@ struct transform_helper {
} // namespace detail } // namespace detail
template <class T, class Func> template <class V, class Func>
auto transform(T &&v, const Func &f) { auto transform(V &&v, const Func &f) {
return detail::transform_helper<std::decay_t<T>>().transform(std::forward<T>(v), f); return detail::transform_helper<std::decay_t<V>>().transform(std::forward<V>(v), f);
} }
template <class T, class Func> template <class V, class Func>
void remove_if(T &v, const Func &f) { void remove_if(V &v, const Func &f) {
size_t i = 0; size_t i = 0;
while (i != v.size() && !f(v[i])) { while (i != v.size() && !f(v[i])) {
i++; i++;
@ -103,9 +103,29 @@ void remove_if(T &v, const Func &f) {
} }
template <class V, class T> template <class V, class T>
bool contains(const V &v, const T &elem) { bool remove(V &v, const T &value) {
size_t i = 0;
while (i != v.size() && v[i] != value) {
i++;
}
if (i == v.size()) {
return false;
}
size_t j = i;
while (++i != v.size()) {
if (v[i] != value) {
v[j++] = std::move(v[i]);
}
}
v.erase(v.begin() + j, v.end());
return true;
}
template <class V, class T>
bool contains(const V &v, const T &value) {
for (auto &x : v) { for (auto &x : v) {
if (x == elem) { if (x == value) {
return true; return true;
} }
} }

View File

@ -268,6 +268,31 @@ TEST(Misc, remove_if) {
test_remove_if(v, none, v); test_remove_if(v, none, v);
} }
static void test_remove(vector<int> v, int value, vector<int> expected) {
bool is_found = expected != v;
ASSERT_EQ(is_found, td::remove(v, value));
if (expected != v) {
LOG(FATAL) << "Receive " << v << ", expected " << expected << " in remove";
}
}
TEST(Misc, remove) {
vector<int> v{1, 2, 3, 4, 5, 6};
test_remove(v, 0, {1, 2, 3, 4, 5, 6});
test_remove(v, 1, {2, 3, 4, 5, 6});
test_remove(v, 2, {1, 3, 4, 5, 6});
test_remove(v, 3, {1, 2, 4, 5, 6});
test_remove(v, 4, {1, 2, 3, 5, 6});
test_remove(v, 5, {1, 2, 3, 4, 6});
test_remove(v, 6, {1, 2, 3, 4, 5});
test_remove(v, 7, {1, 2, 3, 4, 5, 6});
v.clear();
test_remove(v, -1, v);
test_remove(v, 0, v);
test_remove(v, 1, v);
}
TEST(Misc, contains) { TEST(Misc, contains) {
td::vector<int> v{1, 3, 5, 7, 4, 2}; td::vector<int> v{1, 3, 5, 7, 4, 2};
for (int i = -10; i < 20; i++) { for (int i = -10; i < 20; i++) {