diff --git a/.clang-format b/.clang-format index 6ce3c0d61..4e23f1d3a 100644 --- a/.clang-format +++ b/.clang-format @@ -3,17 +3,20 @@ Language: Cpp # BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: Align -AlignConsecutiveMacros: false -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None AlignEscapedNewlines: Left -AlignOperands: true +AlignOperands: Align AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllConstructorInitializersOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: true AllowShortFunctionsOnASingleLine: None # All AllowShortIfStatementsOnASingleLine: Never # WithoutElse AllowShortLambdasOnASingleLine: Inline # All @@ -24,10 +27,11 @@ AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BinPackParameters: true +BitFieldColonSpacing: Both BraceWrapping: AfterCaseLabel: false AfterClass: false - AfterControlStatement: false + AfterControlStatement: Never AfterEnum: false AfterFunction: false AfterNamespace: false @@ -37,12 +41,15 @@ BraceWrapping: AfterExternBlock: false BeforeCatch: false BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach +BreakBeforeConceptDeclarations: true BreakBeforeInheritanceComma: true # false BreakInheritanceList: BeforeComma # BeforeColon BreakBeforeTernaryOperators: true @@ -60,21 +67,30 @@ Cpp11BracedListStyle: true DeriveLineEnding: true DerivePointerAlignment: true DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: - Q_FOREACH_THIS_LIST_MUST_BE_NON_EMPTY IncludeBlocks: Preserve -#IndentCaseBlocks: false +IncludeCategories: + - Regex: '.*' + Priority: 0 +IndentAccessModifiers: false +IndentCaseBlocks: false IndentCaseLabels: true +IndentExternBlock: AfterExternBlock IndentGotoLabels: true IndentPPDirectives: None +IndentRequires: false IndentWidth: 2 IndentWrappedFunctionNames: false # InsertTrailingCommas: None # JavaScriptQuotes: Leave # JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 @@ -91,15 +107,22 @@ PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Right +PPIndentWidth: -1 +ReferenceAlignment: Pointer ReflowComments: false # true -SortIncludes: false # disabled, because we need case insensitive sort +ShortNamespaceLines: 0 # 1 +SortIncludes: CaseInsensitive # CaseSensitive +# SortJavaStaticImport: Before SortUsingDeclarations: false # true SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true @@ -109,10 +132,13 @@ SpaceBeforeSquareBrackets: false SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 -SpacesInAngles: false +SpacesInAngles: Never SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: 1 # -1 SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Auto diff --git a/SplitSource.php b/SplitSource.php index 853a9bec2..9ba0e74e7 100644 --- a/SplitSource.php +++ b/SplitSource.php @@ -219,7 +219,7 @@ function split_file($file, $chunks, $undo) { $new_content = $common.$namespace_begin.$f.$namespace_end; $std_methods = array(); - preg_match_all('/std::[a-z_0-9]*/', $new_content, $std_methods); + preg_match_all('/std::[a-z_0-9]*|td::unique(?!_)/', $new_content, $std_methods); $std_methods = array_unique($std_methods[0]); $needed_std_headers = array(); @@ -230,6 +230,7 @@ function split_file($file, $chunks, $undo) { 'std::uint32_t' => '', 'std::int32_t' => '', 'std::int64_t' => '', + 'td::unique' => 'algorithm', 'std::fill' => 'algorithm', 'std::find' => 'algorithm', 'std::max' => 'algorithm', diff --git a/memprof/memprof.cpp b/memprof/memprof.cpp index b33d11943..072838aba 100644 --- a/memprof/memprof.cpp +++ b/memprof/memprof.cpp @@ -45,9 +45,9 @@ extern void *__libc_stack_end; static void *get_bp() { void *bp; #if defined(__i386__) - __asm__ volatile("movl %%ebp, %[r]" : [ r ] "=r"(bp)); + __asm__ volatile("movl %%ebp, %[r]" : [r] "=r"(bp)); #elif defined(__x86_64__) - __asm__ volatile("movq %%rbp, %[r]" : [ r ] "=r"(bp)); + __asm__ volatile("movq %%rbp, %[r]" : [r] "=r"(bp)); #endif return bp; } diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index eb1a69961..cec3b32c0 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1079,6 +1079,7 @@ class ToggleSlowModeQuery final : public Td::ResultHandler { class ReportChannelSpamQuery final : public Td::ResultHandler { Promise promise_; ChannelId channel_id_; + DialogId sender_dialog_id_; public: explicit ReportChannelSpamQuery(Promise &&promise) : promise_(std::move(promise)) { @@ -1086,6 +1087,7 @@ class ReportChannelSpamQuery final : public Td::ResultHandler { void send(ChannelId channel_id, DialogId sender_dialog_id, const vector &message_ids) { channel_id_ = channel_id; + sender_dialog_id_ = sender_dialog_id; auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); CHECK(input_channel != nullptr); @@ -1110,7 +1112,9 @@ class ReportChannelSpamQuery final : public Td::ResultHandler { } void on_error(Status status) final { - // td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ReportChannelSpamQuery"); + if (sender_dialog_id_.get_type() != DialogType::Channel) { + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ReportChannelSpamQuery"); + } promise_.set_error(std::move(status)); } }; @@ -2127,14 +2131,16 @@ class EditChannelAdminQuery final : public Td::ResultHandler { class EditChannelBannedQuery final : public Td::ResultHandler { Promise promise_; ChannelId channel_id_; + DialogId participant_dialog_id_; public: explicit EditChannelBannedQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(ChannelId channel_id, tl_object_ptr &&input_peer, + void send(ChannelId channel_id, DialogId participant_dialog_id, tl_object_ptr &&input_peer, const DialogParticipantStatus &status) { channel_id_ = channel_id; + participant_dialog_id_ = participant_dialog_id; auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); CHECK(input_channel != nullptr); send_query(G()->net_query_creator().create(telegram_api::channels_editBanned( @@ -2154,7 +2160,9 @@ class EditChannelBannedQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "EditChannelBannedQuery"); + if (participant_dialog_id_.get_type() != DialogType::Channel) { + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "EditChannelBannedQuery"); + } promise_.set_error(std::move(status)); td_->updates_manager_->get_difference("EditChannelBannedQuery"); } @@ -2737,7 +2745,9 @@ class GetChannelParticipantQuery final : public Td::ResultHandler { return; } - // td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelParticipantQuery"); + if (participant_dialog_id_.get_type() != DialogType::Channel) { + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelParticipantQuery"); + } promise_.set_error(std::move(status)); } }; @@ -7573,7 +7583,8 @@ void ContactsManager::restrict_channel_participant(ChannelId channel_id, DialogI if (participant_dialog_id.get_type() == DialogType::User) { speculative_add_channel_user(channel_id, participant_dialog_id.get_user_id(), status, old_status); } - td_->create_handler(std::move(promise))->send(channel_id, std::move(input_peer), status); + td_->create_handler(std::move(promise)) + ->send(channel_id, participant_dialog_id, std::move(input_peer), status); } ChannelId ContactsManager::migrate_chat_to_megagroup(ChatId chat_id, Promise &promise) { diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index f11f9492c..a8d1da6c1 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2873,12 +2873,17 @@ class BlockFromRepliesQuery final : public Td::ResultHandler { class DeleteParticipantHistoryQuery final : public Td::ResultHandler { Promise promise_; + ChannelId channel_id_; + DialogId sender_dialog_id_; public: explicit DeleteParticipantHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { } void send(ChannelId channel_id, DialogId sender_dialog_id) { + channel_id_ = channel_id; + sender_dialog_id_ = sender_dialog_id; + auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return promise_.set_error(Status::Error(400, "Chat is not accessible")); @@ -2902,7 +2907,9 @@ class DeleteParticipantHistoryQuery final : public Td::ResultHandler { } void on_error(Status status) final { - // td_->contacts_manager_->on_get_channel_error(channel_id_, status, "DeleteParticipantHistoryQuery"); + if (sender_dialog_id_.get_type() != DialogType::Channel) { + td_->contacts_manager_->on_get_channel_error(channel_id_, status, "DeleteParticipantHistoryQuery"); + } promise_.set_error(std::move(status)); } }; @@ -12178,6 +12185,30 @@ void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 o return; } + if (online_member_count < 0) { + LOG(ERROR) << "Receive online_member_count = " << online_member_count << " in " << dialog_id; + online_member_count = 0; + } + + switch (dialog_id.get_type()) { + case DialogType::Chat: { + auto participant_count = td_->contacts_manager_->get_chat_participant_count(dialog_id.get_chat_id()); + if (online_member_count > participant_count) { + online_member_count = participant_count; + } + break; + } + case DialogType::Channel: { + auto participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id()); + if (participant_count != 0 && online_member_count > participant_count) { + online_member_count = participant_count; + } + break; + } + default: + break; + } + auto &info = dialog_online_member_counts_[dialog_id]; LOG(INFO) << "Change number of online members from " << info.online_member_count << " to " << online_member_count << " in " << dialog_id << " from " << source; diff --git a/td/telegram/Td.h b/td/telegram/Td.h index de38083c5..54ec37e2b 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -132,7 +132,7 @@ class Td final : public Actor { void set_is_bot_online(bool is_bot_online); template - ActorId create_net_actor(ArgsT &&... args) { + ActorId create_net_actor(ArgsT &&...args) { LOG_CHECK(close_flag_ < 1) << close_flag_ #if TD_CLANG || TD_GCC << ' ' << __PRETTY_FUNCTION__ @@ -243,7 +243,7 @@ class Td final : public Actor { }; template - std::shared_ptr create_handler(Args &&... args) { + std::shared_ptr create_handler(Args &&...args) { LOG_CHECK(close_flag_ < 2) << close_flag_ #if TD_CLANG || TD_GCC << ' ' << __PRETTY_FUNCTION__ diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 67f3cd722..0f0e674db 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -712,7 +712,7 @@ class CliClient final : public Actor { } template - static void get_args(string &args, FirstType &first_arg, SecondType &second_arg, Types &... other_args) { + static void get_args(string &args, FirstType &first_arg, SecondType &second_arg, Types &...other_args) { string arg; std::tie(arg, args) = split(args); get_args(arg, first_arg); diff --git a/td/tl/TlObject.h b/td/tl/TlObject.h index 61caa5e47..4bff624f4 100644 --- a/td/tl/TlObject.h +++ b/td/tl/TlObject.h @@ -199,7 +199,7 @@ using tl_object_ptr = tl::unique_ptr; * \return Wrapped pointer to the created TL-object. */ template -tl_object_ptr make_tl_object(Args &&... args) { +tl_object_ptr make_tl_object(Args &&...args) { return tl_object_ptr(new Type(std::forward(args)...)); } diff --git a/tdactor/td/actor/ConcurrentScheduler.h b/tdactor/td/actor/ConcurrentScheduler.h index e9b35fe7f..96bafc2e1 100644 --- a/tdactor/td/actor/ConcurrentScheduler.h +++ b/tdactor/td/actor/ConcurrentScheduler.h @@ -62,7 +62,7 @@ class ConcurrentScheduler final : private Scheduler::Callback { void finish(); template - ActorOwn create_actor_unsafe(int32 sched_id, Slice name, Args &&... args) { + ActorOwn create_actor_unsafe(int32 sched_id, Slice name, Args &&...args) { #if TD_THREAD_UNSUPPORTED || TD_EVENTFD_UNSUPPORTED sched_id = 0; #endif diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index fe0464e0a..580a3b8a6 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -404,7 +404,7 @@ template class CancellablePromise final : public PromiseT { public: template - CancellablePromise(CancellationToken cancellation_token, ArgsT &&... args) + CancellablePromise(CancellationToken cancellation_token, ArgsT &&...args) : PromiseT(std::forward(args)...), cancellation_token_(std::move(cancellation_token)) { } bool is_cancellable() const final { @@ -421,7 +421,7 @@ class CancellablePromise final : public PromiseT { template class JoinPromise final : public PromiseInterface { public: - explicit JoinPromise(ArgsT &&... arg) : promises_(std::forward(arg)...) { + explicit JoinPromise(ArgsT &&...arg) : promises_(std::forward(arg)...) { } void set_value(Unit &&) final { tuple_for_each(promises_, [](auto &promise) { promise.set_value(Unit()); }); @@ -438,7 +438,7 @@ class JoinPromise final : public PromiseInterface { class SendClosure { public: template - void operator()(ArgsT &&... args) const { + void operator()(ArgsT &&...args) const { send_closure(std::forward(args)...); } }; @@ -453,7 +453,7 @@ class SendClosure { //} template -auto promise_send_closure(ArgsT &&... args) { +auto promise_send_closure(ArgsT &&...args) { return [t = std::make_tuple(std::forward(args)...)](auto &&res) mutable { call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); }; @@ -679,7 +679,7 @@ class PromiseFuture { template FutureActor send_promise(ActorId actor_id, ResultT (ActorBT::*func)(PromiseActor &&, DestArgsT...), - ArgsT &&... args) { + ArgsT &&...args) { PromiseFuture pf; Scheduler::instance()->send_closure( std::move(actor_id), create_immediate_closure(func, pf.move_promise(), std::forward(args)...)); @@ -716,7 +716,7 @@ class PromiseCreator { } template - static Promise<> join(ArgsT &&... args) { + static Promise<> join(ArgsT &&...args) { return Promise<>(td::make_unique>(std::forward(args)...)); } diff --git a/tdactor/td/actor/impl/Actor-decl.h b/tdactor/td/actor/impl/Actor-decl.h index 99eccef42..97b0785df 100644 --- a/tdactor/td/actor/impl/Actor-decl.h +++ b/tdactor/td/actor/impl/Actor-decl.h @@ -90,10 +90,10 @@ class Actor : public ObserverBase { bool empty() const; template - auto self_closure(FuncT &&func, ArgsT &&... args); + auto self_closure(FuncT &&func, ArgsT &&...args); template - auto self_closure(SelfT *self, FuncT &&func, ArgsT &&... args); + auto self_closure(SelfT *self, FuncT &&func, ArgsT &&...args); template auto self_lambda(LambdaT &&lambda); diff --git a/tdactor/td/actor/impl/Actor.h b/tdactor/td/actor/impl/Actor.h index 4cf204ffe..94a07d240 100644 --- a/tdactor/td/actor/impl/Actor.h +++ b/tdactor/td/actor/impl/Actor.h @@ -146,12 +146,12 @@ ActorShared Actor::actor_shared(SelfT *self, uint64 id) { } template -auto Actor::self_closure(FuncT &&func, ArgsT &&... args) { +auto Actor::self_closure(FuncT &&func, ArgsT &&...args) { return self_closure(this, std::forward(func), std::forward(args)...); } template -auto Actor::self_closure(SelfT *self, FuncT &&func, ArgsT &&... args) { +auto Actor::self_closure(SelfT *self, FuncT &&func, ArgsT &&...args) { return EventCreator::closure(actor_id(self), std::forward(func), std::forward(args)...); } diff --git a/tdactor/td/actor/impl/Event.h b/tdactor/td/actor/impl/Event.h index bd4c421fe..5eaa27aa4 100644 --- a/tdactor/td/actor/impl/Event.h +++ b/tdactor/td/actor/impl/Event.h @@ -66,7 +66,7 @@ class ClosureEvent final : public CustomEvent { return new ClosureEvent(closure_.clone()); } template - explicit ClosureEvent(ArgsT &&... args) : closure_(std::forward(args)...) { + explicit ClosureEvent(ArgsT &&...args) : closure_(std::forward(args)...) { } void start_migrate(int32 sched_id) final { @@ -152,7 +152,7 @@ class Event { new ClosureEvent(std::forward(closure))); } template - static Event delayed_closure(ArgsT &&... args) { + static Event delayed_closure(ArgsT &&...args) { using DelayedClosureT = decltype(create_delayed_closure(std::forward(args)...)); return custom(new ClosureEvent(std::forward(args)...)); } diff --git a/tdactor/td/actor/impl/EventFull-decl.h b/tdactor/td/actor/impl/EventFull-decl.h index a3d41c3a0..815ee53ff 100644 --- a/tdactor/td/actor/impl/EventFull-decl.h +++ b/tdactor/td/actor/impl/EventFull-decl.h @@ -56,7 +56,7 @@ class EventFull { class EventCreator { public: template - static EventFull closure(ActorIdT &&actor_id, FunctionT function, ArgsT &&... args) { + static EventFull closure(ActorIdT &&actor_id, FunctionT function, ArgsT &&...args) { using ActorT = typename std::decay_t::ActorT; using FunctionClassT = member_function_class_t; static_assert(std::is_base_of::value, "unsafe send_closure"); diff --git a/tdactor/td/actor/impl/Scheduler-decl.h b/tdactor/td/actor/impl/Scheduler-decl.h index 96e37d078..26137e807 100644 --- a/tdactor/td/actor/impl/Scheduler-decl.h +++ b/tdactor/td/actor/impl/Scheduler-decl.h @@ -84,9 +84,9 @@ class Scheduler { int32 sched_count() const; template - TD_WARN_UNUSED_RESULT ActorOwn create_actor(Slice name, Args &&... args); + TD_WARN_UNUSED_RESULT ActorOwn create_actor(Slice name, Args &&...args); template - TD_WARN_UNUSED_RESULT ActorOwn create_actor_on_scheduler(Slice name, int32 sched_id, Args &&... args); + TD_WARN_UNUSED_RESULT ActorOwn create_actor_on_scheduler(Slice name, int32 sched_id, Args &&...args); template TD_WARN_UNUSED_RESULT ActorOwn register_actor(Slice name, ActorT *actor_ptr, int32 sched_id = -1); template @@ -244,9 +244,9 @@ class Scheduler { /*** Interface to current scheduler ***/ template -TD_WARN_UNUSED_RESULT ActorOwn create_actor(Slice name, Args &&... args); +TD_WARN_UNUSED_RESULT ActorOwn create_actor(Slice name, Args &&...args); template -TD_WARN_UNUSED_RESULT ActorOwn create_actor_on_scheduler(Slice name, int32 sched_id, Args &&... args); +TD_WARN_UNUSED_RESULT ActorOwn create_actor_on_scheduler(Slice name, int32 sched_id, Args &&...args); template TD_WARN_UNUSED_RESULT ActorOwn register_actor(Slice name, ActorT *actor_ptr, int32 sched_id = -1); template @@ -256,7 +256,7 @@ template TD_WARN_UNUSED_RESULT ActorOwn register_existing_actor(unique_ptr actor_ptr); template -void send_closure(ActorIdT &&actor_id, FunctionT function, ArgsT &&... args) { +void send_closure(ActorIdT &&actor_id, FunctionT function, ArgsT &&...args) { using ActorT = typename std::decay_t::ActorT; using FunctionClassT = member_function_class_t; static_assert(std::is_base_of::value, "unsafe send_closure"); @@ -266,7 +266,7 @@ void send_closure(ActorIdT &&actor_id, FunctionT function, ArgsT &&... args) { } template -void send_closure_later(ActorIdT &&actor_id, FunctionT function, ArgsT &&... args) { +void send_closure_later(ActorIdT &&actor_id, FunctionT function, ArgsT &&...args) { using ActorT = typename std::decay_t::ActorT; using FunctionClassT = member_function_class_t; static_assert(std::is_base_of::value, "unsafe send_closure"); @@ -276,17 +276,17 @@ void send_closure_later(ActorIdT &&actor_id, FunctionT function, ArgsT &&... arg } template -void send_lambda(ActorRef actor_ref, ArgsT &&... args) { +void send_lambda(ActorRef actor_ref, ArgsT &&...args) { Scheduler::instance()->send_lambda(actor_ref, std::forward(args)...); } template -void send_event(ActorRef actor_ref, ArgsT &&... args) { +void send_event(ActorRef actor_ref, ArgsT &&...args) { Scheduler::instance()->send(actor_ref, std::forward(args)...); } template -void send_event_later(ActorRef actor_ref, ArgsT &&... args) { +void send_event_later(ActorRef actor_ref, ArgsT &&...args) { Scheduler::instance()->send(actor_ref, std::forward(args)...); } diff --git a/tdactor/td/actor/impl/Scheduler.h b/tdactor/td/actor/impl/Scheduler.h index 94c9b8f99..797a2539c 100644 --- a/tdactor/td/actor/impl/Scheduler.h +++ b/tdactor/td/actor/impl/Scheduler.h @@ -69,12 +69,12 @@ inline int32 Scheduler::sched_count() const { } template -ActorOwn Scheduler::create_actor(Slice name, Args &&... args) { +ActorOwn Scheduler::create_actor(Slice name, Args &&...args) { return register_actor_impl(name, new ActorT(std::forward(args)...), Actor::Deleter::Destroy, sched_id_); } template -ActorOwn Scheduler::create_actor_on_scheduler(Slice name, int32 sched_id, Args &&... args) { +ActorOwn Scheduler::create_actor_on_scheduler(Slice name, int32 sched_id, Args &&...args) { return register_actor_impl(name, new ActorT(std::forward(args)...), Actor::Deleter::Destroy, sched_id); } @@ -334,12 +334,12 @@ inline void Scheduler::run(Timestamp timeout) { /*** Interface to current scheduler ***/ template -ActorOwn create_actor(Slice name, Args &&... args) { +ActorOwn create_actor(Slice name, Args &&...args) { return Scheduler::instance()->create_actor(name, std::forward(args)...); } template -ActorOwn create_actor_on_scheduler(Slice name, int32 sched_id, Args &&... args) { +ActorOwn create_actor_on_scheduler(Slice name, int32 sched_id, Args &&...args) { return Scheduler::instance()->create_actor_on_scheduler(name, sched_id, std::forward(args)...); } diff --git a/tdutils/td/utils/Closure.h b/tdutils/td/utils/Closure.h index ef2054f69..bc6386e4c 100644 --- a/tdutils/td/utils/Closure.h +++ b/tdutils/td/utils/Closure.h @@ -83,7 +83,7 @@ class ImmediateClosure { template ImmediateClosure create_immediate_closure( - ResultT (ActorT::*func)(DestArgsT...), SrcArgsT &&... args) { + ResultT (ActorT::*func)(DestArgsT...), SrcArgsT &&...args) { return ImmediateClosure(func, std::forward(args)...); } @@ -160,7 +160,7 @@ DelayedClosure to_delayed_closure(DelayedClosure &&other) { } template -auto create_delayed_closure(ResultT (ActorT::*func)(DestArgsT...), SrcArgsT &&... args) { +auto create_delayed_closure(ResultT (ActorT::*func)(DestArgsT...), SrcArgsT &&...args) { return DelayedClosure(func, std::forward(args)...); } diff --git a/tdutils/td/utils/ObjectPool.h b/tdutils/td/utils/ObjectPool.h index 05a1f4fa4..feb611ca8 100644 --- a/tdutils/td/utils/ObjectPool.h +++ b/tdutils/td/utils/ObjectPool.h @@ -156,7 +156,7 @@ class ObjectPool { }; template - OwnerPtr create(ArgsT &&... args) { + OwnerPtr create(ArgsT &&...args) { Storage *storage = get_storage(); storage->init_data(std::forward(args)...); return OwnerPtr(storage, this); @@ -201,7 +201,7 @@ class ObjectPool { std::atomic generation{1}; template - void init_data(ArgsT &&... args) { + void init_data(ArgsT &&...args) { // new (&data) DataT(std::forward(args)...); data = DataT(std::forward(args)...); } diff --git a/tdutils/td/utils/SharedObjectPool.h b/tdutils/td/utils/SharedObjectPool.h index 8cd377950..3ad155f2d 100644 --- a/tdutils/td/utils/SharedObjectPool.h +++ b/tdutils/td/utils/SharedObjectPool.h @@ -49,7 +49,7 @@ class SharedPtrRaw CHECK(option_magic_ == Magic); } template - void init_data(ArgsT &&... args) { + void init_data(ArgsT &&...args) { new (&option_data_) DataT(std::forward(args)...); } void destroy_data() { @@ -158,13 +158,13 @@ class SharedPtr { } template - static SharedPtr create(ArgsT &&... args) { + static SharedPtr create(ArgsT &&...args) { auto raw = make_unique(DeleterT()); raw->init_data(std::forward(args)...); return SharedPtr(raw.release()); } template - static SharedPtr create_with_deleter(D &&d, ArgsT &&... args) { + static SharedPtr create_with_deleter(D &&d, ArgsT &&...args) { auto raw = make_unique(std::forward(d)); raw->init_data(std::forward(args)...); return SharedPtr(raw.release()); @@ -201,7 +201,7 @@ class SharedObjectPool { } template - Ptr alloc(ArgsT &&... args) { + Ptr alloc(ArgsT &&...args) { auto *raw = alloc_raw(); raw->init_data(std::forward(args)...); return Ptr(raw); diff --git a/tdutils/td/utils/Status.h b/tdutils/td/utils/Status.h index ee74cc23f..170c3fc3b 100644 --- a/tdutils/td/utils/Status.h +++ b/tdutils/td/utils/Status.h @@ -416,7 +416,7 @@ class Result { } struct emplace_t {}; template - Result(emplace_t, ArgsT &&... args) : status_(), value_(std::forward(args)...) { + Result(emplace_t, ArgsT &&...args) : status_(), value_(std::forward(args)...) { } Result(Status &&status) : status_(std::move(status)) { CHECK(status_.is_error()); @@ -451,7 +451,7 @@ class Result { return *this; } template - void emplace(ArgsT &&... args) { + void emplace(ArgsT &&...args) { if (status_.is_ok()) { value_.~T(); } diff --git a/tdutils/td/utils/VectorQueue.h b/tdutils/td/utils/VectorQueue.h index a0330e165..73bc47425 100644 --- a/tdutils/td/utils/VectorQueue.h +++ b/tdutils/td/utils/VectorQueue.h @@ -22,7 +22,7 @@ class VectorQueue { } template - void emplace(Args &&... args) { + void emplace(Args &&...args) { vector_.emplace_back(std::forward(args)...); } diff --git a/tdutils/td/utils/buffer.cpp b/tdutils/td/utils/buffer.cpp index 05da3e220..d6e70a4cd 100644 --- a/tdutils/td/utils/buffer.cpp +++ b/tdutils/td/utils/buffer.cpp @@ -8,7 +8,6 @@ #include "td/utils/logging.h" #include "td/utils/port/thread_local.h" -#include "td/utils/ThreadSafeCounter.h" #include #include @@ -26,18 +25,12 @@ TD_THREAD_LOCAL BufferAllocator::BufferRawTls *BufferAllocator::buffer_raw_tls; std::atomic BufferAllocator::buffer_mem; -static ThreadSafeCounter buffer_slice_size_; - int64 BufferAllocator::get_buffer_slice_size() { - return buffer_slice_size_.sum(); + return 0; } void BufferAllocator::track_buffer_slice(int64 size) { - if (size == 0) { - return; - } - - buffer_slice_size_.add(size); + return; } size_t BufferAllocator::get_buffer_mem() { diff --git a/tdutils/td/utils/format.h b/tdutils/td/utils/format.h index 61039a6c1..8bba4c7f7 100644 --- a/tdutils/td/utils/format.h +++ b/tdutils/td/utils/format.h @@ -301,7 +301,7 @@ StringBuilder &operator<<(StringBuilder &sb, const Concat &concat) { } template -auto concat(const ArgsT &... args) { +auto concat(const ArgsT &...args) { return Concat{std::tie(args...)}; } diff --git a/tdutils/td/utils/invoke.h b/tdutils/td/utils/invoke.h index f26a24378..8a74c3814 100644 --- a/tdutils/td/utils/invoke.h +++ b/tdutils/td/utils/invoke.h @@ -54,7 +54,7 @@ struct is_reference_wrapper> : std::true_type {}; template auto invoke_impl(T Base::*pmf, Derived &&ref, - Args &&... args) noexcept(noexcept((std::forward(ref).*pmf)(std::forward(args)...))) + Args &&...args) noexcept(noexcept((std::forward(ref).*pmf)(std::forward(args)...))) -> std::enable_if_t::value && std::is_base_of>::value, decltype((std::forward(ref).*pmf)(std::forward(args)...))> { return (std::forward(ref).*pmf)(std::forward(args)...); @@ -62,7 +62,7 @@ auto invoke_impl(T Base::*pmf, Derived &&ref, template auto invoke_impl(T Base::*pmf, RefWrap &&ref, - Args &&... args) noexcept(noexcept((ref.get().*pmf)(std::forward(args)...))) + Args &&...args) noexcept(noexcept((ref.get().*pmf)(std::forward(args)...))) -> std::enable_if_t::value && is_reference_wrapper>::value, decltype((ref.get().*pmf)(std::forward(args)...))> @@ -72,7 +72,7 @@ auto invoke_impl(T Base::*pmf, RefWrap &&ref, template auto invoke_impl(T Base::*pmf, Pointer &&ptr, - Args &&... args) noexcept(noexcept(((*std::forward(ptr)).*pmf)(std::forward(args)...))) + Args &&...args) noexcept(noexcept(((*std::forward(ptr)).*pmf)(std::forward(args)...))) -> std::enable_if_t::value && !is_reference_wrapper>::value && !std::is_base_of>::value, decltype(((*std::forward(ptr)).*pmf)(std::forward(args)...))> { @@ -102,7 +102,7 @@ auto invoke_impl(T Base::*pmd, Pointer &&ptr) noexcept(noexcept((*std::forward

