YSTest: YEvent.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

YEvent.hpp
浏览该文件的文档.
1 /*
2 © 2010-2020 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YSL_INC_Core_yevt_hpp_
29 #define YSL_INC_Core_yevt_hpp_ 1
30
31 #include "YModules.h"
32 #include YFM_YSLib_Core_YObject // for ystdex::is_expandable,
33 // ystdex::is_decayed, ystdex::examiners::equal_examiner, std::allocator_arg_t,
34 // std::allocator_arg, ystdex::make_expanded, ystdex::default_last_value,
35 // std::piecewise_construct, YSLib::forward_as_tuple;
36 #include YFM_YSLib_Core_YFunc
37 #include <ystdex/type_op.hpp> // for ystdex::exclude_self_t,
38 // ystdex::exclude_self_params_t;
39 #include <ystdex/iterator.hpp> // for ystdex::make_transform, ystdex::get_value;
40 #include <ystdex/container.hpp> // for ystdex::erase_all_if;
41 #include <ystdex/base.h> // for ystdex::cloneable;
42 #include <ystdex/operators.hpp> // for ystdex::equality_comparable;
43 #include <ystdex/swap.hpp> // for ystdex::swap_dependent;
44 #include <ystdex/optional.h> // for ystdex::optional_last_value;
45
46 namespace YSLib
47 {
48
58 template<typename>
59 class GHEvent;
60
62 template<typename _tRet, typename... _tParams>
63 class GHEvent<_tRet(_tParams...)>
64 : protected ystdex::expanded_function<_tRet(_tParams...)>,
65 private ystdex::equality_comparable<GHEvent<_tRet(_tParams...)>>,
66 private ystdex::equality_comparable<GHEvent<_tRet(_tParams...)>, nullptr_t>
67 {
68 public:
69 using FuncType = _tRet(_tParams...);
70 using BaseType = ystdex::expanded_function<FuncType>;
71
72 private:
73 // XXX: Clang++ 7.1 behaves weirdly with %lref<GHEvent> when using combined
74 // traits by %ystdex::not_ and %ystdex::and_. It seems related to https://bugs.llvm.org/show_bug.cgi?id=38033,
75 // but this does not work whether '-std=c++17' is used.
77 template<typename _fCallable>
78 using enable_if_expandable_t = ystdex::enable_if_t<
79 !std::is_constructible<function<FuncType>, _fCallable>::value
80 && ystdex::is_expandable<function<FuncType>, _fCallable>::value>;
82 using Comparer = bool(*)(const GHEvent&, const GHEvent&);
83 template<typename _fCallable>
84 struct GEquality
85 {
87 static_assert(ystdex::is_decayed<_fCallable>(),
88 "Decayed functor expected.");
89
94 YB_ATTR_nodiscard YB_PURE static bool
95 AreEqual(const GHEvent& x, const GHEvent& y)
96 // TODO: Verify if it is a GCC bug. Since the resolution of CWG
97 // 1330 is in the working draft N4659, it is likely to be. See also
98 // https://stackoverflow.com/questions/35790350.
99 #if !(YB_IMPL_GNUCPP >= 70000)
100 ynoexcept_spec(ystdex::examiners::equal_examiner::are_equal(Deref(
101 x.template target<_fCallable>()),
102 Deref(y.template target<_fCallable>())))
103 #endif
104 {
105 return ystdex::examiners::equal_examiner::are_equal(
106 Deref(x.template target<_fCallable>()),
107 Deref(y.template target<_fCallable>()));
108 }
109 };
111 template<typename _fCallable>
112 struct GEqualityExpanded
113 {
115 static_assert(ystdex::is_decayed<_fCallable>(), "Invalid type found.");
116
117 YB_ATTR_nodiscard YB_PURE static bool
118 AreEqual(const GHEvent& x, const GHEvent& y) ynoexcept_spec(
119 ystdex::examiners::equal_examiner::are_equal(std::declval<const
120 _fCallable&>(), std::declval<const _fCallable&>()))
121 // TODO: Exception specification?
122 {
123 // NOTE: Blocked. Use ISO C++14 deduced lambda return type (cf. CWG
124 // 975) compatible to G++ attribute.
125 const auto get_ref(
126 [](const GHEvent& h) YB_ATTR_LAMBDA_QUAL(ynothrowv, YB_PURE){
127 return std::ref(Deref(h.template target<ystdex::expanded_caller<
128 FuncType, _fCallable>>()).caller);
129 });
130
131 return ystdex::examiners::equal_examiner::are_equal(
132 get_ref(x).get(), get_ref(y).get());
133 }
134 };
135
140 Comparer comp_eq;
141
142 public:
148 GHEvent(FuncType* f = {}) ynothrow
150 : BaseType(f),
151 comp_eq(GEquality<ystdex::decay_t<FuncType>>::AreEqual)
152 {}
154 template<class _tAlloc>
155 inline
156 GHEvent(std::allocator_arg_t, const _tAlloc& a, FuncType* f = {}) ynothrow
157 : BaseType(std::allocator_arg, a, f),
158 comp_eq(GEquality<ystdex::decay_t<FuncType>>::AreEqual)
159 {}
161
163 template<class _fCallable, yimpl(typename = ystdex::exclude_self_t<GHEvent,
165 _fCallable>, typename = ystdex::enable_if_t<std::is_constructible<
166 function<FuncType>, _fCallable>::value>)>
167 inline
168 GHEvent(_fCallable f)
169 : BaseType(std::move(f)),
170 comp_eq(GEquality<_fCallable>::AreEqual)
171 {}
173 template<class _fCallable, class _tAlloc,
174 yimpl(typename = ystdex::exclude_self_t<GHEvent, _fCallable>,
175 typename = ystdex::enable_if_t<
176 std::is_constructible<function<FuncType>, _fCallable>::value>)>
177 inline
178 GHEvent(std::allocator_arg_t, const _tAlloc& a, _fCallable&& f)
179 : BaseType(std::allocator_arg, a, yforward(f)),
180 comp_eq(GEquality<_fCallable>::AreEqual)
181 {}
183 template<typename _fCallable,
184 yimpl(typename = enable_if_expandable_t<_fCallable>)>
185 inline
186 GHEvent(_fCallable f)
187 : BaseType(ystdex::make_expanded<FuncType>(std::move(f))),
188 // XXX: Here lambda-expression is buggy on G++ LTO, at least G++ 7.1.0
189 // (failure of multiple definitions).
190 comp_eq(GEqualityExpanded<_fCallable>::AreEqual)
191 {}
193 template<typename _fCallable, class _tAlloc,
194 yimpl(typename = enable_if_expandable_t<_fCallable>)>
195 inline
196 GHEvent(std::allocator_arg_t, const _tAlloc& a, _fCallable f)
197 : BaseType(std::allocator_arg, a,
198 ystdex::make_expanded<FuncType>(std::move(f))),
199 // XXX: Here lambda-expression is buggy on G++ LTO, at least G++ 7.1.0
200 // (failure of multiple definitions).
201 comp_eq(GEqualityExpanded<_fCallable>::AreEqual)
202 {}
204
210 template<class _type>
212 yconstfn
213 GHEvent(_type& obj, _tRet(_type::*pm)(_tParams...))
214 : GHEvent([&, pm](_tParams... args) ynoexcept(
215 noexcept((obj.*pm)(yforward(args)...))
216 && std::is_nothrow_copy_constructible<_tRet>::value){
217 return (obj.*pm)(yforward(args)...);
218 })
219 {}
221 template<class _type, class _tAlloc>
222 yconstfn
223 GHEvent(std::allocator_arg_t, const _tAlloc& a, _type& obj,
224 _tRet(_type::*pm)(_tParams...))
225 : GHEvent(std::allocator_arg, a, [&, pm](_tParams... args) ynoexcept(
226 noexcept((obj.*pm)(yforward(args)...))
227 && std::is_nothrow_copy_constructible<_tRet>::value){
228 return (obj.*pm)(yforward(args)...);
229 })
230 {}
232
234 template<class _tAlloc>
236 inline
237 GHEvent(std::allocator_arg_t, const _tAlloc& a, const GHEvent& x)
238 : BaseType(std::allocator_arg, a, x),
239 comp_eq(x.comp_eq)
240 {}
242 template<class _tAlloc>
243 inline
244 GHEvent(std::allocator_arg_t, const _tAlloc& a, GHEvent&& x)
245 : BaseType(std::allocator_arg, a, std::move(x)),
246 comp_eq(x.comp_eq)
247 {}
249 DefDeCopyMoveCtorAssignment(GHEvent)
250
251
252
253
257 YB_ATTR_nodiscard YB_PURE friend
258 PDefHOp(bool, ==, const GHEvent& x, const GHEvent& y)
259 ImplRet(x.Equals(y))
261
262 template<typename _type>
264 YB_ATTR_nodiscard YB_PURE friend inline bool
265 operator==(const GHEvent& x, nullptr_t y)
266 {
267 return x.Equals(y);
268 }
270
271 template<typename _type>
272 YB_ATTR_nodiscard YB_PURE friend inline bool
273 operator==(const GHEvent& x, const _type& y)
274 {
275 return x.Equals(y);
276 }
277 template<typename _type>
278 YB_ATTR_nodiscard YB_PURE friend inline bool
279 operator==(const _type& x, const GHEvent& y)
280 {
281 return y.Equals(x);
282 }
284
286
287 template<typename _type>
288 YB_ATTR_nodiscard friend inline bool
289 operator!=(const GHEvent& x, const _type& y)
290 {
291 return !(x == y);
292 }
293 template<typename _type>
294 YB_ATTR_nodiscard friend inline bool
295 operator!=(const _type& x, const GHEvent& y)
296 {
297 return !(x == y);
298 }
300
301
302
304 using BaseType::operator();
305
307 using BaseType::operator bool;
308
310
311
317 YB_ATTR_nodiscard YB_PURE bool
318 Equals(nullptr_t) const
319 {
320 return !bool(*this);
321 }
323 YB_ATTR_nodiscard YB_PURE bool
324 Equals(const GHEvent& x) const
325 {
326 return HaveSameTargetType(*this, x) && EqualsUnchecked(x);
327 }
328 template<typename _type>
329 YB_ATTR_nodiscard YB_PURE bool
330 Equals(const _type& x) const
331 {
332 if(const auto p = this->template target<ystdex::decay_t<_type>>())
333 return *p == x;
334 return {};
335 }
336
341 YB_ATTR_nodiscard YB_PURE bool
342 EqualsUnchecked(const GHEvent& x) const
343 {
344 YAssert(HaveSameTargetType(*this, x), "Invalid target found.");
345 return !bool(*this) || comp_eq(*this, x);
346 }
348
350 YB_ATTR_nodiscard YB_PURE static bool
351 HaveSameTargetType(const GHEvent& x, const GHEvent& y)
352 {
353 #if defined(YF_DLL) || defined(YF_BUILD_DLL)
354 return x.target_type() == y.target_type();
355 #else
356 return x.comp_eq == y.comp_eq;
357 #endif
358 }
360
362 friend yconstfn_relaxed
363 DefSwap(ynothrow, Comparer, ystdex::swap_dependent(_x, _y))
364 friend void
365 swap(GHEvent& x, GHEvent& y) ynothrow
366 {
367 ystdex::swap_dependent(static_cast< BaseType&>(x),
368 static_cast< BaseType&>(y));
369 swap(x.comp_eq, y.comp_eq);
370 }
371
373 using BaseType::target;
374
376 using BaseType::target_type;
377 };
379
384 template<typename _tRet, typename... _tParams>
385 yconstfn bool
386 operator==(const GHEvent<_tRet(_tParams...)>& x, nullptr_t)
387 {
388 return !x;
389 }
390
391
396 using EventPriority = std::uint8_t;
397
398
403 yconstexpr const EventPriority DefaultEventPriority(0x80);
404
405
407
408 struct CountedHandlerInvoker
410 {
412 template<typename _tIn, typename... _tParams>
413 size_t
414 operator()(_tIn first, _tIn last, _tParams&&... args) const
415 {
416 size_t n(0);
417
418 while(first != last)
419 {
420 (*first)(yforward(args)...);
421 yunseq(++n, ++first);
422 }
423 return n;
424 }
425 };
426
427
429 template<typename _type, typename _tCombiner>
430 struct GCombinerInvoker
431 {
432 static_assert(ystdex::is_decayed<_tCombiner>(), "Invalid type found.");
433
434 public:
435 using result_type = _type;
436
437 private:
438 _tCombiner combiner;
439
440 public:
441 template<typename _tIn, typename... _tParams>
442 result_type
443 operator()(_tIn first, _tIn last, _tParams&&... args) const
444 {
445 // XXX: Blocked. 'yforward' cause G++ 5.2 crash: internal
446 // compiler error: Aborted (program cc1plus).
447 #if false
448 const auto tr([&](_tIn iter){
449 return ystdex::make_transform(iter, [&](_tIn i){
450 // XXX: Blocked. 'std::forward' still cause G++ 5.2 crash:
451 // internal compiler error: in execute, at cfgexpand.c:6044.
452 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65992.
453 return (*i)(std::forward<_tParams>(args)...);
454 });
455 });
456 #else
457 const auto f([&](_tIn i){
458 return (*i)(std::forward<_tParams>(args)...);
459 });
460 const auto tr([f](_tIn iter){
461 return ystdex::make_transform(iter, f);
462 });
463 #endif
464
465 return combiner(tr(first), tr(last));
466 }
467 };
468
469
471 template<typename _type>
472 using GDefaultLastValueInvoker
473 = GCombinerInvoker<_type, ystdex::default_last_value<_type>>;
474
476 template<typename _type>
477 using GOptionalLastValueInvoker = GCombinerInvoker<ystdex::cond_t<std::is_void<
478 _type>, void, ystdex::optional<_type>>, ystdex::optional_last_value<_type>>;
479
480
481
487 template<typename, typename = CountedHandlerInvoker>
488 class GEvent;
489
494 template<typename _tRet, typename... _tParams, typename _tInvoker>
495 class GEvent<_tRet(_tParams...), _tInvoker>
496 {
497 public:
499
500 using HandlerType = GHEvent<_tRet(_tParams...)>;
501 using FuncType = typename HandlerType::FuncType;
503
507 using ContainerType
508 = multimap<EventPriority, HandlerType, std::greater<EventPriority>>;
510 using InvokerType = _tInvoker;
512 using allocator_type = typename ContainerType::allocator_type;
514
515 using const_iterator = typename ContainerType::const_iterator;
516 using const_reference = typename ContainerType::const_reference;
517 using const_reverse_iterator
518 = typename ContainerType::const_reverse_iterator;
519 using iterator = typename ContainerType::iterator;
520 using reference = typename ContainerType::reference;
521 using reverse_iterator = typename ContainerType::reverse_iterator;
522 using size_type = typename ContainerType::size_type;
523 using value_type = typename ContainerType::value_type;
525 using result_type = decltype(std::declval<_tInvoker&>()(
527 std::declval<const_iterator>(), std::declval<const_iterator>(),
528 std::declval<_tParams>()...));
529
534 InvokerType Invoker{};
535
536 private:
541 ContainerType handlers{};
542
543 public:
548 DefDeCtor(GEvent)
550 GEvent(allocator_type a)
551 : handlers(a)
552 {}
557 GEvent(InvokerType ivk)
558 : Invoker(std::move(ivk))
559 {}
561 GEvent(InvokerType ivk, allocator_type a)
562 : Invoker(std::move(ivk)), handlers(a)
563 {}
568 template<typename _tHandler, yimpl(typename = ystdex::exclude_self_t<GEvent,
569 _tHandler>, typename = ystdex::enable_if_t<
570 std::is_constructible<HandlerType, _tHandler>::value>)>
571 GEvent(_tHandler h, InvokerType ivk = {})
572 : Invoker(std::move(ivk))
573 {
574 Add(std::move(h));
575 }
577
578 template<typename _tHandler, yimpl(typename = ystdex::exclude_self_t<GEvent,
579 _tHandler>, typename = ystdex::enable_if_t<
580 std::is_constructible<HandlerType, _tHandler>::value>)>
581 GEvent(_tHandler h, InvokerType ivk, allocator_type a)
582 : Invoker(std::move(ivk)), handlers(a)
583 {
584 Add(std::move(h), a);
585 }
586 GEvent(const GEvent& e, allocator_type a)
587 : Invoker(e.Invoker), handlers(e.handlers, a)
588 {}
589 GEvent(GEvent&& e, allocator_type a)
590 : Invoker(std::move(e.Invoker)), handlers(std::move(e.handlers), a)
591 {}
593 DefDeCopyMoveCtorAssignment(GEvent)
595
596
600 template<typename _tHandler,
601 yimpl(typename = ystdex::exclude_self_t<GEvent, _tHandler>)>
602 inline GEvent&
603 operator=(_tHandler&& arg)
604 {
605 return *this = GEvent(yforward(arg));
606 }
607
609
610
614 inline PDefHOp(GEvent&, +=, const HandlerType& h)
615 ImplRet(Add(h))
620 inline PDefHOp(GEvent&, +=, HandlerType&& h)
621 ImplRet(Add(std::move(h)))
627 template<typename _type,
628 yimpl(typename = ystdex::exclude_self_t<HandlerType, _type>)>
629 inline GEvent&
630 operator+=(_type&& arg)
631 {
632 return Add(HandlerType(yforward(arg)));
633 }
634
636 GEvent&
637 operator-=(const HandlerType& h)
638 {
639 ystdex::erase_all_if<ContainerType>(handlers, handlers.cbegin(),
640 handlers.cend(), [&](decltype(*handlers.cbegin()) pr){
641 return pr.second == h;
642 });
643 return *this;
644 }
649 inline PDefHOp(GEvent&, -=, HandlerType&& h)
650 ImplRet(*this -= static_cast<const HandlerType&>(h))
655 template<typename _type,
656 yimpl(typename = ystdex::exclude_self_t<HandlerType, _type>)>
657 inline GEvent&
658 operator-=(_type&& arg)
659 {
660 return *this -= HandlerType(yforward(arg));
661 }
663
671 template<typename _type>
673 inline GEvent&
674 Add(_type&& arg, EventPriority prior = DefaultEventPriority)
675 {
676 Insert(yforward(arg), prior);
677 return *this;
678 }
683 template<class _tObj, class _type>
684 inline GEvent&
685 Add(_tObj& obj, _tRet(_type::*pm)(_tParams...),
686 EventPriority prior = DefaultEventPriority)
687 {
688 Insert(obj, pm, prior);
689 return *this;
690 }
692
694
695 PDefH(typename ContainerType::iterator, Emplace, EventPriority prior,
696 const HandlerType& h)
697 ImplRet(handlers.emplace(std::piecewise_construct,
698 YSLib::forward_as_tuple(prior), YSLib::forward_as_tuple(h)))
699 PDefH(typename ContainerType::iterator, Emplace, EventPriority prior,
700 HandlerType&& h)
701 ImplRet(handlers.emplace(std::piecewise_construct,
702 YSLib::forward_as_tuple(prior),
703 YSLib::forward_as_tuple(std::move(h))))
704 template<typename... _tEmplaceParams, yimpl(typename
705 = ystdex::exclude_self_params_t<HandlerType, _tEmplaceParams...>)>
706 inline typename ContainerType::iterator
707 Emplace(EventPriority prior, _tEmplaceParams&&... args)
708 {
709 return handlers.emplace(std::piecewise_construct,
710 YSLib::forward_as_tuple(prior), YSLib::forward_as_tuple(
711 std::allocator_arg, handlers.get_allocator(), yforward(args)...));
712 }
714
721 template<typename _type>
723 inline typename ContainerType::iterator
724 Insert(_type&& arg, EventPriority prior = DefaultEventPriority)
725 {
726 return Emplace(prior, yforward(arg));
727 }
729 template<class _tObj, class _type>
730 inline typename ContainerType::iterator
731 Insert(_tObj& obj, _tRet(_type::*pm)(_tParams...),
732 EventPriority prior = DefaultEventPriority)
733 {
734 return Emplace(prior, obj, pm);
735 }
737
742 template<class _tObj, class _type>
743 inline GEvent&
744 Remove(_tObj& obj, _tRet(_type::*pm)(_tParams...))
745 {
746 return *this -= HandlerType(static_cast<_type&>(obj), std::move(pm));
747 }
748
753 bool
754 Contains(const HandlerType& h) const
755 {
756 using ystdex::get_value;
757
758 return std::count(handlers.cbegin() | get_value,
759 handlers.cend() | get_value, h) != 0;
760 }
765 template<typename _type>
766 inline bool
767 Contains(_type&& arg) const
768 {
769 return Contains(HandlerType(yforward(arg)));
770 }
771
776 PDefHOp(result_type, (), _tParams... args) const
777 ImplRet(Invoker(handlers.cbegin() | ystdex::get_value,
778 handlers.cend() | ystdex::get_value, yforward(args)...))
779
780
781 YB_ATTR_nodiscard YB_PURE PDefH(const_iterator, cbegin, ) const ynothrow
782 ImplRet(handlers.cbegin())
783
785
786 YB_ATTR_nodiscard YB_PURE PDefH(iterator, begin, ) ynothrow
787 ImplRet(handlers.begin())
788 YB_ATTR_nodiscard YB_PURE PDefH(iterator, begin, ) const ynothrow
789 ImplRet(handlers.begin())
790
792 YB_ATTR_nodiscard YB_PURE PDefH(const_iterator, cend, ) const ynothrow
793 ImplRet(handlers.cend())
794
796 PDefH(void, clear, ) ynothrow
797 ImplRet(handlers.clear())
798
800
801 YB_ATTR_nodiscard YB_PURE PDefH(size_type, count, EventPriority prior) const
802 ynothrow
803 ImplRet(handlers.count(prior))
804
805 YB_ATTR_nodiscard YB_PURE
806 PDefH(const_reverse_iterator, crbegin, ) const ynothrow
807 ImplRet(handlers.crbegin())
808
809 YB_ATTR_nodiscard YB_PURE
810 PDefH(const_reverse_iterator, crend, ) const ynothrow
811 ImplRet(handlers.crend())
813
814 YB_ATTR_nodiscard PDefH(bool, empty, ) const ynothrow
815 ImplRet(handlers.empty())
816
817 YB_ATTR_nodiscard YB_PURE PDefH(iterator, end, ) ynothrow
818 ImplRet(handlers.end())
819 YB_ATTR_nodiscard YB_PURE PDefH(iterator, end, ) const ynothrow
820 ImplRet(handlers.end())
822
824 YB_ATTR_nodiscard YB_PURE
825 PDefH(allocator_type, get_allocator, ) const ynothrow
826 ImplRet(handlers.get_allocator())
827
829
830 YB_ATTR_nodiscard YB_PURE PDefH(reverse_iterator, rbegin, ) ynothrow
831 ImplRet(handlers.rbegin())
832
833 YB_ATTR_nodiscard YB_PURE PDefH(reverse_iterator, rend, ) ynothrow
834 ImplRet(handlers.rend())
835
837 YB_ATTR_nodiscard YB_PURE PDefH(size_type, size, ) const ynothrow
838 ImplRet(handlers.size())
840
845 friend PDefH(void, swap, GEvent& x, GEvent& y) ynothrow
846 ImplRet(x.handlers.swap(y.handlers))
847 };
849
850
856 template<typename _tRet, typename... _tParams>
857 inline GEvent<_tRet(_tParams...)>&
858 AddUnique(GEvent<_tRet(_tParams...)>& evt,
859 const typename GEvent<_tRet(_tParams...)>::HandlerType& h,
860 EventPriority prior = DefaultEventPriority)
861 {
862 return (evt -= h).Add(h, prior);
863 }
864 template<typename _tRet, typename... _tParams>
865 inline GEvent<_tRet(_tParams...)>&
866 AddUnique(GEvent<_tRet(_tParams...)>& evt, typename GEvent<_tRet(_tParams...)>
867 ::HandlerType&& h, EventPriority prior = DefaultEventPriority)
868 {
869 return (evt -= h).Add(std::move(h), prior);
870 }
871 template<typename _type, typename _tRet, typename... _tParams>
872 inline GEvent<_tRet(_tParams...)>&
873 AddUnique(GEvent<_tRet(_tParams...)>& evt, _type&& arg,
874 EventPriority prior = DefaultEventPriority)
875 {
876 return AddUnique(evt, HandlerType(yforward(arg)), prior);
877 }
879 template<class _type, typename _tRet, typename... _tParams>
880 inline GEvent<_tRet(_tParams...)>&
881 AddUnique(GEvent<_tRet(_tParams...)>& evt, _type& obj,
882 _tRet(_type::*pm)(_tParams...), EventPriority prior = DefaultEventPriority)
883 {
884 return AddUnique(evt, HandlerType(static_cast<_type&>(obj), std::move(pm)),
885 prior);
886 }
888
889
894 #define DefExtendEventMap(_n, _b) \
895 DefExtendClass(YF_API, _n, public _b)
896
897 } // namespace YSLib;
898
899 #endif
900
ystdex::get_value
const second_tag get_value
Definition: iterator.hpp:560
YB_ATTR_nodiscard
#define YB_ATTR_nodiscard
标记返回值不被忽略的属性。
Definition: ydef.h:715
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:112
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
YSLib::swap
void swap(ValueNode &x, ValueNode &y) ynothrowv
Definition: ValueNode.cpp:95
size
size_t size
Definition: memory_resource.cpp:295
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::ContainerType
multimap< EventPriority, HandlerType, std::greater< EventPriority > > ContainerType
容器类型。
Definition: YEvent.hpp:508
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::const_reference
typename ContainerType::const_reference const_reference
Definition: YEvent.hpp:516
YSLib::AddUnique
GEvent< _tRet(_tParams...)> & AddUnique(GEvent< _tRet(_tParams...)> &evt, const typename GEvent< _tRet(_tParams...)>::HandlerType &h, EventPriority prior=DefaultEventPriority)
添加单一事件响应：删除后添加。
Definition: YEvent.hpp:858
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::InvokerType
_tInvoker InvokerType
Definition: YEvent.hpp:510
YSLib::GHEvent< _tRet(_tParams...)>
Definition: YEvent.hpp:67
YSLib::GEvent
事件模板。
Definition: YEvent.hpp:488
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:1072
YSLib::GCombinerInvoker::operator()
result_type operator()(_tIn first, _tIn last, _tParams &&... args) const
Definition: YEvent.hpp:443
base.h
基类实用设施。
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:919
YSLib::GHEvent< _tRet(_tParams...)>::GEqualityExpanded::AreEqual
YB_ATTR_nodiscard static YB_PURE bool AreEqual(const GHEvent &x, const GHEvent &y) ynoexcept_spec(ystdex
Definition: YEvent.hpp:118
YB_ATTR_LAMBDA_QUAL
#define YB_ATTR_LAMBDA_QUAL(_q,...)
允许在 lambda 表达式的参数列表后和限定符共用的属性。
Definition: ydef.h:619
YSLib::GHEvent< _tRet(_tParams...)>::EqualsUnchecked
YB_ATTR_nodiscard YB_PURE bool EqualsUnchecked(const GHEvent &x) const
Definition: YEvent.hpp:342
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: meta.hpp:199
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::reference
typename ContainerType::reference reference
Definition: YEvent.hpp:520
ystdex::dep_ops::equality_comparable
_t< details::ops_seq< _type, _type2, _tOpt, cond_t< is_same< _type, _type2 >, index_sequence< 7 >, index_sequence< 6, 7, 8 > >> > equality_comparable
Definition: operators.hpp:265
YSLib::GHEvent< _tRet(_tParams...)>::GEquality::AreEqual
YB_ATTR_nodiscard static YB_PURE bool AreEqual(const GHEvent &x, const GHEvent &y) ynoexcept_spec(ystdex
Definition: YEvent.hpp:95
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
GHEvent(std::allocator_arg_t, const _tAlloc &a, GHEvent &&x)
Definition: YEvent.hpp:244
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::iterator
typename ContainerType::iterator iterator
Definition: YEvent.hpp:519
YSLib::GHEvent< _tRet(_tParams...)>::Comparer
bool(*)(const GHEvent &, const GHEvent &) Comparer
比较函数类型。
Definition: YEvent.hpp:82
ystdex::exclude_self_params_t
enable_if_t< not_< cond_or_t< bool_< sizeof...(_tParams)==1 >, false_, is_same_param, _tSelected, _tParams... > >::value, void > exclude_self_params_t
排除选择类型的特定参数类型的重载。
Definition: type_op.hpp:295
ystdex::expanded_function
扩展函数包装类模板。
Definition: functional.hpp:644
swap.hpp
交换操作。
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:1181
YSLib::GHEvent< _tRet(_tParams...)>::Equals
YB_ATTR_nodiscard YB_PURE bool Equals(const GHEvent &x) const
Definition: YEvent.hpp:324
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::size_type
typename ContainerType::size_type size_type
Definition: YEvent.hpp:522
ystdex::nullptr_t
空指针类。
Definition: ydef.h:1321
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::allocator_type
typename ContainerType::allocator_type allocator_type
Definition: YEvent.hpp:512
ystdex::rend
reverse_iterator< _type * > rend(_type(&&array)[_vN])
Definition: range.hpp:397
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
yconstfn GHEvent(_type &obj, _tRet(_type::*pm)(_tParams...))
构造：使用对象引用和成员函数指针。
Definition: YEvent.hpp:213
YSLib::GHEvent< _tRet(_tParams...)>::DefDeCopyMoveCtorAssignment
DefDeCopyMoveCtorAssignment(GHEvent) YB_ATTR_nodiscard YB_PURE friend PDefHOp(bool
比较相等：参数都为空或都非空且存储的对象相等。
YSLib::operator!=
bool operator!=(const shared_ptr< _type > &sp, _type *p)
比较： shared_ptr 左值和内建指针类型的不等关系。
Definition: YShellDefinition.h:84
CHRLib::f
f(d, s)
yconstfn_relaxed
#define yconstfn_relaxed
指定编译时没有 C++11 限制和隐式成员 const 的常量函数。
Definition: ydef.h:1097
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
GHEvent(std::allocator_arg_t, const _tAlloc &a, _fCallable &&f)
使用分配器和函数对象。
Definition: YEvent.hpp:178
ystdex::swap_dependent
void swap_dependent(_type &x, _type &y)(is_nothrow_swappable< _type >())
支持基于 ystdex_swap::swap 的 ADL 的左值交换。
Definition: swap.hpp:371
ystdex::is_decayed
判断指定类型是否已退化为指定类型。
Definition: meta.hpp:672
YSLib::GHEvent< _tRet(_tParams...)>::HaveSameTargetType
YB_ATTR_nodiscard static YB_PURE bool HaveSameTargetType(const GHEvent &x, const GHEvent &y)
判断持有的对象具有相同的动态类型。
Definition: YEvent.hpp:351
ystdex::cpp2014::cbegin
auto cbegin(const _tRange &c) -> decltype(ystdex::begin(c))
Definition: range.hpp:418
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::DefDeCtor
DefDeCtor(GEvent) GEvent(allocator_type a)
无参数构造：默认实现。
Definition: YEvent.hpp:548
ystdex::cpp2014::cend
auto cend(const _tRange &c) -> decltype(ystdex::end(c))
Definition: range.hpp:427
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::GEvent
GEvent(InvokerType ivk)
构造：使用指定调用器。
Definition: YEvent.hpp:557
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::GEvent
GEvent(GEvent &&e, allocator_type a)
Definition: YEvent.hpp:589
ystdex::cpp2014::decay_t
typename decay< _type >::type decay_t
Definition: meta.hpp:196
ystdex::cpp2017::optional
可选值对象包装。
Definition: optional.h:81
YSLib::EventPriority
std::uint8_t EventPriority
事件优先级。
Definition: YEvent.hpp:396
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
GHEvent(_fCallable f)
使用函数对象。
Definition: YEvent.hpp:168
ystdex::cpp2017::optional_last_value
合并可选值序列。
Definition: optional.h:958
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
GHEvent(std::allocator_arg_t, const _tAlloc &a, const GHEvent &x)
Definition: YEvent.hpp:237
DefDeCopyMoveCtorAssignment
#define DefDeCopyMoveCtorAssignment(_t)
Definition: YBaseMacro.h:202
YSLib::YAssert
YAssert(!(v< Deref(a)), "Value less than lower bound found.")
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::value_type
typename ContainerType::value_type value_type
Definition: YEvent.hpp:523
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
YSLib::GCombinerInvoker::result_type
_type result_type
Definition: YEvent.hpp:435
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
yconstfn GHEvent(std::allocator_arg_t, const _tAlloc &a, _type &obj, _tRet(_type::*pm)(_tParams...))
Definition: YEvent.hpp:223
YSLib::GHEvent< _tRet(_tParams...)>::swap
swap(x.comp_eq, y.comp_eq)
ystdex::cpp2017::end
auto end(_tRange &c) -> decltype(c.end())
Definition: range.hpp:345
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::GEvent
GEvent(InvokerType ivk, allocator_type a)
Definition: YEvent.hpp:561
YSLib::GHEvent
标准事件处理器模板。
Definition: YEvent.hpp:59
std
Definition: optional.h:982
iterator.hpp
通用迭代器。
YSLib::GCombinerInvoker
结果组合调用器。
Definition: YEvent.hpp:431
YSLib::GHEvent::operator==
yconstfn bool operator==(const GHEvent< _tRet(_tParams...)> &x, nullptr_t)
Definition: YEvent.hpp:386
YSLib::yimpl
YF_API yimpl(GUIApplication &) FetchGlobalInstance()
取全局应用程序实例。
ystdex::is_expandable
is_constructible< _func, expanded_caller< as_function_type_t< _func >, _fCallable > > is_expandable
判断可调用类型是可展开到指定函数对象的类型。
Definition: functional.hpp:629
container.hpp
通用容器操作。
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::reverse_iterator
typename ContainerType::reverse_iterator reverse_iterator
Definition: YEvent.hpp:521
operators.hpp
重载操作符。
YSLib::i
return i
Definition: YCoreUtilities.h:177
type_op.hpp
C++ 类型操作。
YSLib::GCombinerInvoker::combiner
_tCombiner combiner
Definition: YEvent.hpp:438
YSLib::GHEvent< _tRet(_tParams...)>::comp_eq
Comparer comp_eq
比较函数：相等关系。
Definition: YEvent.hpp:140
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::const_reverse_iterator
typename ContainerType::const_reverse_iterator const_reverse_iterator
Definition: YEvent.hpp:518
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1535
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::const_iterator
typename ContainerType::const_iterator const_iterator
Definition: YEvent.hpp:515
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::FuncType
typename HandlerType::FuncType FuncType
Definition: YEvent.hpp:501
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::GEvent
GEvent(_tHandler h, InvokerType ivk={})
构造：使用指定调用器并添加事件处理器。
Definition: YEvent.hpp:571
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
platform::containers::multimap
std::multimap< _tKey, _tMapped, _fComp, _tAlloc > multimap
Definition: Container.h:118
ystdex::cond_t
_t< cond< _tCond, _tThen, _tElse > > cond_t
Definition: meta.hpp:794
ystdex::expanded_caller
接受冗余参数的可调用对象。
Definition: functional.hpp:574
YModules.h
YSLib 用户界面模块配置文件。
platform::KeyCodes::DS::Insert
@ Insert
Definition: Keys.h:261
ystdex::exclude_self_t
enable_if_t<!is_same_param< _tSelected, _tParam >::value, _type > exclude_self_t
排除选择类型的特定参数的重载。
Definition: meta.hpp:865
optional.h
可选值包装类型。
YSLib::ynothrow
YB_PURE const _type size_t n ynothrow
Definition: YCoreUtilities.h:169
ystdex::cpp2017::crbegin
auto crbegin(const _tRange &c) -> decltype(ystdex::rbegin(c))
Definition: range.hpp:506
YSLib::GHEvent< _tRet(_tParams...)>::FuncType
_tRet(_tParams...) FuncType
Definition: YEvent.hpp:69
platform::Deref
YB_PURE yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:547
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::result_type
decltype(std::declval< _tInvoker & >()(std::declval< const_iterator >(), std::declval< const_iterator >(), std::declval< _tParams >()...)) result_type
Definition: YEvent.hpp:528
YSLib::ImplRet
ImplRet(FetchGlobalInstance().GetGUIHostRef()) YF_API void Execute(GUIApplication &
执行程序主消息循环。
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
GHEvent(std::allocator_arg_t, const _tAlloc &a, FuncType *f={}) ynothrow
构造：使用分配器和函数指针。
Definition: YEvent.hpp:156
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
ystdex::cpp2017::crend
auto crend(const _tRange &c) -> decltype(ystdex::rend(c))
Definition: range.hpp:513
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::examiners::equal::are_equal
static auto are_equal(_type &&x, _type2 &&y) -> decltype(bool(x==y))
Definition: examiner.hpp:53
YSLib::GHEvent< _tRet(_tParams...)>::enable_if_expandable_t
ystdex::enable_if_t< !std::is_constructible< function< FuncType >, _fCallable >::value &&ystdex::is_expandable< function< FuncType >, _fCallable >::value > enable_if_expandable_t
Definition: YEvent.hpp:80
YSLib::GHEvent< _tRet(_tParams...)>::Equals
YB_ATTR_nodiscard YB_PURE bool Equals(const _type &x) const
Definition: YEvent.hpp:330
YSLib::DefaultEventPriority
yconstexpr const EventPriority DefaultEventPriority(0x80)
默认事件优先级。
YSLib::GHEvent< _tRet(_tParams...)>::GHEvent
GHEvent(std::allocator_arg_t, const _tAlloc &a, _fCallable f)
使用分配器和扩展函数对象。
Definition: YEvent.hpp:196
platform::p
return p p
Definition: YCLib/FileSystem.h:209
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::GEvent
GEvent(_tHandler h, InvokerType ivk, allocator_type a)
Definition: YEvent.hpp:581
YSLib::GHEvent< _tRet(_tParams...)>::DefSwap
friend yconstfn_relaxed DefSwap(ynothrow, Comparer, ystdex::swap_dependent(_x, _y)) friend void swap(GHEvent &x
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
ystdex::rbegin
reverse_iterator< _type * > rbegin(_type(&&array)[_vN])
Definition: range.hpp:390
platform::bool
YB_ATTR_nodiscard std::FILE *fp bool
Definition: FileIO.h:1271
YSLib::GEvent< _tRet(_tParams...), _tInvoker >::GEvent
GEvent(const GEvent &e, allocator_type a)
Definition: YEvent.hpp:586
YSLib::args
YB_ATTR_nodiscard YB_PURE typename _tParams && args
Definition: ValueNode.h:1299
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:1151
NPL::get
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(NPL ref get()
Definition: NPLA.h:1737
ystdex::ref
void ref(const _type &&)=delete
YSLib::GHEvent< _tRet(_tParams...)>::Equals
YB_ATTR_nodiscard YB_PURE bool Equals(nullptr_t) const
判断相等。
Definition: YEvent.hpp:318
YSLib::PDefH
PDefH(Environment &, FetchEnvironment,) ImplRet(FetchGlobalInstance().GetEnvironmentRef()) inline PDefH(GUIHost &
取单一环境对象引用。
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::cpp2017::begin
auto begin(_tRange &c) -> decltype(c.begin())
Definition: range.hpp:323
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:168
YSLib::CountedHandlerInvoker
计数调用器：调用事件处理器并计数。
Definition: YEvent.hpp:410
YSLib::CountedHandlerInvoker::operator()
size_t operator()(_tIn first, _tIn last, _tParams &&... args) const
Definition: YEvent.hpp:414