Allow empty arg list in rpl next/error handlers.

This commit is contained in:
John Preston 2017-09-27 21:29:13 +03:00
parent 21b1ba1f88
commit 5cc7cb1d85
21 changed files with 78 additions and 47 deletions

View File

@ -288,7 +288,7 @@ void EditPrivacyBox::createWidgets() {
auto createExceptionLink = [this](Exception exception) {
exceptionLink(exception).create(this, object_ptr<Ui::LinkButton>(this, exceptionLinkText(exception)), exceptionLinkMargins());
exceptionLink(exception)->heightValue()
| rpl::start_with_next([this](int) {
| rpl::start_with_next([this] {
resizeToWidth(width());
}, lifetime());
exceptionLink(exception)->entity()->setClickedCallback([this, exception] { editExceptionUsers(exception); });

View File

@ -129,7 +129,7 @@ void NotificationsBox::prepare() {
_countSlider->setActiveSectionFast(_oldCount - 1);
_countSlider->sectionActivated()
| rpl::start_with_next(
[this](int) { countChanged(); },
[this] { countChanged(); },
lifetime());
setMouseTracking(true);

View File

@ -52,7 +52,7 @@ void PeerListBox::createMultiSelect() {
_select.create(this, std::move(entity));
_select->heightValue()
| rpl::start_with_next(
[this](int) { updateScrollSkips(); },
[this] { updateScrollSkips(); },
lifetime());
_select->entity()->setSubmittedCallback([this](bool chtrlShiftEnter) { content()->submitted(); });
_select->entity()->setQueryChangedCallback([this](const QString &query) { searchQueryChanged(query); });

View File

@ -246,7 +246,7 @@ void StickersBox::prepare() {
setNoContentMargin(true);
_tabs->sectionActivated()
| rpl::start_with_next(
[this](int) { switchTab(); },
[this] { switchTab(); },
lifetime());
refreshTabs();
}

View File

@ -63,7 +63,7 @@ TabbedPanel::TabbedPanel(
}
});
_selector->showRequests()
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->showFromSelector();
}, lifetime());

View File

@ -609,7 +609,7 @@ void TabbedSelector::createTabsSlider() {
_tabsSlider->setActiveSectionFast(static_cast<int>(_currentTabType));
_tabsSlider->sectionActivated()
| rpl::start_with_next(
[this](int) { switchTab(); },
[this] { switchTab(); },
lifetime());
_tabsSlider->resizeToWidth(width());

View File

@ -81,7 +81,7 @@ object_ptr<TopBar> LayerWrap::createTopBar() {
result.data(),
st::infoLayerTopBarClose));
close->clicks()
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
_controller->hideSpecialLayer();
}, close->lifetime());
result->setTitle(TitleValue(

View File

@ -94,7 +94,7 @@ object_ptr<TopBar> NarrowWrap::createTopBar() {
st::infoLayerTopBar);
result->enableBackButton(true);
result->backRequest()
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->controller()->showBackFromStack();
}, result->lifetime());
result->setTitle(TitleValue(

View File

@ -58,7 +58,7 @@ void TopBar::pushButton(object_ptr<Ui::RpWidget> button) {
auto weak = Ui::AttachParentChild(this, button);
_buttons.push_back(std::move(button));
weak->widthValue()
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->updateControlsGeometry(this->width());
}, _lifetime);
}

View File