-auto invoke_impl(F &&f, Args &&... args) noexcept(noexcept(std::forward(f)(std::forward(args)...))) +auto invoke_impl(F &&f, Args &&...args) noexcept(noexcept(std::forward(f)(std::forward(args)...))) -> std::enable_if_t>::value, decltype(std::forward(f)(std::forward(args)...))> { return std::forward(f)(std::forward(args)...); @@ -110,7 +110,7 @@ auto invoke_impl(F &&f, Args &&... args) noexcept(noexcept(std::forward(f)(st template auto invoke(F &&f, - ArgTypes &&... args) noexcept(noexcept(invoke_impl(std::forward(f), std::forward(args)...))) + ArgTypes &&...args) noexcept(noexcept(invoke_impl(std::forward(f), std::forward(args)...))) -> decltype(invoke_impl(std::forward(f), std::forward(args)...)) { return invoke_impl(std::forward(f), std::forward(args)...); } @@ -176,29 +176,29 @@ void tuple_for_each(const std::tuple &tuple, const F &func) { } template = 0> -auto &&get_nth_argument(Arg &&arg, Args &&... args) { +auto &&get_nth_argument(Arg &&arg, Args &&...args) { return std::forward(arg); } template = 0> -auto &&get_nth_argument(Arg &&arg, Args &&... args) { +auto &&get_nth_argument(Arg &&arg, Args &&...args) { return get_nth_argument(std::forward(args)...); } template -auto &&get_last_argument(Args &&... args) { +auto &&get_last_argument(Args &&...args) { return get_nth_argument(std::forward(args)...); } namespace detail { template -auto call_n_arguments_impl(IntSeq, F &&f, Args &&... args) { +auto call_n_arguments_impl(IntSeq, F &&f, Args &&...args) { return f(get_nth_argument(std::forward(args)...)...); } } // namespace detail template -auto call_n_arguments(F &&f, Args &&... args) { +auto call_n_arguments(F &&f, Args &&...args) { return detail::call_n_arguments_impl(detail::IntRange(), f, std::forward(args)...); } diff --git a/tdutils/td/utils/optional.h b/tdutils/td/utils/optional.h index 0004ec201..6a3c70f08 100644 --- a/tdutils/td/utils/optional.h +++ b/tdutils/td/utils/optional.h @@ -75,7 +75,7 @@ class optional { } template - void emplace(ArgsT &&... args) { + void emplace(ArgsT &&...args) { impl_.emplace(std::forward(args)...); } diff --git a/tdutils/td/utils/port/CxCli.h b/tdutils/td/utils/port/CxCli.h index 6d670c0c4..f8edb329f 100644 --- a/tdutils/td/utils/port/CxCli.h +++ b/tdutils/td/utils/port/CxCli.h @@ -30,8 +30,8 @@ #define REF_NEW ref new #define CLRCALL -#define DEPRECATED_ATTRIBUTE(message) ::Windows::Foundation::Metadata::Deprecated(message,\ - ::Windows::Foundation::Metadata::DeprecationType::Deprecate, 0x0) +#define DEPRECATED_ATTRIBUTE(message) \ + ::Windows::Foundation::Metadata::Deprecated(message, ::Windows::Foundation::Metadata::DeprecationType::Deprecate, 0x0) namespace CxCli { @@ -49,7 +49,7 @@ using Platform::NullReferenceException; template class ConcurrentDictionary { -public: + public: bool TryGetValue(Key key, Value &value) { std::lock_guard guard(mutex_); auto it = impl_.find(key); @@ -69,11 +69,12 @@ public: impl_.erase(it); return true; } - Value &operator [] (Key key) { + Value &operator[](Key key) { std::lock_guard guard(mutex_); return impl_[key]; } -private: + + private: std::mutex mutex_; std::map impl_; }; @@ -82,7 +83,7 @@ inline std::int64_t Increment(volatile std::int64_t &value) { return InterlockedIncrement64(&value); } -inline std::string string_to_unmanaged(String^ str) { +inline std::string string_to_unmanaged(String ^ str) { if (!str) { return std::string(); } @@ -93,12 +94,12 @@ inline std::string string_to_unmanaged(String^ str) { return r_unmanaged_str.move_as_ok(); } -inline String^ string_from_unmanaged(const std::string &from) { +inline String ^ string_from_unmanaged(const std::string &from) { auto tmp = td::to_wstring(from).ok(); return REF_NEW String(tmp.c_str(), static_cast(tmp.size())); } -} // namespace CxCli +} // namespace CxCli #elif TD_CLI @@ -128,27 +129,27 @@ using System::NullReferenceException; using System::Collections::Concurrent::ConcurrentDictionary; -inline std::int64_t Increment(std::int64_t %value) { +inline std::int64_t Increment(std::int64_t % value) { return System::Threading::Interlocked::Increment(value); } -inline std::string string_to_unmanaged(String^ str) { +inline std::string string_to_unmanaged(String ^ str) { if (!str || str->Length == 0) { return std::string(); } - Array^ bytes = System::Text::Encoding::UTF8->GetBytes(str); + Array ^ bytes = System::Text::Encoding::UTF8->GetBytes(str); cli::pin_ptr pinned_ptr = &bytes[0]; std::string result(reinterpret_cast(&pinned_ptr[0]), bytes->Length); return result; } -inline String^ string_from_unmanaged(const std::string &from) { +inline String ^ string_from_unmanaged(const std::string &from) { if (from.empty()) { return String::Empty; } - Array^ bytes = REF_NEW Vector(static_cast(from.size())); + Array ^ bytes = REF_NEW Vector(static_cast(from.size())); cli::pin_ptr pinned_ptr = &bytes[0]; for (size_t i = 0; i < from.size(); ++i) { pinned_ptr[i] = from[i]; @@ -156,6 +157,6 @@ inline String^ string_from_unmanaged(const std::string &from) { return System::Text::Encoding::UTF8->GetString(bytes); } -} // namespace CxCli +} // namespace CxCli #endif diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 4c63b6d31..404c54a69 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -103,7 +103,7 @@ StringBuilder &operator<<(StringBuilder &sb, const PrintFlags &print_flags) { namespace detail { class FileFdImpl { public: - PollableFdInfo info; + PollableFdInfo info_; }; } // namespace detail @@ -242,8 +242,8 @@ Result FileFd::open(CSlice filepath, int32 flags, int32 mode) { FileFd FileFd::from_native_fd(NativeFd native_fd) { auto impl = make_unique(); - impl->info.set_native_fd(std::move(native_fd)); - impl->info.add_flags(PollFlags::Write()); + impl->info_.set_native_fd(std::move(native_fd)); + impl->info_.add_flags(PollFlags::Write()); return FileFd(std::move(impl)); } @@ -648,11 +648,11 @@ Status FileFd::truncate_to_current_position(int64 current_position) { } PollableFdInfo &FileFd::get_poll_info() { CHECK(!empty()); - return impl_->info; + return impl_->info_; } const PollableFdInfo &FileFd::get_poll_info() const { CHECK(!empty()); - return impl_->info; + return impl_->info_; } } // namespace td diff --git a/tdutils/td/utils/port/SocketFd.cpp b/tdutils/td/utils/port/SocketFd.cpp index c54912723..dbb0dcfac 100644 --- a/tdutils/td/utils/port/SocketFd.cpp +++ b/tdutils/td/utils/port/SocketFd.cpp @@ -43,7 +43,7 @@ namespace detail { #if TD_PORT_WINDOWS class SocketFdImpl final : private Iocp::Callback { public: - explicit SocketFdImpl(NativeFd native_fd) : info(std::move(native_fd)) { + explicit SocketFdImpl(NativeFd native_fd) : info_(std::move(native_fd)) { VLOG(fd) << get_native_fd() << " create from native_fd"; get_poll_info().add_flags(PollFlags::Write()); Iocp::get()->subscribe(get_native_fd(), this); @@ -51,7 +51,7 @@ class SocketFdImpl final : private Iocp::Callback { notify_iocp_connected(); } - SocketFdImpl(NativeFd native_fd, const IPAddress &addr) : info(std::move(native_fd)) { + SocketFdImpl(NativeFd native_fd, const IPAddress &addr) : info_(std::move(native_fd)) { VLOG(fd) << get_native_fd() << " create from native_fd and connect"; get_poll_info().add_flags(PollFlags::Write()); Iocp::get()->subscribe(get_native_fd(), this); @@ -88,14 +88,14 @@ class SocketFdImpl final : private Iocp::Callback { } PollableFdInfo &get_poll_info() { - return info; + return info_; } const PollableFdInfo &get_poll_info() const { - return info; + return info_; } const NativeFd &get_native_fd() const { - return info.native_fd(); + return info_.native_fd(); } Result write(Slice data) { @@ -161,7 +161,7 @@ class SocketFdImpl final : private Iocp::Callback { } private: - PollableFdInfo info; + PollableFdInfo info_; SpinLock lock_; std::atomic refcnt_{1}; @@ -283,7 +283,12 @@ class SocketFdImpl final : private Iocp::Callback { if (overlapped == reinterpret_cast(&close_overlapped_)) { return on_close(); } - UNREACHABLE(); + LOG(ERROR) << this << ' ' << overlapped << ' ' << &read_overlapped_ << ' ' << &write_overlapped_ << ' ' + << reinterpret_cast(&close_overlapped_) << ' ' << size; + LOG(FATAL) << get_native_fd() << ' ' << info_.get_flags_local() << ' ' << refcnt_.load() << ' ' << close_flag_ + << ' ' << need_close_after_write_ << ' ' << is_connected_ << ' ' << is_read_active_ << ' ' + << is_write_active_ << ' ' << is_write_waiting_.load() << ' ' << input_reader_.size() << ' ' + << output_reader_.size(); } void on_error(Status status) { @@ -335,7 +340,7 @@ class SocketFdImpl final : private Iocp::Callback { void on_close() { VLOG(fd) << get_native_fd() << " on close"; close_flag_ = true; - info.set_native_fd({}); + info_.set_native_fd({}); } bool dec_refcnt() { VLOG(fd) << get_native_fd() << " dec_refcnt from " << refcnt_; @@ -386,18 +391,18 @@ static InitWSA init_wsa; #else class SocketFdImpl { public: - PollableFdInfo info; - explicit SocketFdImpl(NativeFd fd) : info(std::move(fd)) { + PollableFdInfo info_; + explicit SocketFdImpl(NativeFd fd) : info_(std::move(fd)) { } PollableFdInfo &get_poll_info() { - return info; + return info_; } const PollableFdInfo &get_poll_info() const { - return info; + return info_; } const NativeFd &get_native_fd() const { - return info.native_fd(); + return info_.native_fd(); } Result writev(Span slices) { diff --git a/tdutils/td/utils/port/detail/EventFdLinux.cpp b/tdutils/td/utils/port/detail/EventFdLinux.cpp index ce87692a8..662281730 100644 --- a/tdutils/td/utils/port/detail/EventFdLinux.cpp +++ b/tdutils/td/utils/port/detail/EventFdLinux.cpp @@ -29,7 +29,7 @@ namespace td { namespace detail { class EventFdLinuxImpl { public: - PollableFdInfo info; + PollableFdInfo info_; }; EventFdLinux::EventFdLinux() = default; @@ -42,7 +42,7 @@ void EventFdLinux::init() { auto eventfd_errno = errno; LOG_IF(FATAL, !fd) << Status::PosixError(eventfd_errno, "eventfd call failed"); impl_ = make_unique(); - impl_->info.set_native_fd(std::move(fd)); + impl_->info_.set_native_fd(std::move(fd)); } bool EventFdLinux::empty() { @@ -58,14 +58,14 @@ Status EventFdLinux::get_pending_error() { } PollableFdInfo &EventFdLinux::get_poll_info() { - return impl_->info; + return impl_->info_; } // NB: will be called from multiple threads void EventFdLinux::release() { const uint64 value = 1; auto slice = Slice(reinterpret_cast(&value), sizeof(value)); - auto native_fd = impl_->info.native_fd().fd(); + auto native_fd = impl_->info_.native_fd().fd(); auto result = [&]() -> Result { auto write_res = detail::skip_eintr([&] { return write(native_fd, slice.begin(), slice.size()); }); @@ -86,7 +86,7 @@ void EventFdLinux::release() { } void EventFdLinux::acquire() { - impl_->info.sync_with_poll(); + impl_->info_.sync_with_poll(); SCOPE_EXIT { // Clear flags without EAGAIN and EWOULDBLOCK // Looks like it is safe thing to do with eventfd @@ -94,7 +94,7 @@ void EventFdLinux::acquire() { }; uint64 res; auto slice = MutableSlice(reinterpret_cast(&res), sizeof(res)); - auto native_fd = impl_->info.native_fd().fd(); + auto native_fd = impl_->info_.native_fd().fd(); auto result = [&]() -> Result { CHECK(!slice.empty()); auto read_res = detail::skip_eintr([&] { return ::read(native_fd, slice.begin(), slice.size()); }); diff --git a/tdutils/td/utils/port/detail/ThreadPthread.h b/tdutils/td/utils/port/detail/ThreadPthread.h index d73ec1083..a0abd5640 100644 --- a/tdutils/td/utils/port/detail/ThreadPthread.h +++ b/tdutils/td/utils/port/detail/ThreadPthread.h @@ -40,7 +40,7 @@ class ThreadPthread { return *this; } template - explicit ThreadPthread(Function &&f, Args &&... args) { + explicit ThreadPthread(Function &&f, Args &&...args) { auto func = create_destructor([args = std::make_tuple(decay_copy(std::forward(f)), decay_copy(std::forward(args))...)]() mutable { invoke_tuple(std::move(args)); diff --git a/tdutils/td/utils/port/detail/ThreadStl.h b/tdutils/td/utils/port/detail/ThreadStl.h index 8c3b40d7a..43bae2bc8 100644 --- a/tdutils/td/utils/port/detail/ThreadStl.h +++ b/tdutils/td/utils/port/detail/ThreadStl.h @@ -34,7 +34,7 @@ class ThreadStl { join(); } template - explicit ThreadStl(Function &&f, Args &&... args) { + explicit ThreadStl(Function &&f, Args &&...args) { thread_ = std::thread([args = std::make_tuple(decay_copy(std::forward(f)), decay_copy(std::forward(args))...)]() mutable { ThreadIdGuard thread_id_guard; diff --git a/tdutils/td/utils/port/thread_local.h b/tdutils/td/utils/port/thread_local.h index 6c7f5102a..7b803cbd6 100644 --- a/tdutils/td/utils/port/thread_local.h +++ b/tdutils/td/utils/port/thread_local.h @@ -29,7 +29,7 @@ namespace td { // If raw_ptr is not nullptr, allocate T as in std::make_unique(args...) and store pointer into raw_ptr template -bool init_thread_local(P &raw_ptr, ArgsT &&... args); +bool init_thread_local(P &raw_ptr, ArgsT &&...args); // Destroy all thread locals, and store nullptr into corresponding pointers void clear_thread_locals(); @@ -42,7 +42,7 @@ namespace detail { void add_thread_local_destructor(unique_ptr destructor); template -void do_init_thread_local(P &raw_ptr, ArgsT &&... args) { +void do_init_thread_local(P &raw_ptr, ArgsT &&...args) { auto ptr = std::make_unique(std::forward(args)...); raw_ptr = ptr.get(); @@ -54,7 +54,7 @@ void do_init_thread_local(P &raw_ptr, ArgsT &&... args) { } // namespace detail template -bool init_thread_local(P &raw_ptr, ArgsT &&... args) { +bool init_thread_local(P &raw_ptr, ArgsT &&...args) { if (likely(raw_ptr != nullptr)) { return false; } diff --git a/tdutils/td/utils/unique_ptr.h b/tdutils/td/utils/unique_ptr.h index b56ee9ab7..89944e986 100644 --- a/tdutils/td/utils/unique_ptr.h +++ b/tdutils/td/utils/unique_ptr.h @@ -99,7 +99,7 @@ bool operator!=(const unique_ptr &p, std::nullptr_t) { } template -unique_ptr make_unique(Args &&... args) { +unique_ptr make_unique(Args &&...args) { return unique_ptr(new Type(std::forward(args)...)); }