Nui
Loading...
Searching...
No Matches
observed_value.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <nui/concepts.hpp>
9
10#include <memory>
11#include <vector>
12#include <functional>
13#include <type_traits>
14#include <list>
15#include <utility>
16#include <deque>
17#include <string>
18#include <cassert>
19#include <set>
20#include <concepts>
21#include <iterator>
22#include <exception>
23
24namespace Nui
25{
29
31 {
32 public:
38 virtual ~ObservedBase() = default;
39 ObservedBase(ObservedBase const&) = delete;
40 ObservedBase(ObservedBase&& other) noexcept
41 : eventContext_{other.eventContext_}
44 {
45 // events are outside the value logic of the observed class. the contained value is moved, but the events
46 // are merged.
47 try
48 {
49 attachedEvents_.reserve(attachedEvents_.size() + other.attachedEvents_.size());
50 attachedOneshotEvents_.reserve(attachedOneshotEvents_.size() + other.attachedOneshotEvents_.size());
51
52 for (auto& event : other.attachedEvents_)
53 {
54 // Dont want to lose the move if event becomes non trivial
55 // NOLINTNEXTLINE(performance-move-const-arg, hicpp-move-const-arg)
56 attachedEvents_.push_back(std::move(event));
57 }
58 for (auto& event : other.attachedOneshotEvents_)
59 {
60 // Dont want to lose the move if event becomes non trivial
61 // NOLINTNEXTLINE(performance-move-const-arg, hicpp-move-const-arg)
62 attachedOneshotEvents_.push_back(std::move(event));
63 }
64 }
65 catch (...)
66 {
67 std::terminate();
68 }
69 }
72 {
73 eventContext_ = other.eventContext_;
74 try
75 {
76 attachedEvents_.reserve(attachedEvents_.size() + other.attachedEvents_.size());
77 attachedOneshotEvents_.reserve(attachedOneshotEvents_.size() + other.attachedOneshotEvents_.size());
78
79 for (auto& event : other.attachedEvents_)
80 {
81 // Dont want to lose the move if event becomes non trivial
82 // NOLINTNEXTLINE(performance-move-const-arg, hicpp-move-const-arg)
83 attachedEvents_.push_back(std::move(event));
84 }
85 for (auto& event : other.attachedOneshotEvents_)
86 {
87 // Dont want to lose the move if event becomes non trivial
88 // NOLINTNEXTLINE(performance-move-const-arg, hicpp-move-const-arg)
89 attachedOneshotEvents_.push_back(std::move(event));
90 }
91 }
92 catch (...)
93 {
94 std::terminate();
95 }
96
97 return *this;
98 }
99
101 {
102 attachedEvents_.emplace_back(eventId);
103 }
105 {
106 attachedOneshotEvents_.emplace_back(eventId);
107 }
109 {
110 attachedEvents_.erase(
111 std::remove(std::begin(attachedEvents_), std::end(attachedEvents_), eventId),
112 std::end(attachedEvents_));
113 }
114
115 std::size_t attachedEventCount() const
116 {
117 return attachedEvents_.size();
118 }
119 std::size_t attachedOneshotEventCount() const
120 {
121 return attachedOneshotEvents_.size();
122 }
123 std::size_t totalAttachedEventCount() const
124 {
125 return attachedEvents_.size() + attachedOneshotEvents_.size();
126 }
127
132 {
133 attachedEvents_.clear();
135 }
136
137 virtual void update(bool /*force*/ = false) const
138 {
139 NUI_ASSERT(eventContext_ != nullptr, "Event context must never be null.");
140
141 for (auto& event : attachedEvents_)
142 {
143 auto activationResult = eventContext_->activateEvent(event);
144 if (!activationResult.found)
146 }
147 for (auto& event : attachedOneshotEvents_)
150 attachedEvents_.erase(
151 std::remove(std::begin(attachedEvents_), std::end(attachedEvents_), EventRegistry::invalidEventId),
152 std::end(attachedEvents_));
153 }
154
155 void updateNow(bool force = false) const
156 {
157 NUI_ASSERT(eventContext_ != nullptr, "Event context must never be null.");
158
159 update(force);
161 }
162
163 protected:
165 mutable std::vector<EventContext::EventIdType> attachedEvents_;
166 mutable std::vector<EventContext::EventIdType> attachedOneshotEvents_;
167 };
168
169 template <typename ContainedT>
171 {
172 public:
173 using value_type = ContainedT;
174
175 public:
177 {
178 public:
180 : observed_{&observed}
181 , now_{false}
182 {}
183 explicit ModificationProxy(ModifiableObserved& observed, bool now)
184 : observed_{&observed}
185 , now_{now}
186 {}
190 : observed_{other.observed_}
191 , now_{other.now_}
192 {
193 other.observed_ = nullptr;
194 }
196 {
197 if (this != &other)
198 {
199 observed_ = other.observed_;
200 now_ = other.now_;
201 other.observed_ = nullptr;
202 }
203 return *this;
204 }
206 {
207 try
208 {
209 if (observed_ == nullptr)
210 return;
211
212 if (now_)
213 observed_->updateNow(true);
214 else
215 observed_->update(true);
216 }
217 // NOLINTNEXTLINE(bugprone-empty-catch)
218 catch (...)
219 {
220 // TODO: log?
221 }
222 }
223 auto& value()
224 {
225 return observed_->contained_;
226 }
228 {
229 return &observed_->contained_;
230 }
231 auto& operator*()
232 {
233 return observed_->contained_;
234 }
235 explicit operator ContainedT&()
236 {
237 return observed_->contained_;
238 }
239
240 private:
241 ModifiableObserved* observed_;
242 bool now_;
243 };
244
245 public:
252 : ObservedBase{std::move(other)}
253 , contained_{std::move(other.contained_)}
254 {
255 update();
256 };
259 {
260 if (this != &other)
261 {
262 ObservedBase::operator=(std::move(other));
263 contained_ = std::move(other.contained_);
264 update();
265 }
266 return *this;
267 };
268 ModifiableObserved& operator=(ContainedT const& contained)
269 {
270 contained_ = contained;
271 update();
272 return *this;
273 }
274 ModifiableObserved& operator=(ContainedT&& contained)
275 {
276 contained_ = std::move(contained);
277 update();
278 return *this;
279 }
280 ~ModifiableObserved() override = default;
281
282 template <typename T = ContainedT>
283 requires std::is_constructible_v<ContainedT, T>
284 explicit ModifiableObserved(T&& t)
286 , contained_{std::forward<T>(t)}
287 {}
288
293
294 template <typename T = ContainedT>
295 requires std::is_constructible_v<ContainedT, T>
300
307 template <typename T = ContainedT>
309 {
310 contained_ = std::forward<T>(t);
311 update();
312 return *this;
313 }
314
315 template <typename T = ContainedT, typename U>
316 requires PlusAssignable<T, U>
318 {
319 this->contained_ += rhs;
320 return *this;
321 }
322 template <typename T = ContainedT, typename U>
323 requires MinusAssignable<T, U>
325 {
326 this->contained_ -= rhs;
327 return *this;
328 }
329
330 template <typename T = ContainedT>
331 requires std::equality_comparable_with<ContainedT, T> && Fundamental<T> && Fundamental<ContainedT>
333 {
334 assignChecked(std::forward<T>(t));
335 return *this;
336 }
337
338 template <typename T = ContainedT>
339 requires std::equality_comparable_with<ContainedT, T>
341 {
342 if (contained_ != other)
343 {
344 contained_ = std::forward<T>(other);
345 update();
346 }
347 return *this;
348 }
349
357 {
358 return ModificationProxy{*this};
359 }
360
362 {
363 return ModificationProxy{*this, true};
364 }
365
366 explicit operator bool() const
367 requires std::convertible_to<ContainedT, bool>
368 {
369 return static_cast<bool>(contained_);
370 }
371
372 ContainedT& value()
373 {
374 return contained_;
375 }
376 ContainedT const& value() const
377 {
378 return contained_;
379 }
380 ContainedT& operator*()
381 {
382 return contained_;
383 }
384 ContainedT const& operator*() const
385 {
386 return contained_;
387 }
388 ContainedT* operator->()
389 {
390 return &contained_;
391 }
392 ContainedT const* operator->() const
393 {
394 return &contained_;
395 }
396
400 template <typename T>
401 requires std::constructible_from<ContainedT, T>
403 {
404 contained_ = std::forward<ContainedT>(t);
405 }
406
407 protected:
408 ContainedT contained_;
409 };
410
411 template <typename ContainerT>
412 class ObservedContainer;
413
414 namespace ContainerWrapUtility
415 {
416 template <typename T, typename ContainerT>
417 class ReferenceWrapper
418 {
419 public:
420 ReferenceWrapper(ObservedContainer<ContainerT>* owner, std::size_t pos, T& ref)
421 : owner_{owner}
422 , pos_{pos}
423 , ref_{&ref}
424 {}
425 ReferenceWrapper(ReferenceWrapper const&) = default;
426 ReferenceWrapper(ReferenceWrapper&& other) noexcept
427 : owner_{other.owner_}
428 , pos_{other.pos_}
429 , ref_{other.ref_}
430 {
431 other.owner_ = nullptr;
432 other.pos_ = 0;
433 other.ref_ = nullptr;
434 }
435 ReferenceWrapper& operator=(ReferenceWrapper const&) = default;
436 ReferenceWrapper& operator=(ReferenceWrapper&& other) noexcept
437 {
438 if (this != &other)
439 {
440 owner_ = other.owner_;
441 pos_ = other.pos_;
442 ref_ = other.ref_;
443 other.owner_ = nullptr;
444 other.pos_ = 0;
445 other.ref_ = nullptr;
446 }
447 return *this;
448 }
449 ~ReferenceWrapper() = default;
450 // NOLINTNEXTLINE(hicpp-explicit-conversions)
451 operator T&()
452 {
453 return *ref_;
454 }
455 T& operator*()
456 {
458 return *ref_;
459 }
460 T const& operator*() const
461 {
462 return *ref_;
463 }
464 T* operator->()
465 {
466 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
467 return ref_;
468 }
469 T const* operator->() const
470 {
471 return ref_;
472 }
473 T& get()
474 {
475 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
476 return *ref_;
477 }
478 T const& getReadonly()
479 {
480 return *ref_;
481 }
482 ReferenceWrapper& operator=(T&& val)
483 {
484 *ref_ = std::move(val);
485 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
486 return *this;
487 }
488 ReferenceWrapper& operator=(T const& val)
489 {
490 *ref_ = val;
491 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
492 return *this;
493 }
494 bool operator==(ReferenceWrapper const& other) const
495 {
496 return *ref_ == *other.ref_;
497 }
498 bool operator==(T const& other) const
499 {
500 return *ref_ == other;
501 }
502
503 protected:
505 std::size_t pos_;
506 T* ref_;
507 };
508
509 template <typename T, typename ContainerT>
510 auto& unwrapReferenceWrapper(ReferenceWrapper<T, ContainerT>& wrapper)
511 {
512 return wrapper.get();
513 }
514 template <typename T, typename ContainerT>
515 auto const& unwrapReferenceWrapper(ReferenceWrapper<T, ContainerT> const& wrapper)
516 {
517 return wrapper.get();
518 }
519 auto& unwrapReferenceWrapper(auto& ref)
520 {
521 return ref;
522 }
523 auto const& unwrapReferenceWrapper(auto const& ref)
524 {
525 return ref;
526 }
527
528 template <typename T, typename ContainerT>
529 class PointerWrapper
530 {
531 public:
532 PointerWrapper(ObservedContainer<ContainerT>* owner, std::size_t pos, T* ptr) noexcept
533 : owner_{owner}
534 , pos_{pos}
535 , ptr_{ptr}
536 {}
537 // NOLINTNEXTLINE(hicpp-explicit-conversions)
538 operator T&()
539 {
540 return *ptr_;
541 }
542 T& operator*()
543 {
545 return *ptr_;
546 }
547 T const& operator*() const
548 {
549 return *ptr_;
550 }
551 T* operator->()
552 {
553 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
554 return ptr_;
555 }
556 T const* operator->() const
557 {
558 return ptr_;
559 }
560 T& get()
561 {
562 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
563 return *ptr_;
564 }
565 T const& getReadonly()
566 {
567 return *ptr_;
568 }
569 PointerWrapper& operator=(T* ptr)
570 {
571 ptr_ = ptr;
572 owner_->insertRangeChecked(pos_, pos_, RangeOperationType::Modify);
573 return *this;
574 }
575
576 protected:
578 std::size_t pos_;
579 T* ptr_;
580 };
581
582 template <typename WrappedIterator, typename ContainerT>
583 class IteratorWrapper
584 {
585 public:
586 using iterator_category = std::random_access_iterator_tag;
587 using value_type = typename WrappedIterator::value_type;
588 using difference_type = typename WrappedIterator::difference_type;
589 using pointer = PointerWrapper<value_type, ContainerT>;
590 using reference = ReferenceWrapper<value_type, ContainerT>;
591
592 public:
593 IteratorWrapper(ObservedContainer<ContainerT>* owner, WrappedIterator it)
594 : owner_{owner}
595 , it_{std::move(it)}
596 {}
597 IteratorWrapper(IteratorWrapper const&) = default;
598 IteratorWrapper(IteratorWrapper&&) = default;
599 IteratorWrapper& operator=(IteratorWrapper const&) = default;
600 IteratorWrapper& operator=(IteratorWrapper&&) = default;
601 ~IteratorWrapper() = default;
602 IteratorWrapper& operator+=(difference_type n)
603 {
604 it_ += n;
605 return *this;
606 }
607 IteratorWrapper& operator-=(difference_type n)
608 {
609 it_ -= n;
610 return *this;
611 }
612 IteratorWrapper& operator++()
613 {
614 ++it_;
615 return *this;
616 }
617 IteratorWrapper operator++(int)
618 {
619 return IteratorWrapper{it_++};
620 }
621 IteratorWrapper& operator--()
622 {
623 --it_;
624 return *this;
625 }
626 IteratorWrapper operator--(int)
627 {
628 return IteratorWrapper{it_--};
629 }
630 friend IteratorWrapper operator+(IteratorWrapper const& wrap, difference_type n)
631 {
632 return IteratorWrapper{wrap.owner_, wrap.it_ + n};
633 }
634 friend IteratorWrapper operator-(IteratorWrapper const& wrap, difference_type n)
635 {
636 return IteratorWrapper{wrap.owner_, wrap.it_ - n};
637 }
638 difference_type operator-(IteratorWrapper const& other) const
639 {
640 return it_ - other.it_;
641 }
642 auto operator*()
643 {
644 if constexpr (std::is_same_v<WrappedIterator, typename ContainerT::reverse_iterator>)
645 return ReferenceWrapper<value_type, ContainerT>{
646 owner_,
647 owner_->contained_.size() - static_cast<std::size_t>(1) -
648 static_cast<std::size_t>(it_ - owner_->contained_.rbegin()),
649 *it_};
650 else
651 return ReferenceWrapper<value_type, ContainerT>{
652 owner_, static_cast<std::size_t>(it_ - owner_->contained_.begin()), *it_};
653 }
654 auto operator*() const
655 {
656 return *it_;
657 }
658 auto operator->()
659 {
660 if constexpr (std::is_same_v<WrappedIterator, typename ContainerT::reverse_iterator>)
661 return PointerWrapper<value_type, ContainerT>{
662 owner_,
663 owner_->contained_.size() - static_cast<std::size_t>(1) -
664 static_cast<std::size_t>(it_ - owner_->contained_.rbegin()),
665 &*it_};
666 else
667 return PointerWrapper<value_type, ContainerT>{
668 owner_, static_cast<std::size_t>(it_ - owner_->contained_.begin()), &*it_};
669 }
670 auto operator->() const
671 {
672 return &*it_;
673 }
674 IteratorWrapper operator[](std::size_t offset) const
675 {
676 return IteratorWrapper{owner_, it_[offset]};
677 }
678 bool operator<(IteratorWrapper const& other) const
679 {
680 return it_ < other.it_;
681 }
682 bool operator>(IteratorWrapper const& other) const
683 {
684 return it_ > other.it_;
685 }
686 bool operator<=(IteratorWrapper const& other) const
687 {
688 return it_ <= other.it_;
689 }
690 bool operator>=(IteratorWrapper const& other) const
691 {
692 return it_ >= other.it_;
693 }
694 bool operator==(IteratorWrapper const& other) const
695 {
696 return it_ == other.it_;
697 }
698 WrappedIterator getWrapped() const
699 {
700 return it_;
701 }
702
703 private:
705 WrappedIterator it_;
706 };
707 };
708
709 template <typename ContainerT>
710 class ObservedContainer : public ModifiableObserved<ContainerT>
711 {
712 public:
713 friend class ContainerWrapUtility::ReferenceWrapper<typename ContainerT::value_type, ContainerT>;
714 friend class ContainerWrapUtility::PointerWrapper<typename ContainerT::value_type, ContainerT>;
715
716 using value_type = typename ContainerT::value_type;
717 using allocator_type = typename ContainerT::allocator_type;
718 using size_type = typename ContainerT::size_type;
719 using difference_type = typename ContainerT::difference_type;
720 using reference = ContainerWrapUtility::ReferenceWrapper<typename ContainerT::value_type, ContainerT>;
721 using const_reference = typename ContainerT::const_reference;
722 using pointer = ContainerWrapUtility::PointerWrapper<typename ContainerT::value_type, ContainerT>;
723 using const_pointer = typename ContainerT::const_pointer;
724
725 using iterator = ContainerWrapUtility::IteratorWrapper<typename ContainerT::iterator, ContainerT>;
726 using const_iterator = typename ContainerT::const_iterator;
728 ContainerWrapUtility::IteratorWrapper<typename ContainerT::reverse_iterator, ContainerT>;
729 using const_reverse_iterator = typename ContainerT::const_reverse_iterator;
730
731 using ModifiableObserved<ContainerT>::contained_;
732
733 public:
734 explicit ObservedContainer(CustomEventContextFlag_t, EventContext* ctx)
736 , rangeContext_{std::make_shared<RangeEventContext>()}
738 {}
740 : ModifiableObserved<ContainerT>{}
741 , rangeContext_{std::make_shared<RangeEventContext>()}
743 {}
744 template <typename T = ContainerT>
746 : ModifiableObserved<ContainerT>{CustomEventContextFlag, ctx, std::forward<T>(t)}
747 , rangeContext_{std::make_shared<RangeEventContext>()}
749 {}
750 template <typename T = ContainerT>
751 requires std::constructible_from<ContainerT, T>
752 explicit ObservedContainer(T&& t)
753 : ModifiableObserved<ContainerT>{std::forward<T>(t)}
754 , rangeContext_{std::make_shared<RangeEventContext>()}
756 {}
758 : ModifiableObserved<ContainerT>{}
759 , rangeContext_{std::make_shared<RangeEventContext>(std::move(rangeContext))}
761 {}
764 , rangeContext_{std::make_shared<RangeEventContext>(std::move(rangeContext))}
766 {}
767 template <typename T = ContainerT>
769 : ModifiableObserved<ContainerT>{std::forward<T>(t)}
770 , rangeContext_{std::make_shared<RangeEventContext>(std::move(rangeContext))}
772 {}
773 template <typename T = ContainerT>
775 : ModifiableObserved<ContainerT>{CustomEventContextFlag, ctx, std::forward<T>(t)}
776 , rangeContext_{std::make_shared<RangeEventContext>(std::move(rangeContext))}
778 {}
779
789
790 constexpr auto map(auto&& function) const;
791 constexpr auto map(auto&& function);
792
793 template <typename T = ContainerT>
795 {
796 contained_ = std::forward<T>(t);
797 rangeContext_->reset(true);
798 update();
799 return *this;
800 }
801 void assign(size_type count, const value_type& value)
802 {
803 contained_.assign(count, value);
804 rangeContext_->reset(true);
805 update();
806 }
807 template <typename Iterator>
808 void assign(Iterator first, Iterator last)
809 {
810 contained_.assign(first, last);
811 rangeContext_->reset(true);
812 update();
813 }
814 void assign(std::initializer_list<value_type> ilist)
815 {
816 contained_.assign(ilist);
817 rangeContext_->reset(true);
818 update();
819 }
820
821 // Element access
823 {
824 return reference{this, 0, contained_.front()};
825 }
827 {
828 return contained_.front();
829 }
831 {
832 return reference{this, contained_.size() - 1, contained_.back()};
833 }
835 {
836 return contained_.back();
837 }
838 pointer data() noexcept
839 {
840 return pointer{this, 0, contained_.data()};
841 }
842 const_pointer data() const noexcept
843 {
844 return contained_.data();
845 }
847 {
848 return reference{this, pos, contained_.at(pos)};
849 }
851 {
852 return contained_.at(pos);
853 }
855 {
856 return reference{this, pos, contained_[pos]};
857 }
859 {
860 return contained_[pos];
861 }
862
863 // Iterators
864 iterator begin() noexcept
865 {
866 return iterator{this, contained_.begin()};
867 }
868 const_iterator begin() const noexcept
869 {
870 return contained_.begin();
871 }
872 iterator end() noexcept
873 {
874 return iterator{this, contained_.end()};
875 }
876 const_iterator end() const noexcept
877 {
878 return contained_.end();
879 }
880 const_iterator cbegin() const noexcept
881 {
882 return contained_.cbegin();
883 }
884 const_iterator cend() const noexcept
885 {
886 return contained_.cend();
887 }
889 {
890 return reverse_iterator{this, contained_.rbegin()};
891 }
893 {
894 return contained_.rbegin();
895 }
897 {
898 return reverse_iterator{this, contained_.rend()};
899 }
901 {
902 return contained_.rend();
903 }
905 {
906 return contained_.crbegin();
907 }
909 {
910 return contained_.crend();
911 }
912
913 // Capacity
914 bool empty() const noexcept
915 {
916 return contained_.empty();
917 }
918 std::size_t size() const noexcept
919 {
920 return contained_.size();
921 }
922 template <typename U = ContainerT>
924 {
925 return contained_.max_size();
926 }
927 template <typename U = ContainerT>
928 Detail::PickFirst_t<void, decltype(std::declval<U>().reserve(std::declval<std::size_t>()))>
930 {
931 return contained_.reserve(capacity);
932 }
933 template <typename U = ContainerT>
935 {
936 return contained_.capacity();
937 }
938 template <typename U = ContainerT>
940 {
941 return contained_.shrink_to_fit();
942 }
943
944 // Modifiers
945 void clear()
946 {
947 contained_.clear();
948 rangeContext_->reset(true);
949 update();
950 }
951 template <typename U = ContainerT>
953 std::pair<typename ContainerT::iterator, bool>,
954 decltype(std::declval<U>().insert(std::declval<const value_type&>()))>
956 {
957 NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null.");
958
959 const auto result = contained_.insert(value);
960 rangeContext_->performFullRangeUpdate();
961 update();
963 return result;
964 }
965 template <typename U = ContainerT>
967 std::pair<typename ContainerT::iterator, bool>,
968 decltype(std::declval<U>().insert(std::declval<value_type&&>()))>
970 {
971 NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null.");
972
973 const auto result = contained_.insert(std::move(value));
974 rangeContext_->performFullRangeUpdate();
975 update();
977 return result;
978 }
980 {
981 return insert(pos.getWrapped(), value);
982 }
984 {
985 const auto distance = pos - cbegin();
986 auto it = contained_.insert(pos, value);
988 return iterator{this, it};
989 }
991 {
992 return insert(pos.getWrapped(), std::move(value));
993 }
995 {
996 const auto distance = pos - cbegin();
997 auto it = contained_.insert(pos, std::move(value));
999 return iterator{this, it};
1000 }
1002 {
1003 return insert(pos.getWrapped(), count, value);
1004 }
1006 {
1007 const auto distance = pos - cbegin();
1008 auto it = contained_.insert(pos, count, value);
1009 insertRangeChecked(distance, distance + count - 1, RangeOperationType::Insert);
1010 return iterator{this, it};
1011 }
1012 template <typename Iterator>
1013 iterator insert(iterator pos, Iterator first, Iterator last)
1014 {
1015 return insert(pos.getWrapped(), first, last);
1016 }
1017 template <typename Iterator>
1018 iterator insert(const_iterator pos, Iterator first, Iterator last)
1019 {
1020 const auto distance = pos - cbegin();
1021 auto it = contained_.insert(pos, first, last);
1022 insertRangeChecked(distance, distance + std::distance(first, last) - 1, RangeOperationType::Insert);
1023 return iterator{this, it};
1024 }
1025 iterator insert(iterator pos, std::initializer_list<value_type> ilist)
1026 {
1027 return insert(pos.getWrapped(), ilist);
1028 }
1029 iterator insert(const_iterator pos, std::initializer_list<value_type> ilist)
1030 {
1031 const auto distance = pos - cbegin();
1032 auto it = contained_.insert(pos, ilist);
1033 insertRangeChecked(distance, distance + ilist.size() - 1, RangeOperationType::Insert);
1034 return iterator{this, it};
1035 }
1036 template <typename... Args>
1037 iterator emplace(const_iterator pos, Args&&... args)
1038 {
1039 const auto distance = pos - cbegin();
1040 auto it = contained_.emplace(pos, std::forward<Args>(args)...);
1042 return iterator{this, it};
1043 }
1045 {
1046 const auto distance = pos - begin();
1047 eraseNotify(distance, distance);
1048 auto it = contained_.erase(pos.getWrapped());
1049 insertRangeChecked(distance, distance, RangeOperationType::Erase);
1050 return iterator{this, it};
1051 }
1053 {
1054 const auto distance = pos - cbegin();
1055 eraseNotify(distance, distance);
1056 auto it = contained_.erase(pos);
1057 insertRangeChecked(distance, distance, RangeOperationType::Erase);
1058 return iterator{this, it};
1059 }
1061 {
1062 const auto distance = first - begin();
1063 const auto distance2 = std::distance(first, last);
1064 eraseNotify(distance, distance + distance2 - 1);
1065 auto it = contained_.erase(first.getWrapped(), last.getWrapped());
1066 insertRangeChecked(distance, distance + distance2 - 1, RangeOperationType::Erase);
1067 return iterator{this, it};
1068 }
1070 {
1071 const auto distance = first - cbegin();
1072 const auto distance2 = std::distance(first, last);
1073 eraseNotify(distance, distance + distance2 - 1);
1074 auto it = contained_.erase(first, last);
1075 insertRangeChecked(distance, distance + distance2 - 1, RangeOperationType::Erase);
1076 return iterator{this, it};
1077 }
1078 template <typename U = ContainerT>
1079 Detail::PickFirst_t<void, decltype(std::declval<U>().push_back(std::declval<const value_type&>()))>
1081 {
1082 contained_.push_back(value);
1084 }
1085 template <typename U = ContainerT>
1086 Detail::PickFirst_t<void, decltype(std::declval<U>().push_back(std::declval<value_type>()))>
1088 {
1089 contained_.push_back(std::move(value));
1091 }
1092 template <typename U = ContainerT>
1093 Detail::PickFirst_t<void, decltype(std::declval<U>().push_front(std::declval<const value_type&>()))>
1095 {
1096 contained_.push_front(value);
1098 }
1099 template <typename U = ContainerT>
1100 Detail::PickFirst_t<void, decltype(std::declval<U>().push_front(std::declval<value_type>()))>
1102 {
1103 contained_.push_front(std::move(value));
1105 }
1106 template <typename... Args>
1107 void emplace_back(Args&&... args)
1108 {
1109 contained_.emplace_back(std::forward<Args>(args)...);
1111 }
1112 template <typename U = ContainerT, typename... Args>
1114 {
1115 contained_.emplace_front(std::forward<Args>(args)...);
1117 }
1119 {
1120 if (contained_.empty())
1121 return;
1122 eraseNotify(size() - 1, size() - 1);
1123 contained_.pop_back();
1125 }
1126 template <typename U = ContainerT>
1128 {
1129 if (contained_.empty())
1130 return;
1131 eraseNotify(0, 0);
1132 contained_.pop_front();
1134 }
1135 template <typename U = ContainerT>
1136 Detail::PickFirst_t<void, decltype(std::declval<U>().resize(std::declval<std::size_t>()))>
1138 {
1139 const auto sizeBefore = contained_.size();
1140 if (sizeBefore < count && sizeBefore != 0)
1141 {
1142 eraseNotify(sizeBefore, count - 1);
1143 }
1144 contained_.resize(count);
1145 if (sizeBefore < count)
1146 {
1147 insertRangeChecked(sizeBefore, count - 1, RangeOperationType::Insert);
1148 }
1149 else if (sizeBefore != 0)
1150 {
1151 insertRangeChecked(count, sizeBefore - 1, RangeOperationType::Erase);
1152 }
1153 }
1154 template <typename U = ContainerT>
1156 void,
1157 decltype(std::declval<U>().resize(std::declval<std::size_t>(), std::declval<value_type const&>()))>
1158 resize(size_type count, value_type const& fillValue)
1159 {
1160 const auto sizeBefore = contained_.size();
1161 eraseNotify(sizeBefore, count - 1);
1162 contained_.resize(count, fillValue);
1163 if (sizeBefore < count)
1164 {
1165 insertRangeChecked(sizeBefore, count - 1, RangeOperationType::Insert);
1166 }
1167 else if (sizeBefore != 0)
1168 {
1169 insertRangeChecked(count, sizeBefore - 1, RangeOperationType::Erase);
1170 }
1171 }
1172 void swap(ContainerT& other)
1173 {
1174 contained_.swap(other);
1175 rangeContext_->reset(true);
1176 update();
1177 }
1178
1179 // Other
1180 ContainerT& value()
1181 {
1182 return contained_;
1183 }
1184 ContainerT const& value() const
1185 {
1186 return contained_;
1187 }
1189 {
1190 return *rangeContext_;
1191 }
1193 {
1194 return *rangeContext_;
1195 }
1196
1197 protected:
1198 void update(bool force = false) const override
1199 {
1200 if (force)
1201 rangeContext_->reset(true);
1203 ObservedBase::update(force);
1204 }
1205
1206 protected:
1207 void insertRangeChecked(std::size_t low, std::size_t high, RangeOperationType type)
1208 {
1209 std::function<void(int)> doInsert;
1210 doInsert = [&](int retries) {
1211 NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null.");
1212
1213 const auto result = rangeContext_->insertModificationRange(low, high, type);
1215 {
1216 update();
1218 }
1220 {
1221 update();
1223
1224 if (retries < 3)
1225 doInsert(retries + 1);
1226 else
1227 {
1228 rangeContext_->reset(true);
1229 update();
1231 return;
1232 }
1233 }
1235 {
1236 update();
1237 }
1238 else
1239 {
1240 // Rejected! (why?)
1241 rangeContext_->reset(true);
1242 update();
1244 return;
1245 }
1246 };
1247
1248 doInsert(0);
1249 }
1250
1252 {
1253 NUI_ASSERT(ObservedBase::eventContext_ != nullptr, "Event context must never be null.");
1255 Event{[weak = std::weak_ptr<RangeEventContext>{rangeContext_}](EventContext::EventIdType) {
1256 if (auto shared = weak.lock(); shared)
1257 {
1258 shared->reset();
1259 return true;
1260 }
1261 return false;
1262 }});
1263 }
1264
1265 void eraseNotify(std::size_t index, std::size_t high)
1266 {
1267 const bool fixupPerformed = rangeContext_->eraseNotify(index, high);
1268 if (fixupPerformed) // FORCE update:
1269 {
1270 update();
1272 }
1273 }
1274
1275 protected:
1277 mutable std::shared_ptr<RangeEventContext> rangeContext_;
1279 };
1280
1281 template <typename T>
1283 {
1284 public:
1286 using ModifiableObserved<T>::operator=;
1287 using ModifiableObserved<T>::operator->;
1288
1289 Observed& operator=(T const& contained)
1290 {
1292 return *this;
1293 }
1294 Observed& operator=(T&& contained)
1295 {
1296 ModifiableObserved<T>::operator=(std::move(contained));
1297 return *this;
1298 }
1299 };
1300 template <typename... Parameters>
1301 class Observed<std::vector<Parameters...>> : public ObservedContainer<std::vector<Parameters...>>
1302 {
1303 public:
1304 using ObservedContainer<std::vector<Parameters...>>::ObservedContainer;
1305 using ObservedContainer<std::vector<Parameters...>>::operator=;
1306 using ObservedContainer<std::vector<Parameters...>>::operator->;
1307 static constexpr auto isRandomAccess = true;
1308
1309 Observed<std::vector<Parameters...>>& operator=(std::vector<Parameters...> const& contained)
1310 {
1311 ObservedContainer<std::vector<Parameters...>>::operator=(contained);
1312 return *this;
1313 }
1314 Observed<std::vector<Parameters...>>& operator=(std::vector<Parameters...>&& contained)
1315 {
1316 ObservedContainer<std::vector<Parameters...>>::operator=(std::move(contained));
1317 return *this;
1318 }
1319 };
1320 template <typename... Parameters>
1321 class Observed<std::deque<Parameters...>> : public ObservedContainer<std::deque<Parameters...>>
1322 {
1323 public:
1324 using ObservedContainer<std::deque<Parameters...>>::ObservedContainer;
1325 using ObservedContainer<std::deque<Parameters...>>::operator=;
1326 using ObservedContainer<std::deque<Parameters...>>::operator->;
1327 static constexpr auto isRandomAccess = true;
1328
1329 Observed<std::deque<Parameters...>>& operator=(std::deque<Parameters...> const& contained)
1330 {
1331 ObservedContainer<std::deque<Parameters...>>::operator=(contained);
1332 return *this;
1333 }
1334 Observed<std::deque<Parameters...>>& operator=(std::deque<Parameters...>&& contained)
1335 {
1336 ObservedContainer<std::deque<Parameters...>>::operator=(std::move(contained));
1337 return *this;
1338 }
1339 };
1340 template <typename... Parameters>
1341 class Observed<std::basic_string<Parameters...>> : public ObservedContainer<std::basic_string<Parameters...>>
1342 {
1343 public:
1344 using ObservedContainer<std::basic_string<Parameters...>>::ObservedContainer;
1345 using ObservedContainer<std::basic_string<Parameters...>>::operator=;
1346 using ObservedContainer<std::basic_string<Parameters...>>::operator->;
1347 static constexpr auto isRandomAccess = true;
1348
1349 Observed<std::basic_string<Parameters...>>& operator=(std::basic_string<Parameters...> const& contained)
1350 {
1351 ObservedContainer<std::basic_string<Parameters...>>::operator=(contained);
1352 return *this;
1353 }
1354 Observed<std::basic_string<Parameters...>>& operator=(std::basic_string<Parameters...>&& contained)
1355 {
1356 ObservedContainer<std::basic_string<Parameters...>>::operator=(std::move(contained));
1357 return *this;
1358 }
1359
1360 Observed<std::basic_string<Parameters...>>& erase(std::size_t index = 0, std::size_t count = std::string::npos)
1361 {
1362 if (count == std::size_t{0})
1363 return *this;
1364 const auto sizeBefore = this->contained_.size();
1365 const auto high = count == std::string::npos ? sizeBefore - 1 : count - 1;
1366 this->eraseNotify(index, high);
1367 this->contained_.erase(index, count);
1368 this->insertRangeChecked(index, high, RangeOperationType::Erase);
1369 return *this;
1370 }
1371 };
1372 template <typename... Parameters>
1373 class Observed<std::set<Parameters...>> : public ObservedContainer<std::set<Parameters...>>
1374 {
1375 public:
1376 using ObservedContainer<std::set<Parameters...>>::ObservedContainer;
1377 using ObservedContainer<std::set<Parameters...>>::operator=;
1378 using ObservedContainer<std::set<Parameters...>>::operator->;
1379 static constexpr auto isRandomAccess = false;
1380
1381 public:
1383 : ObservedContainer<std::set<Parameters...>>{RangeEventContext{true}}
1384 {}
1385 template <typename T = std::set<Parameters...>>
1386 requires std::constructible_from<std::set<Parameters...>, T>
1387 explicit Observed(T&& t)
1388 : ObservedContainer<std::set<Parameters...>>{std::forward<T>(t), RangeEventContext{true}}
1389 {}
1390
1391 Observed<std::set<Parameters...>>& operator=(std::set<Parameters...> const& contained)
1392 {
1393 ObservedContainer<std::set<Parameters...>>::operator=(contained);
1394 return *this;
1395 }
1396 Observed<std::set<Parameters...>>& operator=(std::set<Parameters...>&& contained)
1397 {
1398 ObservedContainer<std::set<Parameters...>>::operator=(std::move(contained));
1399 return *this;
1400 }
1401 };
1402 template <typename... Parameters>
1403 class Observed<std::list<Parameters...>> : public ObservedContainer<std::list<Parameters...>>
1404 {
1405 public:
1406 using ObservedContainer<std::list<Parameters...>>::ObservedContainer;
1407 using ObservedContainer<std::list<Parameters...>>::operator=;
1408 using ObservedContainer<std::list<Parameters...>>::operator->;
1409 static constexpr auto isRandomAccess = false;
1410
1411 public:
1413 : ObservedContainer<std::list<Parameters...>>{RangeEventContext{true}}
1414 {}
1415 template <typename T = std::list<Parameters...>>
1416 requires std::constructible_from<std::list<Parameters...>, T>
1417 explicit Observed(T&& t)
1418 : ObservedContainer<std::list<Parameters...>>{std::forward<T>(t), RangeEventContext{true}}
1419 {}
1420
1421 Observed<std::list<Parameters...>>& operator=(std::list<Parameters...> const& contained)
1422 {
1423 ObservedContainer<std::list<Parameters...>>::operator=(contained);
1424 return *this;
1425 }
1426 Observed<std::list<Parameters...>>& operator=(std::list<Parameters...>&& contained)
1427 {
1428 ObservedContainer<std::list<Parameters...>>::operator=(std::move(contained));
1429 return *this;
1430 }
1431 };
1432
1433 template <>
1435 {
1436 public:
1438 using ObservedBase::operator=;
1439
1440 void modify() const
1441 {
1442 update();
1443 };
1444
1445 void modifyNow() const
1446 {
1447 updateNow();
1448 };
1449 };
1450
1451 namespace Detail
1452 {
1453 template <typename T>
1455 {
1456 static constexpr bool value = false;
1457 };
1458
1459 template <typename T>
1461 {
1462 static constexpr bool value = true;
1463 };
1464
1465 template <typename T>
1467 {
1468 static constexpr bool value = false;
1469 };
1470
1471 template <typename T>
1472 struct IsWeakObserved<std::weak_ptr<Observed<T>>>
1473 {
1474 static constexpr bool value = true;
1475 };
1476
1477 template <typename T>
1479 {
1480 static constexpr bool value = false;
1481 };
1482
1483 template <typename T>
1484 struct IsSharedObserved<std::shared_ptr<Observed<T>>>
1485 {
1486 static constexpr bool value = true;
1487 };
1488
1489 template <typename T>
1491 {
1492 static constexpr bool value =
1494 };
1495 }
1496
1497 template <typename T>
1498 requires Incrementable<T>
1500 {
1501 ++observedValue.value();
1502 observedValue.update();
1503 return observedValue;
1504 }
1505 template <typename T>
1506 requires Incrementable<T>
1507 inline T operator++(ModifiableObserved<T>& observedValue, int)
1508 {
1509 auto tmp = observedValue.value();
1510 ++observedValue.value();
1511 observedValue.update();
1512 return tmp;
1513 }
1514
1515 template <typename T>
1516 inline auto operator--(ModifiableObserved<T>& observedValue)
1517 -> ModifiableObserved<Detail::PickFirst_t<T, decltype(--std::declval<T>())>>&
1518 {
1519 --observedValue.value();
1520 observedValue.update();
1521 return observedValue;
1522 }
1523 template <typename T>
1524 inline auto operator--(ModifiableObserved<T>& observedValue, int)
1526 {
1527 auto tmp = observedValue.value();
1528 --observedValue.value();
1529 observedValue.update();
1530 return tmp;
1531 }
1532
1533 template <typename T>
1535 template <typename T>
1537 template <typename T>
1539 template <typename T>
1541
1542 namespace Detail
1543 {
1544 template <typename T>
1545 struct CopyableObservedWrap // minimal wrapper to make Observed<T> copiable
1546 {
1547 public:
1548 explicit constexpr CopyableObservedWrap(Observed<T> const& observed)
1549 : observed_{&observed}
1550 {}
1551
1552 T const& value() const
1553 {
1554 return observed_->value();
1555 }
1556
1557 void attachEvent(auto eventId) const
1558 {
1559 observed_->attachEvent(eventId);
1560 }
1561
1562 void detachEvent(auto eventId) const
1563 {
1564 observed_->detachEvent(eventId);
1565 }
1566
1567 private:
1568 Observed<T> const* observed_;
1569 };
1570
1571 template <typename T>
1573 {
1574 using type = T const&;
1575 };
1576 template <>
1578 {
1579 using type = void;
1580 };
1581 template <typename T>
1582 struct ObservedAddReference<std::weak_ptr<Observed<T>>>
1583 {
1584 using type = std::weak_ptr<Observed<T>>;
1585 };
1586 template <typename T>
1587 struct ObservedAddReference<std::shared_ptr<Observed<T>>>
1588 {
1589 using type = std::weak_ptr<Observed<T>>;
1590 };
1591 template <typename T>
1592 struct ObservedAddReference<std::weak_ptr<const Observed<T>>>
1593 {
1594 using type = std::weak_ptr<const Observed<T>>;
1595 };
1596 template <typename T>
1597 struct ObservedAddReference<std::shared_ptr<const Observed<T>>>
1598 {
1599 using type = std::weak_ptr<const Observed<T>>;
1600 };
1601
1602 template <typename T>
1604 {
1605 using type = T&;
1606 using raw = T;
1607 };
1608 template <>
1610 {
1611 using type = void;
1612 using raw = void;
1613 };
1614 template <typename T>
1615 struct ObservedAddMutableReference<std::weak_ptr<Observed<T>>>
1616 {
1617 using type = std::weak_ptr<Observed<T>>;
1619 };
1620 template <typename T>
1621 struct ObservedAddMutableReference<std::shared_ptr<Observed<T>>>
1622 {
1623 using type = std::weak_ptr<Observed<T>>;
1625 };
1626
1627 template <typename T>
1629 template <typename T>
1631 template <typename T>
1633 }
1634
1635 template <typename T>
1637 {
1638 using type = T;
1639 };
1640 template <typename T>
1642 {
1643 using type = T;
1644 };
1645 template <typename T>
1646 struct UnpackObserved<std::weak_ptr<Observed<T>>>
1647 {
1648 using type = T;
1649 };
1650 template <typename T>
1651 struct UnpackObserved<std::shared_ptr<Observed<T>>>
1652 {
1653 using type = T;
1654 };
1655 template <typename T>
1656 struct UnpackObserved<std::weak_ptr<const Observed<T>>>
1657 {
1658 using type = T;
1659 };
1660 template <typename T>
1661 struct UnpackObserved<std::shared_ptr<const Observed<T>>>
1662 {
1663 using type = T;
1664 };
1665 template <typename T>
1667}
#define NUI_ASSERT(condition, message)
Definition assert.hpp:31
This object can be copied with low cost.
Definition event_context.hpp:38
void removeAfterEffect(EventIdType id)
Definition event_context.hpp:80
EventIdType registerAfterEffect(Event event)
Definition event_context.hpp:72
auto activateEvent(EventIdType id)
Definition event_context.hpp:56
auto activateAfterEffect(EventIdType id)
Definition event_context.hpp:60
EventRegistry::EventIdType EventIdType
Definition event_context.hpp:40
void executeActiveEventsImmediately()
Definition event_context.hpp:64
static constexpr EventIdType invalidEventId
Definition event_registry.hpp:16
Definition event.hpp:46
Definition observed_value.hpp:177
ModificationProxy & operator=(ModificationProxy &&other) noexcept
Definition observed_value.hpp:195
ModificationProxy & operator=(ModificationProxy const &)=delete
ModificationProxy(ModifiableObserved &observed)
Definition observed_value.hpp:179
ModificationProxy(ModifiableObserved &observed, bool now)
Definition observed_value.hpp:183
ModificationProxy(ModificationProxy &&other) noexcept
Definition observed_value.hpp:189
~ModificationProxy()
Definition observed_value.hpp:205
auto & value()
Definition observed_value.hpp:223
ModificationProxy(ModificationProxy const &)=delete
auto & operator*()
Definition observed_value.hpp:231
auto * operator->()
Definition observed_value.hpp:227
Definition observed_value.hpp:171
ModifiableObserved & operator=(ContainedT const &contained)
Definition observed_value.hpp:268
ModificationProxy modify()
Can be used to make mutations to the underlying class that get commited when the returned proxy is de...
Definition observed_value.hpp:356
ModifiableObserved(CustomEventContextFlag_t, EventContext *ctx)
Definition observed_value.hpp:289
ContainedT & value()
Definition observed_value.hpp:372
ModifiableObserved & operator=(const ModifiableObserved &)=delete
ContainedT const & operator*() const
Definition observed_value.hpp:384
~ModifiableObserved() override=default
ModifiableObserved< T > & operator+=(U const &rhs)
Definition observed_value.hpp:317
ModifiableObserved & operator=(ContainedT &&contained)
Definition observed_value.hpp:274
ModifiableObserved(ModifiableObserved &&other) noexcept
Definition observed_value.hpp:251
ModifiableObserved()
Definition observed_value.hpp:246
ContainedT const * operator->() const
Definition observed_value.hpp:392
ModificationProxy modifyNow()
Definition observed_value.hpp:361
ModifiableObserved & operator=(T &&t)
Assign a completely new value.
Definition observed_value.hpp:308
ModifiableObserved & operator=(T &&t)
Definition observed_value.hpp:332
ContainedT value_type
Definition observed_value.hpp:173
ContainedT & operator*()
Definition observed_value.hpp:380
ModifiableObserved(T &&t)
Definition observed_value.hpp:284
void assignWithoutUpdate(T &&t)
Sets the value without making an update.
Definition observed_value.hpp:402
ModifiableObserved(const ModifiableObserved &)=delete
ContainedT contained_
Definition observed_value.hpp:408
ModifiableObserved & operator=(ModifiableObserved &&other) noexcept
Definition observed_value.hpp:258
ContainedT * operator->()
Definition observed_value.hpp:388
ContainedT const & value() const
Definition observed_value.hpp:376
ModifiableObserved(CustomEventContextFlag_t, EventContext *ctx, T &&t)
Definition observed_value.hpp:296
ModifiableObserved & assignChecked(T &&other)
Definition observed_value.hpp:340
ModifiableObserved< T > & operator-=(U const &rhs)
Definition observed_value.hpp:324
Utility class to detect if an object was moved.
Definition move_detector.hpp:9
bool wasMoved() const noexcept
Definition move_detector.hpp:24
Definition observed_value.hpp:31
std::size_t totalAttachedEventCount() const
Definition observed_value.hpp:123
void attachOneshotEvent(EventContext::EventIdType eventId) const
Definition observed_value.hpp:104
std::size_t attachedOneshotEventCount() const
Definition observed_value.hpp:119
void detachAllEvents()
You should never need to do this.
Definition observed_value.hpp:131
virtual void update(bool=false) const
Definition observed_value.hpp:137
ObservedBase(CustomEventContextFlag_t, EventContext *ctx)
Definition observed_value.hpp:33
std::size_t attachedEventCount() const
Definition observed_value.hpp:115
ObservedBase(ObservedBase const &)=delete
ObservedBase & operator=(ObservedBase &&other) noexcept
Definition observed_value.hpp:71
void attachEvent(EventContext::EventIdType eventId) const
Definition observed_value.hpp:100
void detachEvent(EventContext::EventIdType eventId) const
Definition observed_value.hpp:108
ObservedBase & operator=(ObservedBase const &)=delete
void updateNow(bool force=false) const
Definition observed_value.hpp:155
virtual ~ObservedBase()=default
ObservedBase(ObservedBase &&other) noexcept
Definition observed_value.hpp:40
EventContext * eventContext_
Definition observed_value.hpp:164
std::vector< EventContext::EventIdType > attachedEvents_
Definition observed_value.hpp:165
std::vector< EventContext::EventIdType > attachedOneshotEvents_
Definition observed_value.hpp:166
Definition observed_value.hpp:711
ObservedContainer(CustomEventContextFlag_t, EventContext *ctx, RangeEventContext &&rangeContext)
Definition observed_value.hpp:762
ObservedContainer()
Definition observed_value.hpp:739
iterator erase(const_iterator first, const_iterator last)
Definition observed_value.hpp:1069
iterator insert(iterator pos, std::initializer_list< value_type > ilist)
Definition observed_value.hpp:1025
Detail::PickFirst_t< std::size_t, decltype(std::declval< U >().capacity())> capacity() const noexcept
Definition observed_value.hpp:934
~ObservedContainer()
Definition observed_value.hpp:784
Detail::PickFirst_t< void, decltype(std::declval< U >().pop_front())> pop_front()
Definition observed_value.hpp:1127
void swap(ContainerT &other)
Definition observed_value.hpp:1172
const_reference front() const
Definition observed_value.hpp:826
std::shared_ptr< RangeEventContext > rangeContext_
Definition observed_value.hpp:1277
const_reference at(size_type pos) const
Definition observed_value.hpp:850
reference front()
Definition observed_value.hpp:822
ObservedContainer & operator=(T &&t)
Definition observed_value.hpp:794
iterator erase(iterator pos)
Definition observed_value.hpp:1044
const_reverse_iterator rend() const noexcept
Definition observed_value.hpp:900
typename ContainerT::allocator_type allocator_type
Definition observed_value.hpp:717
void insertRangeChecked(std::size_t low, std::size_t high, RangeOperationType type)
Definition observed_value.hpp:1207
const_reference back() const
Definition observed_value.hpp:834
Detail::PickFirst_t< void, decltype(std::declval< U >().reserve(std::declval< std::size_t >()))> reserve(size_type capacity)
Definition observed_value.hpp:929
typename ContainerT::const_pointer const_pointer
Definition observed_value.hpp:723
const_iterator end() const noexcept
Definition observed_value.hpp:876
auto registerAfterEffect()
Definition observed_value.hpp:1251
Detail::PickFirst_t< std::pair< typename ContainerT::iterator, bool >, decltype(std::declval< U >().insert(std::declval< const value_type & >()))> insert(const value_type &value)
Definition observed_value.hpp:955
Detail::PickFirst_t< void, decltype(std::declval< U >().push_front(std::declval< value_type >()))> push_front(value_type &&value)
Definition observed_value.hpp:1101
EventContext::EventIdType afterEffectId_
Definition observed_value.hpp:1278
ObservedContainer(CustomEventContextFlag_t, EventContext *ctx, T &&t)
Definition observed_value.hpp:745
iterator end() noexcept
Definition observed_value.hpp:872
reference at(size_type pos)
Definition observed_value.hpp:846
Detail::PickFirst_t< void, decltype(std::declval< U >().push_back(std::declval< const value_type & >()))> push_back(const value_type &value)
Definition observed_value.hpp:1080
ContainerT const & value() const
Definition observed_value.hpp:1184
Detail::PickFirst_t< std::pair< typename ContainerT::iterator, bool >, decltype(std::declval< U >().insert(std::declval< value_type && >()))> insert(value_type &&value)
Definition observed_value.hpp:969
RangeEventContext const & rangeContext() const
Definition observed_value.hpp:1192
reverse_iterator rend() noexcept
Definition observed_value.hpp:896
const_reference operator[](size_type pos) const
Definition observed_value.hpp:858
Detail::PickFirst_t< void, decltype(std::declval< U >().emplace_front())> emplace_front(Args &&... args)
Definition observed_value.hpp:1113
iterator insert(iterator pos, value_type &&value)
Definition observed_value.hpp:990
reference back()
Definition observed_value.hpp:830
const_pointer data() const noexcept
Definition observed_value.hpp:842
iterator insert(const_iterator pos, value_type &&value)
Definition observed_value.hpp:994
void assign(std::initializer_list< value_type > ilist)
Definition observed_value.hpp:814
void assign(Iterator first, Iterator last)
Definition observed_value.hpp:808
iterator begin() noexcept
Definition observed_value.hpp:864
const_reverse_iterator rbegin() const noexcept
Definition observed_value.hpp:892
Detail::PickFirst_t< void, decltype(std::declval< U >().push_front(std::declval< const value_type & >()))> push_front(const value_type &value)
Definition observed_value.hpp:1094
constexpr auto map(auto &&function) const
Definition range.hpp:153
ObservedContainer(RangeEventContext &&rangeContext)
Definition observed_value.hpp:757
pointer data() noexcept
Definition observed_value.hpp:838
ObservedContainer(T &&t)
Definition observed_value.hpp:752
const_reverse_iterator crbegin() const noexcept
Definition observed_value.hpp:904
const_iterator begin() const noexcept
Definition observed_value.hpp:868
iterator insert(const_iterator pos, const value_type &value)
Definition observed_value.hpp:983
ObservedContainer(ObservedContainer &&)=default
ObservedContainer & operator=(const ObservedContainer &)=delete
typename ContainerT::size_type size_type
Definition observed_value.hpp:718
ObservedContainer(T &&t, RangeEventContext &&rangeContext)
Definition observed_value.hpp:768
iterator insert(const_iterator pos, std::initializer_list< value_type > ilist)
Definition observed_value.hpp:1029
ContainerWrapUtility::ReferenceWrapper< typename ContainerT::value_type, ContainerT > reference
Definition observed_value.hpp:720
iterator insert(const_iterator pos, Iterator first, Iterator last)
Definition observed_value.hpp:1018
ObservedContainer(const ObservedContainer &)=delete
iterator erase(const_iterator pos)
Definition observed_value.hpp:1052
void emplace_back(Args &&... args)
Definition observed_value.hpp:1107
const_reverse_iterator crend() const noexcept
Definition observed_value.hpp:908
Detail::PickFirst_t< void, decltype(std::declval< U >().resize(std::declval< std::size_t >(), std::declval< value_type const & >()))> resize(size_type count, value_type const &fillValue)
Definition observed_value.hpp:1158
Detail::PickFirst_t< void, decltype(std::declval< U >().shrink_to_fit())> shrink_to_fit()
Definition observed_value.hpp:939
typename ContainerT::value_type value_type
Definition observed_value.hpp:716
void update(bool force=false) const override
Definition observed_value.hpp:1198
ContainerWrapUtility::IteratorWrapper< typename ContainerT::iterator, ContainerT > iterator
Definition observed_value.hpp:725
Detail::PickFirst_t< void, decltype(std::declval< U >().push_back(std::declval< value_type >()))> push_back(value_type &&value)
Definition observed_value.hpp:1087
iterator insert(const_iterator pos, size_type count, const value_type &value)
Definition observed_value.hpp:1005
ContainerT & value()
Definition observed_value.hpp:1180
reference operator[](size_type pos)
Definition observed_value.hpp:854
iterator emplace(const_iterator pos, Args &&... args)
Definition observed_value.hpp:1037
RangeEventContext & rangeContext()
Definition observed_value.hpp:1188
void pop_back()
Definition observed_value.hpp:1118
const_iterator cend() const noexcept
Definition observed_value.hpp:884
iterator insert(iterator pos, Iterator first, Iterator last)
Definition observed_value.hpp:1013
reverse_iterator rbegin() noexcept
Definition observed_value.hpp:888
const_iterator cbegin() const noexcept
Definition observed_value.hpp:880
ContainerWrapUtility::IteratorWrapper< typename ContainerT::reverse_iterator, ContainerT > reverse_iterator
Definition observed_value.hpp:728
ContainerWrapUtility::PointerWrapper< typename ContainerT::value_type, ContainerT > pointer
Definition observed_value.hpp:722
ObservedContainer & operator=(ObservedContainer &&)=default
typename ContainerT::const_reverse_iterator const_reverse_iterator
Definition observed_value.hpp:729
void assign(size_type count, const value_type &value)
Definition observed_value.hpp:801
typename ContainerT::const_iterator const_iterator
Definition observed_value.hpp:726
iterator erase(iterator first, iterator last)
Definition observed_value.hpp:1060
bool empty() const noexcept
Definition observed_value.hpp:914
void eraseNotify(std::size_t index, std::size_t high)
Definition observed_value.hpp:1265
MoveDetector moveDetector_
Definition observed_value.hpp:1276
std::size_t size() const noexcept
Definition observed_value.hpp:918
typename ContainerT::difference_type difference_type
Definition observed_value.hpp:719
typename ContainerT::const_reference const_reference
Definition observed_value.hpp:721
iterator insert(iterator pos, size_type count, const value_type &value)
Definition observed_value.hpp:1001
ObservedContainer(CustomEventContextFlag_t, EventContext *ctx, T &&t, RangeEventContext &&rangeContext)
Definition observed_value.hpp:774
Detail::PickFirst_t< void, decltype(std::declval< U >().resize(std::declval< std::size_t >()))> resize(size_type count)
Definition observed_value.hpp:1137
void clear()
Definition observed_value.hpp:945
iterator insert(iterator pos, const value_type &value)
Definition observed_value.hpp:979
Detail::PickFirst_t< std::size_t, decltype(std::declval< U >().max_size())> max_size() const noexcept
Definition observed_value.hpp:923
Observed< std::basic_string< Parameters... > > & erase(std::size_t index=0, std::size_t count=std::string::npos)
Definition observed_value.hpp:1360
Observed< std::basic_string< Parameters... > > & operator=(std::basic_string< Parameters... > &&contained)
Definition observed_value.hpp:1354
Observed< std::basic_string< Parameters... > > & operator=(std::basic_string< Parameters... > const &contained)
Definition observed_value.hpp:1349
Observed< std::deque< Parameters... > > & operator=(std::deque< Parameters... > const &contained)
Definition observed_value.hpp:1329
Observed< std::deque< Parameters... > > & operator=(std::deque< Parameters... > &&contained)
Definition observed_value.hpp:1334
Observed< std::list< Parameters... > > & operator=(std::list< Parameters... > const &contained)
Definition observed_value.hpp:1421
Observed()
Definition observed_value.hpp:1412
Observed(T &&t)
Definition observed_value.hpp:1417
Observed< std::list< Parameters... > > & operator=(std::list< Parameters... > &&contained)
Definition observed_value.hpp:1426
Observed< std::set< Parameters... > > & operator=(std::set< Parameters... > const &contained)
Definition observed_value.hpp:1391
Observed< std::set< Parameters... > > & operator=(std::set< Parameters... > &&contained)
Definition observed_value.hpp:1396
Observed(T &&t)
Definition observed_value.hpp:1387
Observed()
Definition observed_value.hpp:1382
Observed< std::vector< Parameters... > > & operator=(std::vector< Parameters... > &&contained)
Definition observed_value.hpp:1314
Observed< std::vector< Parameters... > > & operator=(std::vector< Parameters... > const &contained)
Definition observed_value.hpp:1309
void modify() const
Definition observed_value.hpp:1440
void modifyNow() const
Definition observed_value.hpp:1445
Definition observed_value.hpp:1283
Observed & operator=(T const &contained)
Definition observed_value.hpp:1289
Observed & operator=(T &&contained)
Definition observed_value.hpp:1294
Definition range_event_context.hpp:187
Definition concepts.hpp:11
Definition concepts.hpp:14
Definition observed_value.hpp:1540
Definition observed_value.hpp:1534
Definition observed_value.hpp:1536
Definition observed_value.hpp:1538
Definition concepts.hpp:29
Definition concepts.hpp:26
typename ObservedAddReference< std::decay_t< T > >::type ObservedAddReference_t
Definition observed_value.hpp:1628
typename PickFirst< Ts... >::type PickFirst_t
Definition pick_first.hpp:22
typename ObservedAddMutableReference< std::remove_reference_t< T > >::type ObservedAddMutableReference_t
Definition observed_value.hpp:1630
typename ObservedAddMutableReference< std::remove_reference_t< T > >::raw ObservedAddMutableReference_raw
Definition observed_value.hpp:1632
static constexpr auto extractJsonMember(nlohmann::json const &json) -> decltype(auto)
Definition rpc_hub.hpp:29
Definition file_dialog.hpp:6
typename UnpackObserved< T >::type UnpackObserved_t
Definition observed_value.hpp:1666
bool operator==(GObjectReference< T > const &lhs, GObjectReference< U > const &rhs)
Definition gobject.hpp:166
ModifiableObserved< T > & operator++(ModifiableObserved< T > &observedValue)
Definition observed_value.hpp:1499
RangeOperationType
Definition range_event_context.hpp:16
@ Modify
Definition range_event_context.hpp:18
@ Insert
Definition range_event_context.hpp:19
@ Erase
Definition range_event_context.hpp:20
thread_local EventContext globalEventContext
Definition event_context.cpp:5
auto operator--(ModifiableObserved< T > &observedValue) -> ModifiableObserved< Detail::PickFirst_t< T, decltype(--std::declval< T >())> > &
Definition observed_value.hpp:1516
emscripten::val val
Definition val.hpp:5
constexpr CustomEventContextFlag_t CustomEventContextFlag
Definition observed_value.hpp:28
Definition observed_value.hpp:27
Definition observed_value.hpp:1546
constexpr CopyableObservedWrap(Observed< T > const &observed)
Definition observed_value.hpp:1548
T const & value() const
Definition observed_value.hpp:1552
void detachEvent(auto eventId) const
Definition observed_value.hpp:1562
void attachEvent(auto eventId) const
Definition observed_value.hpp:1557
std::weak_ptr< Observed< T > > type
Definition observed_value.hpp:1623
std::weak_ptr< Observed< T > > type
Definition observed_value.hpp:1617
void raw
Definition observed_value.hpp:1612
void type
Definition observed_value.hpp:1611
Definition observed_value.hpp:1604
T raw
Definition observed_value.hpp:1606
T & type
Definition observed_value.hpp:1605
std::weak_ptr< Observed< T > > type
Definition observed_value.hpp:1589
std::weak_ptr< const Observed< T > > type
Definition observed_value.hpp:1599
std::weak_ptr< Observed< T > > type
Definition observed_value.hpp:1584
std::weak_ptr< const Observed< T > > type
Definition observed_value.hpp:1594
void type
Definition observed_value.hpp:1579
Definition observed_value.hpp:1573
T const & type
Definition observed_value.hpp:1574
T type
Definition observed_value.hpp:1643
T type
Definition observed_value.hpp:1648
Definition observed_value.hpp:1637
T type
Definition observed_value.hpp:1638