@ -52,7 +52,7 @@ Button *Button::toggleOn(rpl::producer<bool> &&toggled) {
false,
[this] { rtlupdate(toggleRect()); });
clicks()
| rpl::start_with_next([this](auto) {
| rpl::start_with_next([this] {
_toggle->setCheckedAnimated(!_toggle->checked());
}, lifetime());
std::move(toggled)

View File

@ -254,16 +254,16 @@ void Cover::initViewers() {
using Flag = Notify::PeerUpdate::Flag;
PeerUpdateValue(_peer, Flag::PhotoChanged)
| rpl::start_with_next(
[this](auto&&) { this->refreshUserpicLink(); },
[this] { this->refreshUserpicLink(); },
lifetime());
PeerUpdateValue(_peer, Flag::NameChanged)
| rpl::start_with_next(
[this](auto&&) { this->refreshNameText(); },
[this] { this->refreshNameText(); },
lifetime());
PeerUpdateValue(_peer,
Flag::UserOnlineChanged | Flag::MembersChanged)
| rpl::start_with_next(
[this](auto&&) { this->refreshStatusText(); },
[this] { this->refreshStatusText(); },
lifetime());
}

View File

@ -44,7 +44,7 @@ FloatingIcon::FloatingIcon(
setAttribute(Qt::WA_TransparentForMouseEvents);
parent->widthValue()
| rpl::start_with_next(
[this](auto&&) { moveToLeft(0, 0); },
[this] { moveToLeft(0, 0); },
lifetime());
}

View File

@ -203,7 +203,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupMuteToggle(
result->toggleOn(
NotificationsEnabledValue(_peer)
)->clicks()
| rpl::start_with_next([this](auto) {
| rpl::start_with_next([this] {
App::main()->updateNotifySetting(
_peer,
_peer->isMuted()
@ -239,7 +239,7 @@ void InnerWidget::setupUserButtons(
_controller->historyPeer.value()
| rpl::map($1 != user)
)->entity()->clicks()
| rpl::start_with_next([this, user](auto&&) {
| rpl::start_with_next([this, user] {
_controller->showPeerHistory(
user,
Ui::ShowWay::Forward);
@ -250,7 +250,7 @@ void InnerWidget::setupUserButtons(
)->toggleOn(
CanAddContactValue(user)
)->entity()->clicks()
| rpl::start_with_next([user](auto&&) {
| rpl::start_with_next([user] {
auto firstName = user->firstName;
auto lastName = user->lastName;
auto phone = user->phone().isEmpty()
@ -310,7 +310,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
return phrase(lt_count, count);
}
)->entity()->clicks()
| rpl::start_with_next([peer = _peer, type](auto&&) {
| rpl::start_with_next([peer = _peer, type] {
SharedMediaShowOverview(type, App::history(peer));
}, content->lifetime());
};
@ -321,7 +321,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
return lng_profile_common_groups(lt_count, count);
}
)->entity()->clicks()
| rpl::start_with_next([peer = _peer](auto&&) {
| rpl::start_with_next([peer = _peer] {
App::main()->showSection(
::Profile::CommonGroups::SectionMemento(
peer->asUser()),
@ -389,7 +389,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupUserActions(
)->toggleOn(
std::move(toggleOn)
)->entity()->clicks()
| rpl::start_with_next([callback = std::move(callback)](auto&&) {
| rpl::start_with_next([callback = std::move(callback)] {
callback();
}, result->lifetime());
};
@ -432,7 +432,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupUserActions(
st::infoBlockButtonSkip));
auto text = PeerUpdateValue(user, Notify::PeerUpdate::Flag::UserIsBlocked)
| rpl::map([user](auto&&) -> rpl::producer<QString> {
| rpl::map([user]() -> rpl::producer<QString> {
switch (user->blockStatus()) {
case UserData::BlockStatus::Blocked:
return Lang::Viewer(lng_profile_unblock_user);

View File

@ -118,7 +118,7 @@ void Members::setupButtons() {
}, _addMember->lifetime());
_addMember->showOn(rpl::duplicate(addMemberShown));
_addMember->clicks() // TODO throttle(ripple duration)
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->addMember();
}, _addMember->lifetime());
@ -128,18 +128,18 @@ void Members::setupButtons() {
| rpl::start_spawning(lifetime());
_search->showOn(rpl::duplicate(searchShown));
_search->clicks()
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->showSearch();
}, _search->lifetime());
_cancelSearch->clicks()
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->cancelSearch();
}, _cancelSearch->lifetime());
rpl::combine(
std::move(addMemberShown),
std::move(searchShown))
| rpl::start_with_next([this](auto&&) {
| rpl::start_with_next([this] {
this->resizeToWidth(width());
}, lifetime());

View File

@ -68,7 +68,7 @@ rpl::producer<TextWithEntities> PhoneValue(
return PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserPhoneChanged)
| rpl::map([user](auto&&) {
| rpl::map([user] {
return App::formatPhone(user->phone());
})
| WithEmptyEntities();
@ -79,7 +79,7 @@ rpl::producer<TextWithEntities> BioValue(
return PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::AboutChanged)
| rpl::map([user](auto&&) { return user->about(); })
| rpl::map([user] { return user->about(); })
| WithEmptyEntities();
}
@ -88,7 +88,7 @@ rpl::producer<QString> PlainUsernameViewer(
return PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::UsernameChanged)
| rpl::map([peer](auto&&) {
| rpl::map([peer] {
return peer->userName();
});
}
@ -110,7 +110,7 @@ rpl::producer<TextWithEntities> AboutValue(
return PeerUpdateValue(
channel,
Notify::PeerUpdate::Flag::AboutChanged)
| rpl::map([channel](auto&&) { return channel->about(); })
| rpl::map([channel] { return channel->about(); })
| WithEmptyEntities();
}
return rpl::single(TextWithEntities{});
@ -132,7 +132,7 @@ rpl::producer<bool> NotificationsEnabledValue(
return PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::NotificationsEnabled)
| rpl::map([peer](auto&&) { return !peer->isMuted(); });
| rpl::map([peer] { return !peer->isMuted(); });
}
rpl::producer<bool> IsContactValue(
@ -140,7 +140,7 @@ rpl::producer<bool> IsContactValue(
return PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserIsContact)
| rpl::map([user](auto&&) { return user->isContact(); });
| rpl::map([user] { return user->isContact(); });
}
rpl::producer<bool> CanShareContactValue(
@ -148,7 +148,7 @@ rpl::producer<bool> CanShareContactValue(
return PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserCanShareContact)
| rpl::map([user](auto&&) {
| rpl::map([user] {
return user->canShareThisContact();
});
}
@ -168,7 +168,7 @@ rpl::producer<int> MembersCountValue(
return PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::MembersChanged)
| rpl::map([chat](auto&&) {
| rpl::map([chat] {
return chat->amIn()
? qMax(chat->count, chat->participants.size())
: 0;
@ -177,7 +177,7 @@ rpl::producer<int> MembersCountValue(
return PeerUpdateValue(
peer,
Notify::PeerUpdate::Flag::MembersChanged)
| rpl::map([channel](auto &&) {
| rpl::map([channel] {
auto canViewCount = channel->canViewMembers()
|| !channel->isMegagroup();
return canViewCount
@ -215,7 +215,7 @@ rpl::producer<int> CommonGroupsCountValue(
return PeerUpdateValue(
user,
Notify::PeerUpdate::Flag::UserCommonChatsChanged)
| rpl::map([user](auto&&) {
| rpl::map([user] {
return user->commonChatsCount();
});
}
@ -226,14 +226,14 @@ rpl::producer<bool> CanAddMemberValue(
return PeerUpdateValue(
chat,
Notify::PeerUpdate::Flag::ChatCanEdit)
| rpl::map([chat](auto&&) {
| rpl::map([chat] {
return chat->canEdit();
});
} else if (auto channel = peer->asChannel()) {
return PeerUpdateValue(
channel,
Notify::PeerUpdate::Flag::ChannelRightsChanged)
| rpl::map([channel](auto&&) {
| rpl::map([channel] {
return channel->canAddMembers();
});
}

View File

@ -504,7 +504,7 @@ rpl::producer<QString> Viewer(LangKey key) {
rpl::single(Current().getValue(key))
| then(
base::ObservableViewer(Current().updated())
| rpl::map([=](auto&&) {
| rpl::map([=] {
return Current().getValue(key);
}));
}

View File

@ -1847,7 +1847,7 @@ void MainWidget::createPlayer() {
_player.create(this);
_player->heightValue()
| rpl::start_with_next(
[this](int) { playerHeightUpdated(); },
[this] { playerHeightUpdated(); },
lifetime());
_player->entity()->setCloseCallback([this] { closeBothPlayers(); });
_playerVolume.create(this);

View File

@ -91,31 +91,62 @@ struct is_callable<Method>
template <typename Method, typename Arg>
struct is_callable<Method, Arg>
: std::bool_constant<
is_callable_plain_v<Method, Arg>
|| is_callable_tuple_v<Method, Arg>> {
is_callable_plain_v<Method, Arg> ||
is_callable_tuple_v<Method, Arg> ||
is_callable_plain_v<Method>> {
};
template <typename Method, typename ...Args>
constexpr bool is_callable_v = is_callable<Method, Args...>::value;
enum class CallableArgTag {
Plain,
Tuple,
Empty,
};
template <CallableArgTag Arg>
using callable_arg_tag = std::integral_constant<CallableArgTag, Arg>;
template <typename Method, typename Arg>
inline decltype(auto) callable_helper(Method &&method, Arg &&arg, std::true_type) {
inline decltype(auto) callable_helper(
Method &&method,
Arg &&arg,
callable_arg_tag<CallableArgTag::Plain>) {
return std::forward<Method>(method)(std::forward<Arg>(arg));
}
template <typename Method, typename Arg>
inline decltype(auto) callable_helper(Method &&method, Arg &&arg, std::false_type) {
inline decltype(auto) callable_helper(
Method &&method,
Arg &&arg,
callable_arg_tag<CallableArgTag::Tuple>) {
return std::apply(
std::forward<Method>(method),
std::forward<Arg>(arg));
}
template <typename Method, typename Arg>
inline decltype(auto) callable_helper(
Method &&method,
Arg &&,
callable_arg_tag<CallableArgTag::Empty>) {
return std::forward<Method>(method)();
}
template <typename Method, typename Arg>
inline decltype(auto) callable_invoke(Method &&method, Arg &&arg) {
// #TODO if constexpr
constexpr auto kTag = is_callable_plain_v<Method, Arg>
? CallableArgTag::Plain
: is_callable_tuple_v<Method, Arg>
? CallableArgTag::Tuple
: is_callable_v<Method>
? CallableArgTag::Empty
: throw "Bad callable_invoke instance.";
return callable_helper(
std::forward<Method>(method),
std::forward<Arg>(arg),
is_callable_plain<Method, Arg>());
callable_arg_tag<kTag>());
}
template <typename Method, typename Arg>

View File

@ -62,7 +62,7 @@ void ScaleWidget::createControls() {
_scale->setActiveSectionFast(cEvalScale(cConfigScale()) - 1);
_scale->sectionActivated()
| rpl::start_with_next(
[this](int) { scaleChanged(); },
[this] { scaleChanged(); },
lifetime());
}

View File

@ -115,7 +115,7 @@ RpWidget *VerticalLayout::addChild(
width() - margins.left() - margins.right(),
height() - margins.top() - margins.bottom());
weak->heightValue()
| rpl::start_with_next_done([this, weak](int) {
| rpl::start_with_next_done([this, weak] {
childHeightUpdated(weak);
}, [this, weak] {
removeChild(weak);

View File

@ -119,7 +119,7 @@ TopBarWidget::TopBarWidget(
Auth().data().thirdSectionInfoEnabledValue(),
Auth().data().tabbedReplacedWithInfoValue())
| rpl::start_with_next(
[this](auto&&) { updateInfoToggleActive(); },
[this] { updateInfoToggleActive(); },
lifetime());
setCursor(style::cur_pointer);