xrpld
Loading...
Searching...
No Matches
STObject.h
1#pragma once
2
3#include <xrpl/basics/Blob.h>
4#include <xrpl/basics/CountedObject.h>
5#include <xrpl/basics/Number.h>
6#include <xrpl/basics/Slice.h>
7#include <xrpl/basics/base_uint.h>
8#include <xrpl/basics/contract.h>
9#include <xrpl/beast/utility/instrumentation.h>
10#include <xrpl/json/json_value.h>
11#include <xrpl/protocol/AccountID.h>
12#include <xrpl/protocol/HashPrefix.h>
13#include <xrpl/protocol/SField.h>
14#include <xrpl/protocol/SOTemplate.h>
15#include <xrpl/protocol/STAmount.h>
16#include <xrpl/protocol/STBase.h>
17#include <xrpl/protocol/STBitString.h>
18#include <xrpl/protocol/STCurrency.h>
19#include <xrpl/protocol/STIssue.h>
20#include <xrpl/protocol/STPathSet.h>
21#include <xrpl/protocol/STVector256.h>
22#include <xrpl/protocol/Serializer.h>
23#include <xrpl/protocol/Units.h>
24#include <xrpl/protocol/detail/STVar.h>
25
26#include <boost/iterator/transform_iterator.hpp>
27
28#include <cstddef>
29#include <cstdint>
30#include <memory>
31#include <optional>
32#include <stdexcept>
33#include <string>
34#include <type_traits>
35#include <utility>
36#include <vector>
37
38namespace xrpl {
39
40class STArray;
41
42inline void
44{
45 Throw<std::runtime_error>("Field not found: " + field.getName());
46}
47
48class STObject : public STBase, public CountedObject<STObject>
49{
50 // Proxy value for a STBase derived class
51 template <class T>
52 class Proxy;
53 template <class T>
54 class ValueProxy;
55 template <class T>
56 class OptionalProxy;
57
58 struct Transform
59 {
60 explicit Transform() = default;
61
64
65 STBase const&
66 operator()(detail::STVar const& e) const;
67 };
68
70
72 SOTemplate const* type_{};
73
74public:
75 using iterator = boost::transform_iterator<Transform, STObject::list_type::const_iterator>;
76
77 ~STObject() override = default;
78 STObject(STObject const&) = default;
79
80 template <typename F>
81 STObject(SOTemplate const& type, SField const& name, F&& f) : STObject(type, name)
82 {
83 f(*this);
84 }
85
87 operator=(STObject const&) = default;
90 operator=(STObject&& other);
91
92 STObject(SOTemplate const& type, SField const& name);
94 SOTemplate const& type,
95 SerialIter& sit,
96 SField const& name,
97 bool requireCanonicalOrder = false);
98 STObject(SerialIter& sit, SField const& name, int depth = 0);
99 STObject(SerialIter&& sit, SField const& name);
100 explicit STObject(SField const& name);
101
102 static STObject
103 makeInnerObject(SField const& name);
104
105 [[nodiscard]] iterator
106 begin() const;
107
108 [[nodiscard]] iterator
109 end() const;
110
111 [[nodiscard]] bool
112 empty() const;
113
114 void
116
117 void
118 applyTemplate(SOTemplate const& type);
119
120 void
122
123 [[nodiscard]] bool
124 isFree() const;
125
126 void
127 set(SOTemplate const&);
128
129 bool
130 set(SerialIter& u, int depth = 0, bool requireCanonicalOrder = false);
131
132 [[nodiscard]] SerializedTypeID
133 getSType() const override;
134
135 [[nodiscard]] bool
136 isEquivalent(STBase const& t) const override;
137
138 [[nodiscard]] bool
139 isDefault() const override;
140
141 void
142 add(Serializer& s) const override;
143
144 [[nodiscard]] std::string
145 getFullText() const override;
146
147 [[nodiscard]] std::string
148 getText() const override;
149
150 // TODO(tom): options should be an enum.
151 [[nodiscard]] json::Value getJson(JsonOptions = JsonOptions::Values::None) const override;
152
153 void
155
156 [[nodiscard]] Serializer
157 getSerializer() const;
158
159 template <class... Args>
161 emplaceBack(Args&&... args);
162
163 [[nodiscard]] int
164 getCount() const;
165
166 bool
168 bool
170 [[nodiscard]] bool
171 isFlag(std::uint32_t) const;
172
173 [[nodiscard]] std::uint32_t
174 getFlags() const;
175
176 [[nodiscard]] uint256
177 getHash(HashPrefix prefix) const;
178
179 [[nodiscard]] uint256
180 getSigningHash(HashPrefix prefix) const;
181
182 [[nodiscard]] STBase const&
183 peekAtIndex(int offset) const;
184
185 STBase&
186 getIndex(int offset);
187
188 [[nodiscard]] STBase const*
189 peekAtPIndex(int offset) const;
190
191 STBase*
192 getPIndex(int offset);
193
194 [[nodiscard]] int
195 getFieldIndex(SField const& field) const;
196
197 [[nodiscard]] SField const&
198 getFieldSType(int index) const;
199
200 [[nodiscard]] STBase const&
201 peekAtField(SField const& field) const;
202
203 STBase&
204 getField(SField const& field);
205
206 [[nodiscard]] STBase const*
207 peekAtPField(SField const& field) const;
208
209 STBase*
210 getPField(SField const& field, bool createOkay = false);
211
212 // these throw if the field type doesn't match, or return default values
213 // if the field is optional but not present
214 [[nodiscard]] unsigned char
215 getFieldU8(SField const& field) const;
216 [[nodiscard]] std::uint16_t
217 getFieldU16(SField const& field) const;
218 [[nodiscard]] std::uint32_t
219 getFieldU32(SField const& field) const;
220 [[nodiscard]] std::uint64_t
221 getFieldU64(SField const& field) const;
222 [[nodiscard]] uint128
223 getFieldH128(SField const& field) const;
224
225 [[nodiscard]] uint160
226 getFieldH160(SField const& field) const;
227 [[nodiscard]] uint192
228 getFieldH192(SField const& field) const;
229 [[nodiscard]] uint256
230 getFieldH256(SField const& field) const;
231 [[nodiscard]] std::int32_t
232 getFieldI32(SField const& field) const;
233 [[nodiscard]] AccountID
234 getAccountID(SField const& field) const;
235
236 [[nodiscard]] Blob
237 getFieldVL(SField const& field) const;
238 [[nodiscard]] STAmount const&
239 getFieldAmount(SField const& field) const;
240 [[nodiscard]] STPathSet const&
241 getFieldPathSet(SField const& field) const;
242 [[nodiscard]] STVector256 const&
243 getFieldV256(SField const& field) const;
244 // If not found, returns an object constructed with the given field
245 [[nodiscard]] STObject
246 getFieldObject(SField const& field) const;
247 [[nodiscard]] STArray const&
248 getFieldArray(SField const& field) const;
249 [[nodiscard]] STCurrency const&
250 getFieldCurrency(SField const& field) const;
251 [[nodiscard]] STNumber const&
252 getFieldNumber(SField const& field) const;
253
262 template <class T>
263 T::value_type
264 operator[](TypedField<T> const& f) const;
265
275 template <class T>
277 operator[](OptionaledField<T> const& of) const;
278
287 template <class T>
289 operator[](TypedField<T> const& f);
290
301 template <class T>
304
313 template <class T>
314 [[nodiscard]] T::value_type
315 at(TypedField<T> const& f) const;
316
326 template <class T>
328 at(OptionaledField<T> const& of) const;
329
338 template <class T>
340 at(TypedField<T> const& f);
341
352 template <class T>
354 at(OptionaledField<T> const& of);
355
360 void
362
363 void
364 set(STBase&& v);
365
366 void
367 setFieldU8(SField const& field, unsigned char);
368 void
369 setFieldU16(SField const& field, std::uint16_t);
370 void
371 setFieldU32(SField const& field, std::uint32_t);
372 void
373 setFieldU64(SField const& field, std::uint64_t);
374 void
375 setFieldH128(SField const& field, uint128 const&);
376 void
377 setFieldH192(SField const& field, uint192 const&);
378 void
379 setFieldH256(SField const& field, uint256 const&);
380 void
381 setFieldI32(SField const& field, std::int32_t);
382 void
383 setFieldVL(SField const& field, Blob const&);
384 void
385 setFieldVL(SField const& field, Slice const&);
386
387 void
388 setAccountID(SField const& field, AccountID const&);
389
390 void
391 setFieldAmount(SField const& field, STAmount const&);
392 void
393 setFieldIssue(SField const& field, STIssue const&);
394 void
395 setFieldCurrency(SField const& field, STCurrency const&);
396 void
397 setFieldNumber(SField const& field, STNumber const&);
398 void
399 setFieldPathSet(SField const& field, STPathSet const&);
400 void
401 setFieldV256(SField const& field, STVector256 const& v);
402 void
403 setFieldArray(SField const& field, STArray const& v);
404 void
405 setFieldObject(SField const& field, STObject const& v);
406
407 template <class Tag>
408 void
409 setFieldH160(SField const& field, BaseUInt<160, Tag> const& v);
410
411 STObject&
412 peekFieldObject(SField const& field);
413 STArray&
414 peekFieldArray(SField const& field);
415
416 [[nodiscard]] bool
417 isFieldPresent(SField const& field) const;
418 STBase*
419 makeFieldPresent(SField const& field);
420 void
421 makeFieldAbsent(SField const& field);
422 bool
423 delField(SField const& field);
424 void
425 delField(int index);
426
427 [[nodiscard]] SOEStyle
428 getStyle(SField const& field) const;
429
430 [[nodiscard]] bool
431 hasMatchingEntry(STBase const&) const;
432
433 bool
434 operator==(STObject const& o) const;
435
436 class FieldErr;
437
438private:
439 enum class WhichFields : bool {
440 // These values are carefully chosen to do the right thing if passed
441 // to SField::shouldInclude (bool)
444 };
445
446 void
447 add(Serializer& s, WhichFields whichFields) const;
448
449 // Sort the entries in an STObject into the order that they will be
450 // serialized. Note: they are not sorted into pointer value order, they
451 // are sorted by SField::fieldCode.
453 getSortedFields(STObject const& objToSort, WhichFields whichFields);
454
455 // Implementation for getting (most) fields that return by value.
456 //
457 // The remove_cv and remove_reference are necessitated by the STBitString
458 // types. Their value() returns by const ref. We return those types
459 // by value.
460 template <
461 typename T,
463 V
464 getFieldByValue(SField const& field) const;
465
466 // Implementations for getting (most) fields that return by const reference.
467 //
468 // If an absent optional field is deserialized we don't have anything
469 // obvious to return. So we insist on having the call provide an
470 // 'empty' value we return in that circumstance.
471 template <typename T, typename V>
472 V const&
473 getFieldByConstRef(SField const& field, V const& empty) const;
474
475 // Implementation for setting most fields with a setValue() method.
476 template <typename T, typename V>
477 void
478 setFieldUsingSetValue(SField const& field, V value);
479
480 // Implementation for setting fields using assignment
481 template <typename T>
482 void
483 setFieldUsingAssignment(SField const& field, T const& value);
484
485 // Implementation for peeking STObjects and STArrays
486 template <typename T>
487 T&
488 peekField(SField const& field);
489
490 STBase*
491 copy(std::size_t n, void* buf) const override;
492 STBase*
493 move(std::size_t n, void* buf) override;
494
495 friend class detail::STVar;
496};
497
498//------------------------------------------------------------------------------
499
500template <class T>
502{
503public:
504 using value_type = T::value_type;
505
506 [[nodiscard]] value_type
507 value() const;
508
510 operator*() const;
511
516 T const*
517 operator->() const;
518
519protected:
523
524 Proxy(Proxy const&) = default;
525
526 Proxy(STObject* st, TypedField<T> const* f);
527
528 [[nodiscard]] T const*
529 find() const;
530
531 template <class U>
532 void
533 assign(U&& u);
534};
535
536// Constraint += and -= ValueProxy operators
537// to value types that support arithmetic operations
538template <typename U>
541template <typename U, typename Value = U::value_type, typename Unit = U::unit_type>
544template <typename U, typename Value = U::value_type>
546template <typename U>
548
549template <class T, class U>
550concept Addable = requires(T t, U u) { t = t + u; };
551template <typename T, typename U>
554
555template <class T>
557{
558private:
559 using value_type = T::value_type;
560
561public:
562 ValueProxy(ValueProxy const&) = default;
564 operator=(ValueProxy const&) = delete;
565
566 // Write-through proxy: assignment sets the referenced field to the given
567 // value, so it intentionally takes the assigned value rather than a
568 // ValueProxy.
569 template <class U>
570 // NOLINTNEXTLINE(misc-unconventional-assign-operator)
574
575 // Convenience operators for value types supporting
576 // arithmetic operations
577 template <IsArithmetic U>
580 operator+=(U const& u);
581
582 template <IsArithmetic U>
585 operator-=(U const& u);
586
587 operator value_type() const;
588
589 template <typename U>
590 friend bool
591 operator==(U const& lhs, STObject::ValueProxy<T> const& rhs)
592 {
593 return rhs.value() == lhs;
594 }
595
596private:
597 friend class STObject;
598
599 ValueProxy(STObject* st, TypedField<T> const* f);
600};
601
602template <class T>
604{
605private:
606 using value_type = T::value_type;
607
609
610public:
611 OptionalProxy(OptionalProxy const&) = default;
613 operator=(OptionalProxy const&) = delete;
614
621 explicit
622 operator bool() const noexcept;
623
624 operator optional_type() const;
625
630 operator~() const;
631
632 friend bool
633 operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
634 {
635 return !lhs.engaged();
636 }
637
638 friend bool
640 {
641 return rhs == std::nullopt;
642 }
643
644 friend bool
645 operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
646 {
647 if (!lhs.engaged())
648 return !rhs;
649 if (!rhs)
650 return false;
651 return *lhs == *rhs;
652 }
653
654 friend bool
655 operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
656 {
657 return rhs == lhs;
658 }
659
660 friend bool
661 operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
662 {
663 if (lhs.engaged() != rhs.engaged())
664 return false;
665 return !lhs.engaged() || *lhs == *rhs;
666 }
667
668 // Emulate std::optional::value_or
669 [[nodiscard]] value_type
670 valueOr(value_type val) const;
671
675 operator=(optional_type&& v); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
677 operator=(optional_type const& v);
678
679 template <class U>
683
684private:
685 friend class STObject;
686
687 OptionalProxy(STObject* st, TypedField<T> const* f);
688
689 [[nodiscard]] bool
690 engaged() const noexcept;
691
692 void
693 disengage();
694
695 [[nodiscard]] optional_type
696 optionalValue() const;
697};
698
703
704template <class T>
706{
707 if (st_->type_ != nullptr)
708 {
709 // STObject has associated template
710 if (!st_->peekAtPField(*f_))
711 Throw<STObject::FieldErr>("Template field error '" + this->f_->getName() + "'");
712 style_ = st_->type_->style(*f_);
713 }
714 else
715 {
716 style_ = SoeInvalid;
717 }
718}
719
720template <class T>
721auto
723{
724 auto const t = find();
725 if (t)
726 return t->value();
727 if (style_ == SoeInvalid)
728 {
729 Throw<STObject::FieldErr>("Value requested from invalid STObject.");
730 }
731 if (style_ != SoeDefault)
732 {
733 Throw<STObject::FieldErr>("Missing field '" + this->f_->getName() + "'");
734 }
735 return value_type{};
736}
737
738template <class T>
739auto
741{
742 return this->value();
743}
744
749template <class T>
750T const*
752{
753 return this->find();
754}
755
756template <class T>
757inline T const*
759{
760 return dynamic_cast<T const*>(st_->peekAtPField(*f_));
761}
762
763template <class T>
764template <class U>
765void
767{
768 if (style_ == SoeDefault && u == value_type{})
769 {
770 st_->makeFieldAbsent(*f_);
771 return;
772 }
773 T* t = nullptr;
774 if (style_ == SoeInvalid)
775 {
776 t = dynamic_cast<T*>(st_->getPField(*f_, true));
777 }
778 else
779 {
780 t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
781 }
782 XRPL_ASSERT(t, "xrpl::STObject::Proxy::assign : type cast succeeded");
783 *t = std::forward<U>(u);
784}
785
786//------------------------------------------------------------------------------
787
788template <class T>
789template <class U>
790// NOLINTNEXTLINE(misc-unconventional-assign-operator)
794{
795 this->assign(std::forward<U>(u));
796 return *this;
797}
798
799template <typename T>
800template <IsArithmetic U>
804{
805 this->assign(this->value() + u);
806 return *this;
807}
808
809template <class T>
810template <IsArithmetic U>
814{
815 this->assign(this->value() - u);
816 return *this;
817}
818
819template <class T>
821operator value_type() const
822{
823 return this->value();
824}
825
826template <class T>
830
831//------------------------------------------------------------------------------
832
833template <class T>
835operator bool() const noexcept
836{
837 return engaged();
838}
839
840template <class T>
842operator typename STObject::OptionalProxy<T>::optional_type() const
843{
844 return optionalValue();
845}
846
847template <class T>
853
854template <class T>
855auto
861
862template <class T>
863auto
865 optional_type&& v) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
866 -> OptionalProxy&
867{
868 if (v)
869 {
870 this->assign(std::move(*v));
871 }
872 else
873 {
874 disengage();
875 }
876 return *this;
877}
878
879template <class T>
880auto
882{
883 if (v)
884 {
885 this->assign(*v);
886 }
887 else
888 {
889 disengage();
890 }
891 return *this;
892}
893
894template <class T>
895template <class U>
899{
900 this->assign(std::forward<U>(u));
901 return *this;
902}
903
904template <class T>
908
909template <class T>
910bool
912{
913 return this->style_ == SoeDefault || this->find() != nullptr;
914}
915
916template <class T>
917void
919{
920 if (this->style_ == SoeRequired || this->style_ == SoeDefault)
921 Throw<STObject::FieldErr>("Template field error '" + this->f_->getName() + "'");
922 if (this->style_ == SoeInvalid)
923 {
924 this->st_->delField(*this->f_);
925 }
926 else
927 {
928 this->st_->makeFieldAbsent(*this->f_);
929 }
930}
931
932template <class T>
933auto
935{
936 if (!engaged())
937 return std::nullopt;
938 return this->value();
939}
940
941template <class T>
944{
945 return engaged() ? this->value() : val;
946}
947
948//------------------------------------------------------------------------------
949
950inline STBase const&
952{
953 return e.get();
954}
955
956//------------------------------------------------------------------------------
957
958// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
959inline STObject::STObject(SerialIter&& sit, SField const& name) : STObject(sit, name)
960{
961}
962
965{
966 return iterator(v_.begin());
967}
968
971{
972 return iterator(v_.end());
973}
974
975inline bool
977{
978 return v_.empty();
979}
980
981inline void
983{
984 v_.reserve(n);
985}
986
987inline bool
989{
990 return type_ == nullptr;
991}
992
993inline void
998
999// VFALCO NOTE does this return an expensive copy of an object with a
1000// dynamic buffer?
1001// VFALCO TODO Remove this function and fix the few callers.
1002inline Serializer
1004{
1005 Serializer s;
1007 return s;
1008}
1009
1010template <class... Args>
1011inline std::size_t
1013{
1014 v_.emplace_back(std::forward<Args>(args)...);
1015 return v_.size() - 1;
1016}
1017
1018inline int
1020{
1021 return v_.size();
1022}
1023
1024inline STBase const&
1025STObject::peekAtIndex(int offset) const
1026{
1027 return v_[offset].get();
1028}
1029
1030inline STBase&
1032{
1033 return v_[offset].get();
1034}
1035
1036inline STBase const*
1037STObject::peekAtPIndex(int offset) const
1038{
1039 return &v_[offset].get();
1040}
1041
1042inline STBase*
1044{
1045 return &v_[offset].get();
1046}
1047
1048template <class T>
1049T::value_type
1051{
1052 return at(f);
1053}
1054
1055template <class T>
1058{
1059 return at(of);
1060}
1061
1062template <class T>
1063inline auto
1065{
1066 return at(f);
1067}
1068
1069template <class T>
1070inline auto
1072{
1073 return at(of);
1074}
1075
1076template <class T>
1077[[nodiscard]] T::value_type
1079{
1080 auto const b = peekAtPField(f);
1081 if (!b)
1082 {
1083 // This is a free object (no constraints)
1084 // with no template
1085 Throw<STObject::FieldErr>("Missing field: " + f.getName());
1086 }
1087
1088 if (auto const u = dynamic_cast<T const*>(b))
1089 return u->value();
1090
1091 XRPL_ASSERT(type_, "xrpl::STObject::at(TypedField auto) : field template non-null");
1092 XRPL_ASSERT(
1093 b->getSType() == STI_NOTPRESENT, "xrpl::STObject::at(TypedField auto) : type not present");
1094
1095 if (type_->style(f) == SoeOptional)
1096 Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
1097
1098 XRPL_ASSERT(
1099 type_->style(f) == SoeDefault,
1100 "xrpl::STObject::at(TypedField auto) : template style is default");
1101
1102 // Used to help handle the case where value_type is a const reference,
1103 // otherwise we would return the address of a temporary.
1104 static std::decay_t<typename T::value_type> const kDV{};
1105 return kDV;
1106}
1107
1108template <class T>
1111{
1112 auto const b = peekAtPField(*of.f);
1113 if (!b)
1114 return std::nullopt;
1115 auto const u = dynamic_cast<T const*>(b);
1116 if (!u)
1117 {
1118 XRPL_ASSERT(
1119 type_,
1120 "xrpl::STObject::at(OptionaledField auto) : field template "
1121 "non-null");
1122 XRPL_ASSERT(
1123 b->getSType() == STI_NOTPRESENT,
1124 "xrpl::STObject::at(OptionaledField auto) : type not present");
1125 if (type_->style(*of.f) == SoeOptional)
1126 return std::nullopt;
1127 XRPL_ASSERT(
1128 type_->style(*of.f) == SoeDefault,
1129 "xrpl::STObject::at(OptionaledField auto) : template style is "
1130 "default");
1131 return typename T::value_type{};
1132 }
1133 return u->value();
1134}
1135
1136template <class T>
1137inline auto
1139{
1140 return ValueProxy<T>(this, &f);
1141}
1142
1143template <class T>
1144inline auto
1146{
1147 return OptionalProxy<T>(this, of.f);
1148}
1149
1150template <class Tag>
1151void
1153{
1154 STBase* rf = getPField(field, true);
1155
1156 if (!rf)
1157 throwFieldNotFound(field);
1158
1159 if (rf->getSType() == STI_NOTPRESENT)
1160 rf = makeFieldPresent(field);
1161
1162 using Bits = STBitString<160>;
1163 if (auto cf = dynamic_cast<Bits*>(rf))
1164 {
1165 cf->setValue(v);
1166 }
1167 else
1168 {
1169 Throw<std::runtime_error>("Wrong field type");
1170 }
1171}
1172
1173template <typename T, typename V>
1174V
1176{
1177 STBase const* rf = peekAtPField(field);
1178
1179 if (!rf)
1180 throwFieldNotFound(field);
1181
1182 SerializedTypeID const id = rf->getSType();
1183
1184 if (id == STI_NOTPRESENT)
1185 return V(); // optional field not present
1186
1187 T const* cf = dynamic_cast<T const*>(rf);
1188
1189 if (!cf)
1190 Throw<std::runtime_error>("Wrong field type");
1191
1192 return cf->value();
1193}
1194
1195// Implementations for getting (most) fields that return by const reference.
1196//
1197// If an absent optional field is deserialized we don't have anything
1198// obvious to return. So we insist on having the call provide an
1199// 'empty' value we return in that circumstance.
1200template <typename T, typename V>
1201V const&
1202STObject::getFieldByConstRef(SField const& field, V const& empty) const
1203{
1204 STBase const* rf = peekAtPField(field);
1205
1206 if (!rf)
1207 throwFieldNotFound(field);
1208
1209 SerializedTypeID const id = rf->getSType();
1210
1211 if (id == STI_NOTPRESENT)
1212 {
1213 // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
1214 return empty; // optional field not present
1215 }
1216
1217 T const* cf = dynamic_cast<T const*>(rf);
1218
1219 if (!cf)
1220 Throw<std::runtime_error>("Wrong field type");
1221
1222 return *cf;
1223}
1224
1225// Implementation for setting most fields with a setValue() method.
1226template <typename T, typename V>
1227void
1229{
1230 static_assert(!std::is_lvalue_reference_v<V>);
1231
1232 STBase* rf = getPField(field, true);
1233
1234 if (!rf)
1235 throwFieldNotFound(field);
1236
1237 if (rf->getSType() == STI_NOTPRESENT)
1238 rf = makeFieldPresent(field);
1239
1240 T* cf = dynamic_cast<T*>(rf);
1241
1242 if (!cf)
1243 Throw<std::runtime_error>("Wrong field type");
1244
1245 cf->setValue(std::move(value));
1246}
1247
1248// Implementation for setting fields using assignment
1249template <typename T>
1250void
1251STObject::setFieldUsingAssignment(SField const& field, T const& value)
1252{
1253 STBase* rf = getPField(field, true);
1254
1255 if (!rf)
1256 throwFieldNotFound(field);
1257
1258 if (rf->getSType() == STI_NOTPRESENT)
1259 rf = makeFieldPresent(field);
1260
1261 T* cf = dynamic_cast<T*>(rf);
1262
1263 if (!cf)
1264 Throw<std::runtime_error>("Wrong field type");
1265
1266 (*cf) = value;
1267}
1268
1269// Implementation for peeking STObjects and STArrays
1270template <typename T>
1271T&
1273{
1274 STBase* rf = getPField(field, true);
1275
1276 if (!rf)
1277 throwFieldNotFound(field);
1278
1279 if (rf->getSType() == STI_NOTPRESENT)
1280 rf = makeFieldPresent(field);
1281
1282 T* cf = dynamic_cast<T*>(rf);
1283
1284 if (!cf)
1285 Throw<std::runtime_error>("Wrong field type");
1286
1287 return *cf;
1288}
1289
1290} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
Integers of any length that is a multiple of 32-bits.
Definition base_uint.h:82
Identifies fields.
Definition SField.h:132
std::string const & getName() const
Definition SField.h:198
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:105
A type which can be exported to a well known binary format.
Definition STBase.h:129
virtual SerializedTypeID getSType() const
Definition STBase.cpp:54
A serializable number.
Definition STNumber.h:42
T runtime_error(T... args)
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition STObject.h:645
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:655
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:661
OptionalProxy(OptionalProxy const &)=default
value_type valueOr(value_type val) const
Definition STObject.h:943
optional_type operator~() const
Explicit conversion to std::optional.
Definition STObject.h:849
OptionalProxy & operator=(U &&u)
std::optional< std::decay_t< value_type > > optional_type
Definition STObject.h:608
OptionalProxy & operator=(OptionalProxy const &)=delete
optional_type optionalValue() const
Definition STObject.h:934
bool engaged() const noexcept
Definition STObject.h:911
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition STObject.h:639
void assign(U &&u)
Definition STObject.h:766
Proxy(Proxy const &)=default
T::value_type value_type
Definition STObject.h:504
value_type operator*() const
Definition STObject.h:740
T const * operator->() const
Do not use operator->() unless the field is required, or you've checked that it's set.
Definition STObject.h:751
value_type value() const
Definition STObject.h:722
T const * find() const
Definition STObject.h:758
TypedField< T > const * f_
Definition STObject.h:522
ValueProxy(ValueProxy const &)=default
ValueProxy & operator=(ValueProxy const &)=delete
ValueProxy & operator=(U &&u)
ValueProxy & operator-=(U const &u)
ValueProxy & operator+=(U const &u)
friend bool operator==(U const &lhs, STObject::ValueProxy< T > const &rhs)
Definition STObject.h:591
T::value_type value_type
Definition STObject.h:559
void setFieldU8(SField const &field, unsigned char)
Definition STObject.cpp:731
SField const & getFieldSType(int index) const
Definition STObject.cpp:431
uint192 getFieldH192(SField const &field) const
Definition STObject.cpp:625
bool isFree() const
Definition STObject.h:988
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1078
STBase const * peekAtPIndex(int offset) const
Definition STObject.h:1037
void setFieldH192(SField const &field, uint192 const &)
Definition STObject.cpp:761
STCurrency const & getFieldCurrency(SField const &field) const
Definition STObject.cpp:695
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:649
void addWithoutSigningFields(Serializer &s) const
Definition STObject.h:994
void setFieldIssue(SField const &field, STIssue const &)
Definition STObject.cpp:815
uint128 getFieldH128(SField const &field) const
Definition STObject.cpp:613
iterator begin() const
Definition STObject.h:964
bool operator==(STObject const &o) const
Definition STObject.cpp:858
bool isEquivalent(STBase const &t) const override
Definition STObject.cpp:351
bool empty() const
Definition STObject.h:976
void setFieldNumber(SField const &field, STNumber const &)
Definition STObject.cpp:821
void setFieldV256(SField const &field, STVector256 const &v)
Definition STObject.cpp:779
void setFieldU64(SField const &field, std::uint64_t)
Definition STObject.cpp:749
unsigned char getFieldU8(SField const &field) const
Definition STObject.cpp:589
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:601
STBase const & peekAtIndex(int offset) const
Definition STObject.h:1025
V const & getFieldByConstRef(SField const &field, V const &empty) const
STNumber const & getFieldNumber(SField const &field) const
Definition STObject.cpp:702
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:791
void reserve(std::size_t n)
Definition STObject.h:982
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1050
iterator end() const
Definition STObject.h:970
void applyTemplate(SOTemplate const &type)
Definition STObject.cpp:158
int getFieldIndex(SField const &field) const
Definition STObject.cpp:393
uint256 getHash(HashPrefix prefix) const
Definition STObject.cpp:375
void setFieldI32(SField const &field, std::int32_t)
Definition STObject.cpp:773
std::string getFullText() const override
Definition STObject.cpp:295
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:743
list_type v_
Definition STObject.h:71
STArray & peekFieldArray(SField const &field)
Definition STObject.cpp:481
std::string getText() const override
Definition STObject.cpp:332
~STObject() override=default
std::size_t emplaceBack(Args &&... args)
Definition STObject.h:1012
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:688
void setFieldArray(SField const &field, STArray const &v)
Definition STObject.cpp:833
V getFieldByValue(SField const &field) const
Definition STObject.h:1175
STObject & peekFieldObject(SField const &field)
Definition STObject.cpp:475
SOEStyle getStyle(SField const &field) const
Definition STObject.cpp:583
STBase & getField(SField const &field)
Definition STObject.cpp:420
std::vector< detail::STVar > list_type
Definition STObject.h:69
void setFieldAmount(SField const &field, STAmount const &)
Definition STObject.cpp:803
json::Value getJson(JsonOptions=JsonOptions::Values::None) const override
Definition STObject.cpp:845
void add(Serializer &s) const override
Definition STObject.cpp:123
Serializer getSerializer() const
Definition STObject.h:1003
bool isFlag(std::uint32_t) const
Definition STObject.cpp:511
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
STObject & operator=(STObject const &)=default
STObject(STObject const &)=default
int getCount() const
Definition STObject.h:1019
SerializedTypeID getSType() const override
Definition STObject.cpp:111
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:737
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:631
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:79
SOTemplate const * type_
Definition STObject.h:72
std::int32_t getFieldI32(SField const &field) const
Definition STObject.cpp:637
STBase const & peekAtField(SField const &field) const
Definition STObject.cpp:409
void set(SOTemplate const &)
Definition STObject.cpp:138
STObject(SOTemplate const &type, SField const &name, F &&f)
Definition STObject.h:81
uint256 getSigningHash(HashPrefix prefix) const
Definition STObject.cpp:384
bool clearFlag(std::uint32_t)
Definition STObject.cpp:499
void setFieldCurrency(SField const &field, STCurrency const &)
Definition STObject.cpp:809
std::uint64_t getFieldU64(SField const &field) const
Definition STObject.cpp:607
void setFieldPathSet(SField const &field, STPathSet const &)
Definition STObject.cpp:827
STBase * move(std::size_t n, void *buf) override
Definition STObject.cpp:105
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition STObject.cpp:926
STBase * getPField(SField const &field, bool createOkay=false)
Definition STObject.cpp:448
STBase * makeFieldPresent(SField const &field)
Definition STObject.cpp:528
STBase const * peekAtPField(SField const &field) const
Definition STObject.cpp:437
void applyTemplateFromSField(SField const &)
Definition STObject.cpp:207
bool setFlag(std::uint32_t)
Definition STObject.cpp:487
void setFieldObject(SField const &field, STObject const &v)
Definition STObject.cpp:839
void setFieldH128(SField const &field, uint128 const &)
Definition STObject.cpp:755
STObject getFieldObject(SField const &field) const
Definition STObject.cpp:678
T & peekField(SField const &field)
Definition STObject.h:1272
void setFieldUsingSetValue(SField const &field, V value)
Definition STObject.h:1228
void setAccountID(SField const &field, AccountID const &)
Definition STObject.cpp:785
void setFieldUsingAssignment(SField const &field, T const &value)
Definition STObject.h:1251
bool delField(SField const &field)
Definition STObject.cpp:565
STBase & getIndex(int offset)
Definition STObject.h:1031
uint160 getFieldH160(SField const &field) const
Definition STObject.cpp:619
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:643
STBase * getPIndex(int offset)
Definition STObject.h:1043
STVector256 const & getFieldV256(SField const &field) const
Definition STObject.cpp:671
STPathSet const & getFieldPathSet(SField const &field) const
Definition STObject.cpp:664
bool isDefault() const override
Definition STObject.cpp:117
void setFieldH160(SField const &field, BaseUInt< 160, Tag > const &v)
Definition STObject.h:1152
void makeFieldAbsent(SField const &field)
Definition STObject.cpp:550
bool hasMatchingEntry(STBase const &) const
Definition STObject.cpp:284
void setFieldH256(SField const &field, uint256 const &)
Definition STObject.cpp:767
boost::transform_iterator< Transform, STObject::list_type::const_iterator > iterator
Definition STObject.h:75
std::uint16_t getFieldU16(SField const &field) const
Definition STObject.cpp:595
STAmount const & getFieldAmount(SField const &field) const
Definition STObject.cpp:657
std::uint32_t getFlags() const
Definition STObject.cpp:517
STBase * copy(std::size_t n, void *buf) const override
Definition STObject.cpp:99
An immutable linear range of bytes.
Definition Slice.h:28
STBase & get()
Definition STVar.h:67
T forward(T... args)
T is_arithmetic_v
T is_assignable_v
T is_class_v
T is_lvalue_reference_v
T is_same_v
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
BaseUInt< 192 > uint192
Definition base_uint.h:581
void throwFieldNotFound(SField const &field)
Definition STObject.h:43
SOEStyle
Kind of element in each entry of an SOTemplate.
Definition SOTemplate.h:20
@ SoeDefault
Definition SOTemplate.h:24
@ SoeInvalid
Definition SOTemplate.h:21
@ SoeOptional
Definition SOTemplate.h:23
@ SoeRequired
Definition SOTemplate.h:22
BaseUInt< 128 > uint128
Definition base_uint.h:578
Number operator*(Number const &x, Number const &y)
Definition Number.h:797
BaseUInt< 160 > uint160
Definition base_uint.h:579
SerializedTypeID
Definition SField.h:94
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
HashPrefix
Prefix for hashing functions.
Definition HashPrefix.h:35
std::vector< unsigned char > Blob
Storage for linear binary data.
Definition Blob.h:11
BaseUInt< 256 > uint256
Definition base_uint.h:580
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T runtime_error(T... args)
Note, should be treated as flags that can be | and &.
Definition STBase.h:22
Indicate std::optional field semantics.
Definition SField.h:320
TypedField< T > const * f
Definition SField.h:321
STBase const & operator()(detail::STVar const &e) const
Definition STObject.h:951
detail::STVar argument_type
Definition STObject.h:62
A field with a type known at compile time.
Definition SField.h:308