mirror of https://github.com/procxx/kepka.git
Support structured bindings in base::flat_map.
This commit is contained in:
parent
d6b4448d3c
commit
8a3615281c
|
@ -662,7 +662,7 @@ namespace App {
|
|||
bool found = !h || !h->lastKeyboardFrom;
|
||||
auto botStatus = -1;
|
||||
for (auto i = chat->participants.begin(); i != chat->participants.end();) {
|
||||
auto [user, version] = *i;
|
||||
const auto [user, version] = *i;
|
||||
if (version < pversion) {
|
||||
i = chat->participants.erase(i);
|
||||
} else {
|
||||
|
@ -761,7 +761,7 @@ namespace App {
|
|||
}
|
||||
if (chat->botStatus > 0 && user->botInfo) {
|
||||
int32 botStatus = -1;
|
||||
for (auto [participant, v] : chat->participants) {
|
||||
for (const auto [participant, v] : chat->participants) {
|
||||
if (participant->botInfo) {
|
||||
if (true || botStatus > 0/* || !participant->botInfo->readsAllHistory*/) {
|
||||
botStatus = 2;
|
||||
|
|
|
@ -76,6 +76,7 @@ struct flat_multi_map_pair_type {
|
|||
|
||||
const Key first;
|
||||
Value second;
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
|
@ -316,6 +317,18 @@ public:
|
|||
}
|
||||
flat_multi_map &operator=(flat_multi_map &&other) = default;
|
||||
|
||||
template <
|
||||
typename Iterator,
|
||||
typename = typename std::iterator_traits<Iterator>::iterator_category>
|
||||
flat_multi_map(Iterator first, Iterator last)
|
||||
: _data(first, last) {
|
||||
std::sort(std::begin(impl()), std::end(impl()), compare());
|
||||
}
|
||||
|
||||
flat_multi_map(std::initializer_list<pair_type> iter)
|
||||
: flat_multi_map(iter.begin(), iter.end()) {
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return impl().size();
|
||||
}
|
||||
|
@ -614,6 +627,20 @@ public:
|
|||
using reverse_iterator = typename parent::reverse_iterator;
|
||||
using const_reverse_iterator = typename parent::const_reverse_iterator;
|
||||
|
||||
flat_map() = default;
|
||||
|
||||
template <
|
||||
typename Iterator,
|
||||
typename = typename std::iterator_traits<Iterator>::iterator_category
|
||||
>
|
||||
flat_map(Iterator first, Iterator last) : parent(first, last) {
|
||||
finalize();
|
||||
}
|
||||
|
||||
flat_map(std::initializer_list<pair_type> iter) : parent(iter.begin(), iter.end()) {
|
||||
finalize();
|
||||
}
|
||||
|
||||
using parent::parent;
|
||||
using parent::size;
|
||||
using parent::empty;
|
||||
|
@ -732,6 +759,74 @@ public:
|
|||
return std::move(result);
|
||||
}
|
||||
|
||||
private:
|
||||
void finalize() {
|
||||
this->impl().erase(
|
||||
std::unique(
|
||||
std::begin(this->impl()),
|
||||
std::end(this->impl()),
|
||||
[&](auto &&a, auto &&b) {
|
||||
return !this->compare()(a, b);
|
||||
}
|
||||
),
|
||||
std::end(this->impl()));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
// Structured bindings support.
|
||||
namespace std {
|
||||
|
||||
template <typename Key, typename Value>
|
||||
class tuple_size<base::flat_multi_map_pair_type<Key, Value>>
|
||||
: public integral_constant<size_t, 2> {
|
||||
};
|
||||
|
||||
template <typename Key, typename Value>
|
||||
class tuple_element<0, base::flat_multi_map_pair_type<Key, Value>> {
|
||||
public:
|
||||
using type = const Key;
|
||||
};
|
||||
|
||||
template <typename Key, typename Value>
|
||||
class tuple_element<1, base::flat_multi_map_pair_type<Key, Value>> {
|
||||
public:
|
||||
using type = Value;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
// Structured bindings support.
|
||||
namespace base {
|
||||
namespace details {
|
||||
|
||||
template <std::size_t N, typename Key, typename Value>
|
||||
using flat_multi_map_pair_element = std::tuple_element_t<
|
||||
N,
|
||||
flat_multi_map_pair_type<Key, Value>>;
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <std::size_t N, typename Key, typename Value>
|
||||
auto get(base::flat_multi_map_pair_type<Key, Value> &value)
|
||||
-> details::flat_multi_map_pair_element<N, Key, Value> & {
|
||||
if constexpr (N == 0) {
|
||||
return value.first;
|
||||
} else {
|
||||
return value.second;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t N, typename Key, typename Value>
|
||||
auto get(const base::flat_multi_map_pair_type<Key, Value> &value)
|
||||
-> const details::flat_multi_map_pair_element<N, Key, Value> & {
|
||||
if constexpr (N == 0) {
|
||||
return value.first;
|
||||
} else {
|
||||
return value.second;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
|
|
@ -91,3 +91,31 @@ TEST_CASE("flat_maps custom comparator", "[flat_map]") {
|
|||
checkSorted();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("flat_maps structured bindings", "[flat_map]") {
|
||||
base::flat_map<int, std::unique_ptr<double>> v;
|
||||
v.emplace(0, std::make_unique<double>(0.));
|
||||
v.emplace(1, std::make_unique<double>(1.));
|
||||
|
||||
SECTION("structred binded range-based for loop") {
|
||||
for (const auto &[key, value] : v) {
|
||||
REQUIRE(key == int(std::round(*value)));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("non-const structured binded range-based for loop") {
|
||||
base::flat_map<int, int> second = {
|
||||
{ 1, 1 },
|
||||
{ 2, 2 },
|
||||
{ 2, 3 },
|
||||
{ 3, 3 },
|
||||
};
|
||||
REQUIRE(second.size() == 3);
|
||||
//for (auto [a, b] : second) { // #MSVC Bug, reported
|
||||
// REQUIRE(a == b);
|
||||
//}
|
||||
for (const auto [a, b] : second) {
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -656,7 +656,7 @@ void EditChatAdminsBoxController::rebuildRows() {
|
|||
admins.reserve(allAdmins ? _chat->participants.size() : _chat->admins.size());
|
||||
others.reserve(_chat->participants.size());
|
||||
|
||||
for (auto [user, version] : _chat->participants) {
|
||||
for (const auto [user, version] : _chat->participants) {
|
||||
if (user->id == peerFromUser(_chat->creator)) continue;
|
||||
if (_chat->admins.contains(user)) {
|
||||
admins.push_back(user);
|
||||
|
|
|
@ -765,7 +765,7 @@ void TopBarWidget::updateOnlineDisplay() {
|
|||
const auto self = Auth().user();
|
||||
auto online = 0;
|
||||
auto onlyMe = true;
|
||||
for (auto [user, v] : chat->participants) {
|
||||
for (const auto [user, v] : chat->participants) {
|
||||
if (user->onlineTill > now) {
|
||||
++online;
|
||||
if (onlyMe && user != self) onlyMe = false;
|
||||
|
@ -833,7 +833,7 @@ void TopBarWidget::updateOnlineDisplayTimer() {
|
|||
if (const auto user = _activeChat.peer()->asUser()) {
|
||||
handleUser(user);
|
||||
} else if (auto chat = _activeChat.peer()->asChat()) {
|
||||
for (auto [user, v] : chat->participants) {
|
||||
for (const auto [user, v] : chat->participants) {
|
||||
handleUser(user);
|
||||
}
|
||||
} else if (_activeChat.peer()->isChannel()) {
|
||||
|
|
|
@ -406,7 +406,7 @@ void GroupMembersWidget::fillChatMembers(ChatData *chat) {
|
|||
reserveItemsForSize(chat->participants.size());
|
||||
addUser(chat, Auth().user())->onlineForSort
|
||||
= std::numeric_limits<TimeId>::max();
|
||||
for (auto [user, v] : chat->participants) {
|
||||
for (const auto &[user, v] : chat->participants) {
|
||||
if (!user->isSelf()) {
|
||||
addUser(chat, user);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue