diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 435ec58e0..52ef4b794 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -210,7 +210,7 @@ pollOption text:string voter_count:int32 vote_percentage:int32 is_chosen:Bool is //@minithumbnail Animation minithumbnail; may be null @thumbnail Animation thumbnail; may be null @animation File containing the animation animation duration:int32 width:int32 height:int32 file_name:string mime_type:string minithumbnail:minithumbnail thumbnail:photoSize animation:file = Animation; -//@description Describes an audio file. Audio is usually in MP3 format @duration Duration of the audio, in seconds; as defined by the sender @title Title of the audio; as defined by the sender @performer Performer of the audio; as defined by the sender +//@description Describes an audio file. Audio is usually in MP3 or M4A format @duration Duration of the audio, in seconds; as defined by the sender @title Title of the audio; as defined by the sender @performer Performer of the audio; as defined by the sender //@file_name Original name of the file; as defined by the sender @mime_type The MIME type of the file; as defined by the sender @album_cover_minithumbnail The minithumbnail of the album cover; may be null @album_cover_thumbnail The thumbnail of the album cover; as defined by the sender. The full size thumbnail should be extracted from the downloaded file; may be null @audio File containing the audio audio duration:int32 title:string performer:string file_name:string mime_type:string album_cover_minithumbnail:minithumbnail album_cover_thumbnail:photoSize audio:file = Audio; diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 19688b31a..fb903ebf4 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -1001,8 +1001,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour VLOG(notifications) << "Have " << as_notification_update(update.get()); } - updates.erase(std::remove_if(updates.begin(), updates.end(), [](auto &update) { return update == nullptr; }), - updates.end()); + td::remove_if(updates, [](auto &update) { return update == nullptr; }); // if a notification was added, then deleted and then re-added we need to keep // first addition, because it can be with sound, @@ -1034,10 +1033,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour notification_id = 0; } } - update_ptr->removed_notification_ids_.erase( - std::remove_if(update_ptr->removed_notification_ids_.begin(), update_ptr->removed_notification_ids_.end(), - [](auto ¬ification_id) { return notification_id == 0; }), - update_ptr->removed_notification_ids_.end()); + td::remove_if(update_ptr->removed_notification_ids_, [](auto ¬ification_id) { return notification_id == 0; }); } else { CHECK(update->get_id() == td_api::updateNotification::ID); auto update_ptr = static_cast(update.get()); @@ -1127,10 +1123,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour // it is a first addition/edit of needed notification first_add_notification_pos[notification_id] = cur_pos; } - update_ptr->added_notifications_.erase( - std::remove_if(update_ptr->added_notifications_.begin(), update_ptr->added_notifications_.end(), - [](auto ¬ification) { return notification == nullptr; }), - update_ptr->added_notifications_.end()); + td::remove_if(update_ptr->added_notifications_, [](auto ¬ification) { return notification == nullptr; }); if (update_ptr->added_notifications_.empty() && !update_ptr->is_silent_) { update_ptr->is_silent_ = true; is_changed = true; @@ -1169,10 +1162,8 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour // we need to keep the deletion, because otherwise we will have 2 consequent additions } - update_ptr->removed_notification_ids_.erase( - std::remove_if(update_ptr->removed_notification_ids_.begin(), update_ptr->removed_notification_ids_.end(), - [](auto ¬ification_id) { return notification_id == 0; }), - update_ptr->removed_notification_ids_.end()); + td::remove_if(update_ptr->removed_notification_ids_, + [](auto ¬ification_id) { return notification_id == 0; }); if (update_ptr->removed_notification_ids_.empty() && update_ptr->added_notifications_.empty()) { for (size_t i = cur_pos - 1; i > 0; i--) { @@ -1263,8 +1254,7 @@ void NotificationManager::flush_pending_updates(int32 group_id, const char *sour CHECK(old_size == update_ptr->removed_notification_ids_.size()); } - updates.erase(std::remove_if(updates.begin(), updates.end(), [](auto &update) { return update == nullptr; }), - updates.end()); + td::remove_if(updates, [](auto &update) { return update == nullptr; }); if (updates.empty()) { VLOG(notifications) << "There are no updates to send in " << NotificationGroupId(group_id); break; @@ -1776,12 +1766,9 @@ void NotificationManager::remove_added_notifications_from_pending_updates( if (update->get_id() == td_api::updateNotificationGroup::ID) { auto update_ptr = static_cast(update.get()); if (!removed_notification_ids.empty() && !update_ptr->removed_notification_ids_.empty()) { - update_ptr->removed_notification_ids_.erase( - std::remove_if(update_ptr->removed_notification_ids_.begin(), update_ptr->removed_notification_ids_.end(), - [&removed_notification_ids](auto ¬ification_id) { - return removed_notification_ids.count(notification_id) == 1; - }), - update_ptr->removed_notification_ids_.end()); + td::remove_if(update_ptr->removed_notification_ids_, [&removed_notification_ids](auto ¬ification_id) { + return removed_notification_ids.count(notification_id) == 1; + }); } for (auto ¬ification : update_ptr->added_notifications_) { if (is_removed(notification)) { @@ -1790,10 +1777,7 @@ void NotificationManager::remove_added_notifications_from_pending_updates( notification = nullptr; } } - update_ptr->added_notifications_.erase( - std::remove_if(update_ptr->added_notifications_.begin(), update_ptr->added_notifications_.end(), - [](auto ¬ification) { return notification == nullptr; }), - update_ptr->added_notifications_.end()); + td::remove_if(update_ptr->added_notifications_, [](auto ¬ification) { return notification == nullptr; }); } else { CHECK(update->get_id() == td_api::updateNotification::ID); auto update_ptr = static_cast(update.get()); diff --git a/tdutils/td/utils/misc.h b/tdutils/td/utils/misc.h index 50ac0a456..fb1d89ce5 100644 --- a/tdutils/td/utils/misc.h +++ b/tdutils/td/utils/misc.h @@ -83,6 +83,25 @@ auto transform(T &&v, const Func &f) { return detail::transform_helper>().transform(std::forward(v), f); } +template +void remove_if(vector &v, const Func &f) { + size_t i = 0; + while (i != v.size() && !f(v[i])) { + i++; + } + if (i == v.size()) { + return; + } + + size_t j = i; + while (++i != v.size()) { + if (!f(v[i])) { + v[j++] = std::move(v[i]); + } + } + v.erase(v.begin() + j, v.end()); +} + template void reset_to_empty(T &value) { using std::swap; diff --git a/tdutils/test/misc.cpp b/tdutils/test/misc.cpp index 69ee77e18..cd10b3962 100644 --- a/tdutils/test/misc.cpp +++ b/tdutils/test/misc.cpp @@ -209,6 +209,65 @@ TEST(Misc, base64) { "Ojo7ISUiOw=="); } +template +static void test_remove_if(vector v, const T &func, vector expected) { + remove_if(v, func); + if (expected != v) { + LOG(FATAL) << "Receive " << v << ", expected " << expected << " in remove_if"; + } +} + +TEST(Misc, remove_if) { + auto odd = [](int x) { + return x % 2 == 1; + }; + auto even = [](int x) { + return x % 2 == 0; + }; + auto all = [](int x) { + return true; + }; + auto none = [](int x) { + return false; + }; + + vector v{1, 2, 3, 4, 5, 6}; + test_remove_if(v, odd, {2, 4, 6}); + test_remove_if(v, even, {1, 3, 5}); + test_remove_if(v, all, {}); + test_remove_if(v, none, v); + + v = vector{1, 3, 5, 2, 4, 6}; + test_remove_if(v, odd, {2, 4, 6}); + test_remove_if(v, even, {1, 3, 5}); + test_remove_if(v, all, {}); + test_remove_if(v, none, v); + + v.clear(); + test_remove_if(v, odd, v); + test_remove_if(v, even, v); + test_remove_if(v, all, v); + test_remove_if(v, none, v); + + v.push_back(-1); + test_remove_if(v, odd, v); + test_remove_if(v, even, v); + test_remove_if(v, all, {}); + test_remove_if(v, none, v); + + v[0] = 1; + test_remove_if(v, odd, {}); + test_remove_if(v, even, v); + test_remove_if(v, all, {}); + test_remove_if(v, none, v); + + v[0] = 2; + test_remove_if(v, odd, v); + test_remove_if(v, even, {}); + test_remove_if(v, all, {}); + test_remove_if(v, none, v); +} + TEST(Misc, to_integer) { ASSERT_EQ(to_integer("-1234567"), -1234567); ASSERT_EQ(to_integer("-1234567"), -1234567);