Add td::remove.
GitOrigin-RevId: 410df2c90132c9056d71f5fabe69607891b295c9
This commit is contained in:
parent
31e8975be5
commit
c69beaf037
@ -53,10 +53,10 @@ string implode(const vector<string> &v, char delimiter = ' ');
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
template <typename V>
|
||||
struct transform_helper {
|
||||
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;
|
||||
result.reserve(v.size());
|
||||
for (auto &x : v) {
|
||||
@ -66,7 +66,7 @@ struct transform_helper {
|
||||
}
|
||||
|
||||
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;
|
||||
result.reserve(v.size());
|
||||
for (auto &x : v) {
|
||||
@ -78,13 +78,13 @@ struct transform_helper {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T, class Func>
|
||||
auto transform(T &&v, const Func &f) {
|
||||
return detail::transform_helper<std::decay_t<T>>().transform(std::forward<T>(v), f);
|
||||
template <class V, class Func>
|
||||
auto transform(V &&v, const Func &f) {
|
||||
return detail::transform_helper<std::decay_t<V>>().transform(std::forward<V>(v), f);
|
||||
}
|
||||
|
||||
template <class T, class Func>
|
||||
void remove_if(T &v, const Func &f) {
|
||||
template <class V, class Func>
|
||||
void remove_if(V &v, const Func &f) {
|
||||
size_t i = 0;
|
||||
while (i != v.size() && !f(v[i])) {
|
||||
i++;
|
||||
@ -103,9 +103,29 @@ void remove_if(T &v, const Func &f) {
|
||||
}
|
||||
|
||||
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) {
|
||||
if (x == elem) {
|
||||
if (x == value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -268,6 +268,31 @@ TEST(Misc, remove_if) {
|
||||
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) {
|
||||
td::vector<int> v{1, 3, 5, 7, 4, 2};
|
||||
for (int i = -10; i < 20; i++) {
|
||||
|
Reference in New Issue
Block a user