TrinityCore
Loading...
Searching...
No Matches
UpdateField.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef UpdateField_h__
19#define UpdateField_h__
20
21#include "Concepts.h"
22#include "ObjectGuid.h"
23#include "Optional.h"
24#include "UpdateMask.h"
25#include <algorithm>
26#include <memory>
27#include <unordered_map>
28#include <variant>
29#include <vector>
30
31class ByteBuffer;
32class Object;
33
34namespace UF
35{
37 {
38 None = 0,
39 Owner = 0x01,
40 PartyMember = 0x02,
41 UnitAll = 0x04,
42 Empath = 0x08
43 };
44
46
47 template<typename T>
48 class UpdateFieldBase;
49
50 template<typename T, int32 BlockBit, uint32 Bit>
51 class UpdateField;
52
53 template<typename T>
55
56 template<typename T, std::size_t Size>
58
59 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
60 class UpdateFieldArray;
61
62 template<typename T>
64
65 template<typename T, int32 BlockBit, uint32 Bit>
67
68 template<typename K, typename V>
70
71 template<typename K, typename V, int32 BlockBit, uint32 Bit>
72 class MapUpdateField;
73
74 template<typename T>
76
77 template<typename T, int32 BlockBit, uint32 Bit>
78 class SetUpdateField;
79
80 template<typename T>
82
83 template<typename T, int32 BlockBit, uint32 Bit>
85
86 template<typename T>
87 inline constexpr std::type_identity<T> VariantCase;
88
89 template<typename... Types>
91
92 template<int32 BlockBit, uint32 Bit, typename... Types>
94
95 template<typename T, bool PublicSet>
97
98 template<typename T, bool PublicSet>
100
101 template<typename T, bool PublicSet>
103
105 {
106 Unchanged = 0,
107 Changed = 1,
108 Deleted = 2
109 };
110
112 {
113 };
115 {
116 };
118 {
119 };
120
121 template<typename T>
123 {
124 using value_type = T;
125
126 template<typename F>
128
130 {
131 }
132
133 T GetValue() const
134 {
135 return _value;
136 }
137
138 private:
139 bool SetValue(T value)
140 {
141 if (_value != value)
142 {
143 _value = std::move(value);
144 return true;
145 }
146 return false;
147 }
148
150 };
151
152 // Same as UpdateFieldSetter but with public setter, used to set member fields for values added to dynamic fields
153 template<typename T>
155 {
156 using value_type = T;
157
159 {
160 }
161
162 T GetValue() const
163 {
164 return _value;
165 }
166
167 void SetValue(T value)
168 {
169 _value = std::move(value);
170 }
171
172 private:
174 };
175
176 template<typename T, bool PublicSet>
177 using UpdateFieldSetter = std::conditional_t<PublicSet, UpdateFieldPublicSetter<T>, UpdateFieldPrivateSetter<T>>;
178
179 template<typename T, bool PublicSet>
180 using MutableFieldReference = std::conditional_t<std::is_base_of_v<HasChangesMaskTag, T>,
183
184 template<typename T>
186 {
187 using value_type = T;
188 using insert_result = std::conditional_t<std::is_base_of_v<HasChangesMaskTag, T>, MutableFieldReference<T, true>, T&>;
189
190 template<typename F>
192
193 template<typename F>
195
196 template<typename F>
198
199 template<typename F>
201
202 DynamicUpdateFieldSetter(std::vector<T>& values, std::vector<uint32>& updateMask) : _values(values), _updateMask(updateMask)
203 {
204 }
205
206 private:
208 {
209 MarkChanged(_values.size());
210 T& value = _values.emplace_back();
211 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
212 value._changesMask.SetAll();
213 return { value };
214 }
215
216 insert_result InsertValue(std::size_t index)
217 {
218 _values.emplace(_values.begin() + index);
219 for (std::size_t i = index; i < _values.size(); ++i)
220 {
221 MarkChanged(i);
222 // also mark all fields of value as changed
223 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
224 _values[i]._changesMask.SetAll();
225 }
226 return { _values[index] };
227 }
228
229 void RemoveValue(std::size_t index)
230 {
231 // remove by shifting entire container - client might rely on values being sorted for certain fields
232 _values.erase(_values.begin() + index);
233 for (std::size_t i = index; i < _values.size(); ++i)
234 {
235 MarkChanged(i);
236 // also mark all fields of value as changed
237 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
238 _values[i]._changesMask.SetAll();
239 }
240 if (_values.size() % 32)
242 else
243 _updateMask.pop_back();
244 }
245
246 void Clear()
247 {
248 _values.clear();
249 _updateMask.clear();
250 }
251
252 void MarkChanged(std::size_t index)
253 {
254 std::size_t block = UpdateMaskHelpers::GetBlockIndex(index);
255 if (block >= _updateMask.size())
256 _updateMask.resize(block + 1);
257
259 }
260
261 std::vector<T>& _values;
262 std::vector<uint32>& _updateMask;
263 };
264
265 template<typename K, typename V>
267 {
268 template<typename F, typename G>
269 friend bool RemoveMapUpdateFieldValue(MapUpdateFieldSetter<F, G>& setter, std::type_identity_t<F> const& key);
270
271 MapUpdateFieldSetter(std::unordered_map<K, V>& values) : _values(values) { }
272
273 private:
274 bool RemoveKey(K const& key)
275 {
276 auto itr = _values.find(key);
277 if (itr != _values.end())
278 {
279 itr->second.state = MapUpdateFieldState::Deleted;
280 return true;
281 }
282 return false;
283 }
284
285 std::unordered_map<K, V>& _values;
286 };
287
288 template<typename T>
290 {
291 template<typename F>
292 friend bool RemoveSetUpdateFieldValue(SetUpdateFieldSetter<F>& setter, std::type_identity_t<F> const& key);
293
294 SetUpdateFieldSetter(std::unordered_map<T, MapUpdateFieldState>& values) : _values(values) { }
295
296 private:
297 bool Insert(T const& key)
298 {
299 return _values.emplace(key, MapUpdateFieldState::Changed).second;
300 }
301
302 bool Remove(T const& key)
303 {
304 auto itr = _values.find(key);
305 if (itr != _values.end())
306 {
307 itr->second = MapUpdateFieldState::Deleted;
308 return true;
309 }
310 return false;
311 }
312
313 std::unordered_map<T, MapUpdateFieldState>& _values;
314 };
315
316 template<typename T>
318 {
319 template<typename F>
321
323
324 private:
326 {
327 if (_field.has_value())
328 {
329 _field.DestroyValue();
330 return true;
331 }
332 return false;
333 }
334
336 };
337
338 template<typename T, bool PublicSet>
340 {
342 {
343 }
344
345 template<typename V, int32 BlockBit, uint32 Bit>
346 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
348 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
352 {
353 if constexpr (BlockBit >= 0)
354 _value._changesMask.Set(BlockBit);
355
356 _value._changesMask.Set(Bit);
357 return { (_value.*field)._value };
358 }
359
360 template<typename V, std::size_t Size, uint32 Bit, int32 FirstElementBit>
361 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
363 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
367 {
368 _value._changesMask.Set(Bit);
369 if constexpr (FirstElementBit >= 0)
370 {
371 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, V>)
372 _value._changesMask.Set(FirstElementBit + index);
373 else
374 _value._changesMask.Set(FirstElementBit);
375 }
376
377 return { (_value.*field)._values[index] };
378 }
379
380 template<typename V, int32 BlockBit, uint32 Bit>
382 {
383 if constexpr (BlockBit >= 0)
384 _value._changesMask.Set(BlockBit);
385
386 _value._changesMask.Set(Bit);
387 return { (_value.*field)._values, (_value.*field)._updateMask };
388 }
389
390 template<typename V, int32 BlockBit, uint32 Bit>
391 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
393 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
397 {
398 if (index >= (_value.*field).size())
399 {
400 // fill with zeros until reaching desired slot
401 (_value.*field)._values.resize(index + 1);
402 (_value.*field)._updateMask.resize((index + 1 + 31) / 32);
403 }
404
405 if constexpr (BlockBit >= 0)
406 _value._changesMask.Set(BlockBit);
407
408 _value._changesMask.Set(Bit);
409 (_value.*field).MarkChanged(index);
410 return { (_value.*field)._values[index] };
411 }
412
413 template<typename K, typename V, int32 BlockBit, uint32 Bit>
416 {
417 if constexpr (BlockBit >= 0)
418 _value._changesMask.Set(BlockBit);
419
420 _value._changesMask.Set(Bit);
421 return { (_value.*field)._values };
422 }
423
424 template<typename K, typename V, int32 BlockBit, uint32 Bit>
425 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
427 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
430 ModifyValue(MapUpdateField<K, V, BlockBit, Bit>(T::* field), std::type_identity_t<K> const& key)
431 {
432 if constexpr (BlockBit >= 0)
433 _value._changesMask.Set(BlockBit);
434
435 _value._changesMask.Set(Bit);
436
437 auto itr = (_value.*field)._values.try_emplace(key).first;
438 itr->second.state = MapUpdateFieldState::Changed;
439 return { itr->second.value };
440 }
441
442 template<typename V, int32 BlockBit, uint32 Bit>
444 {
445 if constexpr (BlockBit >= 0)
446 _value._changesMask.Set(BlockBit);
447
448 _value._changesMask.Set(Bit);
449 return { (_value.*field)._values };
450 }
451
452 template<typename V, int32 BlockBit, uint32 Bit>
454 {
455 if constexpr (BlockBit >= 0)
456 _value._changesMask.Set(BlockBit);
457
458 _value._changesMask.Set(Bit);
459 return { _value.*field };
460 }
461
462 template<typename V, int32 BlockBit, uint32 Bit>
463 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
465 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
469 {
470 if (!(_value.*field).has_value())
471 (_value.*field).ConstructValue();
472
473 if constexpr (BlockBit >= 0)
474 _value._changesMask.Set(BlockBit);
475
476 _value._changesMask.Set(Bit);
477 return { *((_value.*field)._value) };
478 }
479
480 template<typename V, int32 BlockBit, uint32 Bit, typename... Types>
481 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>,
483 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>,
486 ModifyValue(VariantUpdateField<BlockBit, Bit, Types...>(T::* field), [[maybe_unused]] std::type_identity<V> type)
487 {
488 if (!(_value.*field).template Is<V>())
489 (_value.*field).template ConstructValue<V>();
490
491 if constexpr (BlockBit >= 0)
492 _value._changesMask.Set(BlockBit);
493
494 _value._changesMask.Set(Bit);
495 return { *((_value.*field).template Get<V>()) };
496 }
497
498 private:
500 };
501
502 template<typename T, bool PublicSet>
504 {
506 {
507 }
508
509 template<typename V>
511 {
512 return { _value.*field };
513 }
514
515 template<typename V, std::size_t Size>
517 {
518 return { (_value.*field)[index] };
519 }
520
521 private:
523 };
524
525 template<typename T, bool PublicSet>
527 {
528 using value_type = typename T::value_type;
529
531 {
532 }
533
534 template<typename U = T>
535 std::enable_if_t<std::is_base_of_v<UpdateFieldBase<value_type>, U>,
536 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
538 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
542 {
543 return { _value._value };
544 }
545
546 template<typename U = T>
547 std::enable_if_t<std::is_base_of_v<UpdateFieldArrayBaseWithoutSize<value_type>, U>,
548 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
550 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
554 {
555 return { _value._values[index] };
556 }
557
558 template<typename U = T>
559 std::enable_if_t<std::is_base_of_v<DynamicUpdateFieldBase<value_type>, U>, DynamicUpdateFieldSetter<value_type>>
561 {
562 return { _value._values, _value._updateMask };
563 }
564
565 template<typename U = T>
566 std::enable_if_t<std::is_base_of_v<DynamicUpdateFieldBase<value_type>, U>,
567 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
569 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
573 {
574 if (index >= _value.size())
575 {
576 // fill with zeros until reaching desired slot
577 _value._values.resize(index + 1);
578 _value._updateMask.resize((index + 1 + 31) / 32);
579 }
580
581 _value.MarkChanged(index);
582 return { _value._values[index] };
583 }
584
585 template<typename U = T>
586 std::enable_if_t<std::is_base_of_v<OptionalUpdateFieldBase<value_type>, U>, OptionalUpdateFieldSetter<value_type>>
588 {
589 return { _value };
590 }
591
592 template<typename U = T>
593 std::enable_if_t<std::is_base_of_v<OptionalUpdateFieldBase<value_type>, U>,
594 std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, value_type>,
596 std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, value_type>,
600 {
601 if (!_value.has_value())
602 _value.ConstructValue();
603
604 return { *(_value._value) };
605 }
606
607 private:
609 };
610
611 template<std::size_t Bits>
613 {
614 template<typename T>
616
617 template<typename K, typename V>
618 friend struct MapUpdateFieldSetter;
619
620 template<typename T, bool PublicSet>
622
623 template<typename T, bool PublicSet>
625
626 template<typename T, int32 BlockBit, uint32 Bit>
627 friend class UpdateField;
628
629 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
630 friend class UpdateFieldArray;
631
632 template<typename T, int32 BlockBit, uint32 Bit>
633 friend class DynamicUpdateField;
634
635 public:
638
639 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
641 {
642 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
643
644 if constexpr (BlockBit >= 0)
645 _changesMask.Set(BlockBit);
646
647 _changesMask.Set(Bit);
648 }
649
650 template<typename Derived, typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
652 {
653 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
654
655 _changesMask.Set(Bit);
656 if constexpr (FirstElementBit >= 0)
657 {
658 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
659 _changesMask.Set(FirstElementBit + index);
660 else
661 _changesMask.Set(FirstElementBit);
662 }
663 }
664
665 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
667 {
668 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
669
670 if constexpr (BlockBit >= 0)
671 _changesMask.Set(BlockBit);
672
673 _changesMask.Set(Bit);
674 }
675
676 template<typename Derived, typename K, typename V, int32 BlockBit, uint32 Bit>
678 {
679 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
680
681 if constexpr (BlockBit >= 0)
682 _changesMask.Set(BlockBit);
683
684 _changesMask.Set(Bit);
685 }
686
687 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
689 {
690 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
691
692 if constexpr (BlockBit >= 0)
693 _changesMask.Set(BlockBit);
694
695 _changesMask.Set(Bit);
696 }
697
698 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
700 {
701 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
702
703 if constexpr (BlockBit >= 0)
704 _changesMask.Set(BlockBit);
705
706 _changesMask.Set(Bit);
707 }
708
709 template<typename Derived, int32 BlockBit, uint32 Bit, typename... Types>
711 {
712 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
713
714 if constexpr (BlockBit >= 0)
715 _changesMask.Set(BlockBit);
716
717 _changesMask.Set(Bit);
718 }
719
720 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
722 {
723 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
724
725 _changesMask.Reset(Bit);
726 }
727
728 template<typename Derived, typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
730 {
731 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
732
733 if constexpr (FirstElementBit >= 0)
734 {
735 if constexpr (!std::is_base_of_v<IsUpdateFieldHolderTag, T>)
736 _changesMask.Reset(FirstElementBit + index);
737 else
738 _changesMask.Reset(FirstElementBit);
739 }
740 }
741
742 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
744 {
745 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
746
747 _changesMask.Reset(Bit);
748 }
749
750 template<typename Derived, typename K, typename V, int32 BlockBit, uint32 Bit>
752 {
753 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
754
755 _changesMask.Reset(Bit);
756 }
757
758 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
760 {
761 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
762
763 _changesMask.Reset(Bit);
764 }
765
766 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
768 {
769 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
770
771 _changesMask.Reset(Bit);
772 }
773
774 template<typename Derived, int32 BlockBit, uint32 Bit, typename... Types>
776 {
777 static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
778
779 _changesMask.Reset(Bit);
780 }
781
782 Mask const& GetChangesMask() const { return _changesMask; }
783
784 protected:
785 template<typename T>
786 static inline void ClearChangesMask(UpdateFieldBase<T>& field)
787 {
788 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
789 field._value.ClearChangesMask();
790 }
791
792 template<typename T, std::size_t Size>
794 {
795 if constexpr (std::disjunction_v<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>)
796 for (T& value : field._values)
797 value.ClearChangesMask();
798 }
799
800 template<typename T>
802 {
803 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
804 for (T& value : field._values)
805 value.ClearChangesMask();
806
807 field.ClearChangesMask();
808 }
809
810 template<typename K, typename V>
812 {
813 for (auto itr = field._values.begin(); itr != field._values.end(); )
814 {
815 switch (itr->second.state)
816 {
818 break;
820 if constexpr (std::is_base_of_v<HasChangesMaskTag, K>)
821 const_cast<K&>(itr->first).ClearChangesMask();
822
823 if constexpr (std::is_base_of_v<HasChangesMaskTag, V>)
824 itr->second.value.ClearChangesMask();
825
826 itr->second.state = MapUpdateFieldState::Unchanged;
827 break;
829 itr = field._values.erase(itr++);
830 continue;
831 default:
832 break;
833 }
834
835 ++itr;
836 }
837 }
838
839 template<typename T>
840 static inline void ClearChangesMask(SetUpdateFieldBase<T>& field)
841 {
842 for (auto itr = field._values.begin(); itr != field._values.end(); )
843 {
844 switch (itr->second)
845 {
847 break;
849 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
850 const_cast<T&>(itr->first).ClearChangesMask();
851
852 itr->second = MapUpdateFieldState::Unchanged;
853 break;
855 itr = field._values.erase(itr++);
856 continue;
857 default:
858 break;
859 }
860
861 ++itr;
862 }
863 }
864
865 template<typename T>
867 {
868 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
869 if (field.has_value())
870 field._value->ClearChangesMask();
871 }
872
873 template<typename... Types>
875 {
876 if constexpr ((std::is_base_of_v<HasChangesMaskTag, Types> || ...))
877 std::visit([]<typename T>(T& value)
878 {
879 if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
880 value.ClearChangesMask();
881 }, field._value);
882 }
883
885 };
886
887 template<typename T>
889 {
890 template<typename F, bool PublicSet>
892
893 template<typename F, bool PublicSet>
895
896 template<typename F, bool PublicSet>
898
899 template<std::size_t Bits>
900 friend class HasChangesMask;
901
902 friend class UpdateFieldHolder;
903
904 public:
905 using value_type = T;
906
907 operator T const& () const
908 {
909 return _value;
910 }
911 T const* operator->() const
912 {
913 return &_value;
914 }
915 T const& operator*() const
916 {
917 return _value;
918 }
919
920 private:
921 T _value = {};
922 };
923
924 template<typename T, int32 BlockBit, uint32 Bit>
925 class UpdateField : public UpdateFieldBase<T>
926 {
927 };
928
929 template<typename T>
933
934 template<typename T, std::size_t Size>
936 {
937 template<typename F, bool PublicSet>
939
940 template<typename F, bool PublicSet>
942
943 template<typename F, bool PublicSet>
945
946 template<std::size_t Bits>
947 friend class HasChangesMask;
948
949 public:
950 using value_type = T;
951
952 T const* begin() const
953 {
954 return std::begin(_values);
955 }
956
957 T const* end() const
958 {
959 return std::end(_values);
960 }
961
962 static constexpr std::size_t size()
963 {
964 return Size;
965 }
966
967 T const& operator[](std::size_t index) const
968 {
969 return _values[index];
970 }
971
972 private:
973 T _values[Size] = {};
974 };
975
976 // workaround functions for internal compiler errors in msvc 19.33.31629
977 template<typename T>
978 constexpr std::size_t size()
979 {
980 return T::size();
981 }
982
983 template<typename T>
984 constexpr std::size_t size_of_value_type()
985 {
986 return sizeof(typename T::value_type);
987 }
988
989 template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
991 {
992 };
993
994 void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data, int32 bitsForSize = 32);
995
996 template<typename T>
998 {
999 template<typename F, bool PublicSet>
1001
1002 template<typename F, bool PublicSet>
1004
1005 template<typename F, bool PublicSet>
1007
1008 template<std::size_t Bits>
1009 friend class HasChangesMask;
1010
1011 public:
1012 using value_type = T;
1013
1014 T const* data() const
1015 {
1016 return _values.data();
1017 }
1018
1019 typename std::vector<T>::const_iterator begin() const
1020 {
1021 return _values.begin();
1022 }
1023
1024 typename std::vector<T>::const_iterator end() const
1025 {
1026 return _values.end();
1027 }
1028
1029 bool empty() const
1030 {
1031 return _values.empty();
1032 }
1033
1034 std::size_t size() const
1035 {
1036 return _values.size();
1037 }
1038
1039 T const& operator[](std::size_t index) const
1040 {
1041 return _values[index];
1042 }
1043
1044 int32 FindIndex(T const& value) const
1045 {
1046 auto itr = std::find(_values.begin(), _values.end(), value);
1047 if (itr != _values.end())
1048 return int32(std::distance(_values.begin(), itr));
1049
1050 return -1;
1051 }
1052
1053 template<typename Pred>
1054 int32 FindIndexIf(Pred pred) const
1055 {
1056 auto itr = std::find_if(_values.begin(), _values.end(), std::ref(pred));
1057 if (itr != _values.end())
1058 return int32(std::distance(_values.begin(), itr));
1059
1060 return -1;
1061 }
1062
1063 bool HasChanged(uint32 index) const
1064 {
1066 }
1067
1068 void WriteUpdateMask(ByteBuffer& data, int32 bitsForSize = 32) const
1069 {
1070 WriteDynamicFieldUpdateMask(_values.size(), _updateMask, data, bitsForSize);
1071 }
1072
1073 private:
1074 void MarkChanged(std::size_t index)
1075 {
1077 }
1078
1079 void ClearChanged(std::size_t index)
1080 {
1081 _updateMask[UpdateMaskHelpers::GetBlockIndex(index)] &= ~UpdateMaskHelpers::GetBlockFlag(index);
1082 }
1083
1085 {
1086 std::memset(_updateMask.data(), 0, _updateMask.size() * sizeof(uint32));
1087 }
1088
1089 std::vector<T> _values;
1090 std::vector<uint32> _updateMask;
1091 };
1092
1093 template<typename T, int32 BlockBit, uint32 Bit>
1095 {
1096 };
1097
1098 template<typename K, typename V>
1100 {
1101 template<typename F, bool PublicSet>
1103
1104 template<typename F, bool PublicSet>
1106
1107 template<typename F, bool PublicSet>
1109
1110 template<std::size_t Bits>
1111 friend class HasChangesMask;
1112
1113 public:
1119
1120 using key_type = K;
1122 using value_type = std::pair<key_type const, mapped_type>;
1123
1124 typename std::unordered_map<K, Value>::const_iterator begin() const
1125 {
1126 return _values.begin();
1127 }
1128
1129 typename std::unordered_map<K, Value>::const_iterator end() const
1130 {
1131 return _values.end();
1132 }
1133
1134 bool empty() const
1135 {
1136 return _values.empty();
1137 }
1138
1139 std::size_t size() const
1140 {
1141 return _values.size();
1142 }
1143
1144 V const* Get(K const& key) const
1145 {
1146 auto itr = _values.find(key);
1147 if (itr != _values.end())
1148 return &itr->second.value;
1149
1150 return nullptr;
1151 }
1152
1153 template <Trinity::invocable_r<bool, V const&> Pred>
1154 std::pair<K const*, V const*> FindIf(Pred&& pred) const
1155 {
1156 auto itr = std::ranges::find_if(_values, std::forward<Pred>(pred),
1157 [](value_type const& pair) -> V const& { return pair.second.value; });
1158 if (itr != _values.end())
1159 return std::make_pair(&itr->first, &itr->second.value);
1160
1161 return { nullptr, nullptr };
1162 }
1163
1164 private:
1165 std::unordered_map<K, Value> _values;
1166 };
1167
1168 template<typename K, typename V, int32 BlockBit, uint32 Bit>
1170 {
1171 };
1172
1173 template<typename T>
1175 {
1176 template<typename F, bool PublicSet>
1178
1179 template<typename F, bool PublicSet>
1181
1182 template<typename F, bool PublicSet>
1184
1185 template<std::size_t Bits>
1186 friend class HasChangesMask;
1187
1188 public:
1189 using key_type = T;
1191 using value_type = std::pair<key_type const, mapped_type>;
1192
1193 typename std::unordered_map<T, MapUpdateFieldState>::const_iterator begin() const
1194 {
1195 return _values.begin();
1196 }
1197
1198 typename std::unordered_map<T, MapUpdateFieldState>::const_iterator end() const
1199 {
1200 return _values.end();
1201 }
1202
1203 bool empty() const
1204 {
1205 return _values.empty();
1206 }
1207
1208 std::size_t size() const
1209 {
1210 return _values.size();
1211 }
1212
1213 private:
1214 std::unordered_map<T, MapUpdateFieldState> _values;
1215 };
1216
1217 template<typename T, int32 BlockBit, uint32 Bit>
1219 {
1220 };
1221
1222 template<typename T>
1224 {
1225 template<typename F, bool PublicSet>
1227
1228 template<typename F, bool PublicSet>
1230
1231 template<typename F, bool PublicSet>
1233
1234 template<std::size_t Bits>
1235 friend class HasChangesMask;
1236
1237 template<typename F>
1239
1240 friend class UpdateFieldHolder;
1241
1242 public:
1243 using value_type = T;
1244 using IsLarge = std::integral_constant<bool, sizeof(void*) * 3 < sizeof(T)>;
1245 using StorageType = std::conditional_t<IsLarge::value, std::unique_ptr<T>, Optional<T>>;
1246
1247 bool has_value() const
1248 {
1249 return !!_value;
1250 }
1251
1252 operator bool() const
1253 {
1254 return has_value();
1255 }
1256 T const* operator->() const
1257 {
1258 return &(*_value);
1259 }
1260 T const& operator*() const
1261 {
1262 return *_value;
1263 }
1264
1265 private:
1267 {
1268 if constexpr (IsLarge::value)
1269 _value = std::make_unique<T>();
1270 else
1271 _value.emplace();
1272 }
1273
1275 {
1276 _value.reset();
1277 }
1278
1280 };
1281
1282 template<typename T, int32 BlockBit, uint32 Bit>
1284 {
1285 };
1286
1287 template<typename... Types>
1289 {
1290 template<typename F, bool PublicSet>
1292
1293 template<typename F, bool PublicSet>
1295
1296 template<typename F, bool PublicSet>
1298
1299 template<std::size_t Bits>
1300 friend class HasChangesMask;
1301
1302 public:
1303 template<typename T>
1304 bool Is() const { return std::holds_alternative<T>(_value); }
1305
1306 template<typename T>
1307 T const* Get() const noexcept
1308 {
1309 if (std::holds_alternative<T>(_value))
1310 return &std::get<T>(_value);
1311 return nullptr;
1312 }
1313
1314 template<typename Visitor>
1315 decltype(auto) Visit(Visitor&& visitor) const noexcept
1316 {
1317 return std::visit(std::forward<Visitor>(visitor), _value);
1318 }
1319
1320 private:
1321 template<typename T>
1323 {
1324 _value.template emplace<T>();
1325 }
1326
1327 template<typename T>
1328 T* Get() noexcept
1329 {
1330 if (std::holds_alternative<T>(_value))
1331 return &std::get<T>(_value);
1332 return nullptr;
1333 }
1334
1335 std::variant<std::monostate, Types...> _value;
1336 };
1337
1338 template<int32 BlockBit, uint32 Bit, typename... Types>
1340 {
1341 };
1342
1343 template<typename T>
1345 {
1346 using value_type = T;
1347 };
1348}
1349
1350#endif // UpdateField_h__
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
#define DEFINE_ENUM_FLAG(enumType)
Definition EnumFlag.h:26
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
std::vector< T >::const_iterator begin() const
void ClearChanged(std::size_t index)
std::vector< T >::const_iterator end() const
bool HasChanged(uint32 index) const
void MarkChanged(std::size_t index)
T const & operator[](std::size_t index) const
void WriteUpdateMask(ByteBuffer &data, int32 bitsForSize=32) const
std::vector< uint32 > _updateMask
std::size_t size() const
int32 FindIndexIf(Pred pred) const
int32 FindIndex(T const &value) const
static void ClearChangesMask(OptionalUpdateFieldBase< T > &field)
void ClearChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(UpdateFieldArrayBase< T, Size > &field)
static void ClearChangesMask(UpdateFieldBase< T > &field)
void MarkChanged(VariantUpdateField< BlockBit, Bit, Types... >(Derived::*))
void ClearChanged(MapUpdateField< K, V, BlockBit, Bit >(Derived::*))
void ClearChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
void MarkChanged(OptionalUpdateField< T, BlockBit, Bit >(Derived::*))
Mask const & GetChangesMask() const
void MarkChanged(MapUpdateField< K, V, BlockBit, Bit >(Derived::*))
void ClearChanged(VariantUpdateField< BlockBit, Bit, Types... >(Derived::*))
void MarkChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*))
void ClearChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
void MarkChanged(SetUpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(VariantUpdateFieldBase< Types... > &field)
void ClearChanged(SetUpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(SetUpdateFieldBase< T > &field)
void MarkChanged(UpdateFieldArray< T, Size, Bit, FirstElementBit >(Derived::*), uint32 index)
void MarkChanged(UpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(MapUpdateFieldBase< K, V > &field)
void ClearChanged(DynamicUpdateField< T, BlockBit, Bit >(Derived::*))
static void ClearChangesMask(DynamicUpdateFieldBase< T > &field)
std::unordered_map< K, Value > _values
V const * Get(K const &key) const
std::unordered_map< K, Value >::const_iterator end() const
std::pair< K const *, V const * > FindIf(Pred &&pred) const
std::unordered_map< K, Value >::const_iterator begin() const
std::size_t size() const
std::pair< key_type const, mapped_type > value_type
T const & operator*() const
std::integral_constant< bool, sizeof(void *) *3< sizeof(T)> IsLarge
std::conditional_t< IsLarge::value, std::unique_ptr< T >, Optional< T > > StorageType
T const * operator->() const
std::unordered_map< T, MapUpdateFieldState >::const_iterator begin() const
std::unordered_map< T, MapUpdateFieldState >::const_iterator end() const
std::size_t size() const
std::unordered_map< T, MapUpdateFieldState > _values
std::pair< key_type const, mapped_type > value_type
T const * begin() const
static constexpr std::size_t size()
T const & operator[](std::size_t index) const
T const * end() const
T const & operator*() const
T const * operator->() const
T const * Get() const noexcept
decltype(auto) Visit(Visitor &&visitor) const noexcept
std::variant< std::monostate, Types... > _value
constexpr void Reset(uint32 index)
Definition UpdateMask.h:78
constexpr void Set(uint32 index)
Definition UpdateMask.h:91
constexpr std::size_t size()
constexpr std::type_identity< T > VariantCase
Definition UpdateField.h:87
std::conditional_t< PublicSet, UpdateFieldPublicSetter< T >, UpdateFieldPrivateSetter< T > > UpdateFieldSetter
UpdateFieldFlag
Definition UpdateField.h:37
void WriteDynamicFieldUpdateMask(std::size_t size, std::vector< uint32 > const &updateMask, ByteBuffer &data, int32 bitsForSize=32)
constexpr std::size_t size_of_value_type()
std::conditional_t< std::is_base_of_v< HasChangesMaskTag, T >, MutableFieldReferenceWithChangesMask< T, PublicSet >, MutableFieldReferenceNoChangesMask< T, PublicSet > > MutableFieldReference
MapUpdateFieldState
constexpr std::size_t GetBlockIndex(std::size_t bit)
Definition UpdateMask.h:27
constexpr uint32 GetBlockFlag(std::size_t bit)
Definition UpdateMask.h:28
STL namespace.
DynamicUpdateFieldSetter(std::vector< T > &values, std::vector< uint32 > &updateMask)
friend void ClearDynamicUpdateFieldValues(DynamicUpdateFieldSetter< F > &setter)
friend DynamicUpdateFieldSetter< F >::insert_result InsertDynamicUpdateFieldValue(DynamicUpdateFieldSetter< F > &setter, uint32 index)
friend DynamicUpdateFieldSetter< F >::insert_result AddDynamicUpdateFieldValue(DynamicUpdateFieldSetter< F > &setter)
friend void RemoveDynamicUpdateFieldValue(DynamicUpdateFieldSetter< F > &setter, uint32 index)
std::conditional_t< std::is_base_of_v< HasChangesMaskTag, T >, MutableFieldReference< T, true >, T & > insert_result
void RemoveValue(std::size_t index)
std::vector< T > & _values
void MarkChanged(std::size_t index)
std::vector< uint32 > & _updateMask
insert_result InsertValue(std::size_t index)
MapUpdateFieldState state
bool RemoveKey(K const &key)
friend bool RemoveMapUpdateFieldValue(MapUpdateFieldSetter< F, G > &setter, std::type_identity_t< F > const &key)
std::unordered_map< K, V > & _values
MapUpdateFieldSetter(std::unordered_map< K, V > &values)
UpdateFieldSetter< V, PublicSet > ModifyValue(V(T::*field)[Size], uint32 index)
UpdateFieldSetter< V, PublicSet > ModifyValue(V(T::*field))
DynamicUpdateFieldSetter< V > ModifyValue(DynamicUpdateField< V, BlockBit, Bit >(T::*field))
std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, V >, MutableFieldReference< V, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, V >, MutableNestedFieldReference< V, PublicSet >, UpdateFieldSetter< V, PublicSet > > > ModifyValue(UpdateField< V, BlockBit, Bit >(T::*field))
MapUpdateFieldSetter< K, typename MapUpdateField< K, V, BlockBit, Bit >::mapped_type > ModifyValue(MapUpdateField< K, V, BlockBit, Bit >(T::*field))
std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, V >, MutableFieldReference< V, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, V >, MutableNestedFieldReference< V, PublicSet >, UpdateFieldSetter< V, PublicSet > > > ModifyValue(DynamicUpdateField< V, BlockBit, Bit >(T::*field), uint32 index)
OptionalUpdateFieldSetter< V > ModifyValue(OptionalUpdateField< V, BlockBit, Bit >(T::*field))
std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, V >, MutableFieldReference< V, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, V >, MutableNestedFieldReference< V, PublicSet >, UpdateFieldSetter< V, PublicSet > > > ModifyValue(UpdateFieldArray< V, Size, Bit, FirstElementBit >(T::*field), uint32 index)
std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, V >, MutableFieldReference< V, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, V >, MutableNestedFieldReference< V, PublicSet >, UpdateFieldSetter< V, PublicSet > > > ModifyValue(OptionalUpdateField< V, BlockBit, Bit >(T::*field), uint32)
SetUpdateFieldSetter< V > ModifyValue(SetUpdateField< V, BlockBit, Bit >(T::*field))
std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, V >, MutableFieldReference< V, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, V >, MutableNestedFieldReference< V, PublicSet >, UpdateFieldSetter< V, PublicSet > > > ModifyValue(VariantUpdateField< BlockBit, Bit, Types... >(T::*field), std::type_identity< V > type)
std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, V >, MutableFieldReference< V, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, V >, MutableNestedFieldReference< V, PublicSet >, UpdateFieldSetter< V, PublicSet > > > ModifyValue(MapUpdateField< K, V, BlockBit, Bit >(T::*field), std::type_identity_t< K > const &key)
typename T::value_type value_type
std::enable_if_t< std::is_base_of_v< DynamicUpdateFieldBase< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, MutableFieldReference< value_type, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, value_type >, MutableNestedFieldReference< value_type, PublicSet >, UpdateFieldSetter< value_type, PublicSet > > > > ModifyValue(uint32 index)
std::enable_if_t< std::is_base_of_v< OptionalUpdateFieldBase< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, MutableFieldReference< value_type, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, value_type >, MutableNestedFieldReference< value_type, PublicSet >, UpdateFieldSetter< value_type, PublicSet > > > > ModifyValue(uint32)
std::enable_if_t< std::is_base_of_v< DynamicUpdateFieldBase< value_type >, U >, DynamicUpdateFieldSetter< value_type > > ModifyValue()
std::enable_if_t< std::is_base_of_v< UpdateFieldArrayBaseWithoutSize< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, MutableFieldReference< value_type, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, value_type >, MutableNestedFieldReference< value_type, PublicSet >, UpdateFieldSetter< value_type, PublicSet > > > > ModifyValue(uint32 index)
std::enable_if_t< std::is_base_of_v< UpdateFieldBase< value_type >, U >, std::conditional_t< std::is_base_of_v< IsUpdateFieldStructureTag, value_type >, MutableFieldReference< value_type, PublicSet >, std::conditional_t< std::is_base_of_v< IsUpdateFieldHolderTag, value_type >, MutableNestedFieldReference< value_type, PublicSet >, UpdateFieldSetter< value_type, PublicSet > > > > ModifyValue()
std::enable_if_t< std::is_base_of_v< OptionalUpdateFieldBase< value_type >, U >, OptionalUpdateFieldSetter< value_type > > ModifyValue()
friend bool RemoveOptionalUpdateFieldValue(OptionalUpdateFieldSetter< F > &setter)
OptionalUpdateFieldSetter(OptionalUpdateFieldBase< T > &field)
OptionalUpdateFieldBase< T > & _field
bool Remove(T const &key)
friend bool RemoveSetUpdateFieldValue(SetUpdateFieldSetter< F > &setter, std::type_identity_t< F > const &key)
std::unordered_map< T, MapUpdateFieldState > & _values
bool Insert(T const &key)
SetUpdateFieldSetter(std::unordered_map< T, MapUpdateFieldState > &values)
friend bool SetUpdateFieldValue(UpdateFieldPrivateSetter< F > &setter, typename UpdateFieldPrivateSetter< F >::value_type &&value)