rippled
Loading...
Searching...
No Matches
STObject.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
21#define RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
22
23#include <xrpl/basics/CountedObject.h>
24#include <xrpl/basics/Slice.h>
25#include <xrpl/basics/chrono.h>
26#include <xrpl/basics/contract.h>
27#include <xrpl/beast/utility/instrumentation.h>
28#include <xrpl/protocol/HashPrefix.h>
29#include <xrpl/protocol/SOTemplate.h>
30#include <xrpl/protocol/STAmount.h>
31#include <xrpl/protocol/STBase.h>
32#include <xrpl/protocol/STCurrency.h>
33#include <xrpl/protocol/STIssue.h>
34#include <xrpl/protocol/STPathSet.h>
35#include <xrpl/protocol/STVector256.h>
36#include <xrpl/protocol/Units.h>
37#include <xrpl/protocol/detail/STVar.h>
38
39#include <boost/iterator/transform_iterator.hpp>
40
41#include <optional>
42#include <stdexcept>
43#include <type_traits>
44#include <utility>
45
46namespace ripple {
47
48class STArray;
49
50inline void
52{
53 Throw<std::runtime_error>("Field not found: " + field.getName());
54}
55
56class STObject : public STBase, public CountedObject<STObject>
57{
58 // Proxy value for a STBase derived class
59 template <class T>
60 class Proxy;
61 template <class T>
62 class ValueProxy;
63 template <class T>
64 class OptionalProxy;
65
66 struct Transform
67 {
68 explicit Transform() = default;
69
72
73 STBase const&
74 operator()(detail::STVar const& e) const;
75 };
76
78
81
82public:
83 using iterator = boost::
84 transform_iterator<Transform, STObject::list_type::const_iterator>;
85
86 virtual ~STObject() = default;
87 STObject(STObject const&) = default;
88
89 template <typename F>
90 STObject(SOTemplate const& type, SField const& name, F&& f)
91 : STObject(type, name)
92 {
93 f(*this);
94 }
95
97 operator=(STObject const&) = default;
100 operator=(STObject&& other);
101
102 STObject(SOTemplate const& type, SField const& name);
103 STObject(SOTemplate const& type, SerialIter& sit, SField const& name);
104 STObject(SerialIter& sit, SField const& name, int depth = 0);
105 STObject(SerialIter&& sit, SField const& name);
106 explicit STObject(SField const& name);
107
108 static STObject
109 makeInnerObject(SField const& name);
110
112 begin() const;
113
115 end() const;
116
117 bool
118 empty() const;
119
120 void
122
123 void
124 applyTemplate(SOTemplate const& type);
125
126 void
128
129 bool
130 isFree() const;
131
132 void
133 set(SOTemplate const&);
134
135 bool
136 set(SerialIter& u, int depth = 0);
137
139 getSType() const override;
140
141 bool
142 isEquivalent(STBase const& t) const override;
143
144 bool
145 isDefault() const override;
146
147 void
148 add(Serializer& s) const override;
149
151 getFullText() const override;
152
154 getText() const override;
155
156 // TODO(tom): options should be an enum.
158
159 void
161
163 getSerializer() const;
164
165 template <class... Args>
167 emplace_back(Args&&... args);
168
169 int
170 getCount() const;
171
174 bool isFlag(std::uint32_t) const;
175
177 getFlags() const;
178
179 uint256
180 getHash(HashPrefix prefix) const;
181
182 uint256
183 getSigningHash(HashPrefix prefix) const;
184
185 STBase const&
186 peekAtIndex(int offset) const;
187
188 STBase&
189 getIndex(int offset);
190
191 STBase const*
192 peekAtPIndex(int offset) const;
193
194 STBase*
195 getPIndex(int offset);
196
197 int
198 getFieldIndex(SField const& field) const;
199
200 SField const&
201 getFieldSType(int index) const;
202
203 STBase const&
204 peekAtField(SField const& field) const;
205
206 STBase&
207 getField(SField const& field);
208
209 STBase const*
210 peekAtPField(SField const& field) const;
211
212 STBase*
213 getPField(SField const& field, bool createOkay = false);
214
215 // these throw if the field type doesn't match, or return default values
216 // if the field is optional but not present
217 unsigned char
218 getFieldU8(SField const& field) const;
220 getFieldU16(SField const& field) const;
222 getFieldU32(SField const& field) const;
224 getFieldU64(SField const& field) const;
225 uint128
226 getFieldH128(SField const& field) const;
227
228 uint160
229 getFieldH160(SField const& field) const;
230 uint192
231 getFieldH192(SField const& field) const;
232 uint256
233 getFieldH256(SField const& field) const;
235 getFieldI32(SField const& field) const;
237 getAccountID(SField const& field) const;
238
239 Blob
240 getFieldVL(SField const& field) const;
241 STAmount const&
242 getFieldAmount(SField const& field) const;
243 STPathSet const&
244 getFieldPathSet(SField const& field) const;
245 STVector256 const&
246 getFieldV256(SField const& field) const;
247 STArray const&
248 getFieldArray(SField const& field) const;
249 STCurrency const&
250 getFieldCurrency(SField const& field) const;
251 STNumber const&
252 getFieldNumber(SField const& field) const;
253
261 template <class T>
262 typename T::value_type
263 operator[](TypedField<T> const& f) const;
264
273 template <class T>
275 operator[](OptionaledField<T> const& of) const;
276
284 template <class T>
287
297 template <class T>
300
308 template <class T>
309 typename T::value_type
310 at(TypedField<T> const& f) const;
311
320 template <class T>
322 at(OptionaledField<T> const& of) const;
323
331 template <class T>
333 at(TypedField<T> const& f);
334
344 template <class T>
347
351 void
353
354 void
355 set(STBase&& v);
356
357 void
358 setFieldU8(SField const& field, unsigned char);
359 void
360 setFieldU16(SField const& field, std::uint16_t);
361 void
362 setFieldU32(SField const& field, std::uint32_t);
363 void
364 setFieldU64(SField const& field, std::uint64_t);
365 void
366 setFieldH128(SField const& field, uint128 const&);
367 void
368 setFieldH256(SField const& field, uint256 const&);
369 void
370 setFieldI32(SField const& field, std::int32_t);
371 void
372 setFieldVL(SField const& field, Blob const&);
373 void
374 setFieldVL(SField const& field, Slice const&);
375
376 void
377 setAccountID(SField const& field, AccountID const&);
378
379 void
380 setFieldAmount(SField const& field, STAmount const&);
381 void
382 setFieldIssue(SField const& field, STIssue const&);
383 void
384 setFieldCurrency(SField const& field, STCurrency const&);
385 void
386 setFieldNumber(SField const& field, STNumber const&);
387 void
388 setFieldPathSet(SField const& field, STPathSet const&);
389 void
390 setFieldV256(SField const& field, STVector256 const& v);
391 void
392 setFieldArray(SField const& field, STArray const& v);
393
394 template <class Tag>
395 void
396 setFieldH160(SField const& field, base_uint<160, Tag> const& v);
397
398 STObject&
399 peekFieldObject(SField const& field);
400 STArray&
401 peekFieldArray(SField const& field);
402
403 bool
404 isFieldPresent(SField const& field) const;
405 STBase*
406 makeFieldPresent(SField const& field);
407 void
408 makeFieldAbsent(SField const& field);
409 bool
410 delField(SField const& field);
411 void
412 delField(int index);
413
414 bool
415 hasMatchingEntry(STBase const&);
416
417 bool
418 operator==(STObject const& o) const;
419 bool
420 operator!=(STObject const& o) const;
421
422 class FieldErr;
423
424private:
425 enum WhichFields : bool {
426 // These values are carefully chosen to do the right thing if passed
427 // to SField::shouldInclude (bool)
429 withAllFields = true
430 };
431
432 void
433 add(Serializer& s, WhichFields whichFields) const;
434
435 // Sort the entries in an STObject into the order that they will be
436 // serialized. Note: they are not sorted into pointer value order, they
437 // are sorted by SField::fieldCode.
439 getSortedFields(STObject const& objToSort, WhichFields whichFields);
440
441 // Implementation for getting (most) fields that return by value.
442 //
443 // The remove_cv and remove_reference are necessitated by the STBitString
444 // types. Their value() returns by const ref. We return those types
445 // by value.
446 template <
447 typename T,
448 typename V = typename std::remove_cv<typename std::remove_reference<
449 decltype(std::declval<T>().value())>::type>::type>
450 V
451 getFieldByValue(SField const& field) const;
452
453 // Implementations for getting (most) fields that return by const reference.
454 //
455 // If an absent optional field is deserialized we don't have anything
456 // obvious to return. So we insist on having the call provide an
457 // 'empty' value we return in that circumstance.
458 template <typename T, typename V>
459 V const&
460 getFieldByConstRef(SField const& field, V const& empty) const;
461
462 // Implementation for setting most fields with a setValue() method.
463 template <typename T, typename V>
464 void
465 setFieldUsingSetValue(SField const& field, V value);
466
467 // Implementation for setting fields using assignment
468 template <typename T>
469 void
470 setFieldUsingAssignment(SField const& field, T const& value);
471
472 // Implementation for peeking STObjects and STArrays
473 template <typename T>
474 T&
475 peekField(SField const& field);
476
477 STBase*
478 copy(std::size_t n, void* buf) const override;
479 STBase*
480 move(std::size_t n, void* buf) override;
481
482 friend class detail::STVar;
483};
484
485//------------------------------------------------------------------------------
486
487template <class T>
489{
490public:
491 using value_type = typename T::value_type;
492
494 value() const;
495
497 operator*() const;
498
499 T const*
500 operator->() const;
501
502protected:
506
507 Proxy(Proxy const&) = default;
508
509 Proxy(STObject* st, TypedField<T> const* f);
510
511 T const*
512 find() const;
513
514 template <class U>
515 void
516 assign(U&& u);
517};
518
519// Constraint += and -= ValueProxy operators
520// to value types that support arithmetic operations
521template <typename U>
523
524template <class T>
526{
527private:
528 using value_type = typename T::value_type;
529
530public:
531 ValueProxy(ValueProxy const&) = default;
533 operator=(ValueProxy const&) = delete;
534
535 template <class U>
537 operator=(U&& u);
538
539 // Convenience operators for value types supporting
540 // arithmetic operations
541 template <IsArithmetic U>
543 operator+=(U const& u);
544
545 template <IsArithmetic U>
547 operator-=(U const& u);
548
549 operator value_type() const;
550
551 template <typename U>
552 friend bool
553 operator==(U const& lhs, STObject::ValueProxy<T> const& rhs)
554 {
555 return rhs.value() == lhs;
556 }
557
558private:
559 friend class STObject;
560
561 ValueProxy(STObject* st, TypedField<T> const* f);
562};
563
564template <class T>
566{
567private:
568 using value_type = typename T::value_type;
569
571
572public:
573 OptionalProxy(OptionalProxy const&) = default;
575 operator=(OptionalProxy const&) = delete;
576
582 explicit
583 operator bool() const noexcept;
584
585 operator optional_type() const;
586
589 operator~() const;
590
591 friend bool
592 operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
593 {
594 return !lhs.engaged();
595 }
596
597 friend bool
599 {
600 return rhs == std::nullopt;
601 }
602
603 friend bool
604 operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
605 {
606 if (!lhs.engaged())
607 return !rhs;
608 if (!rhs)
609 return false;
610 return *lhs == *rhs;
611 }
612
613 friend bool
614 operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
615 {
616 return rhs == lhs;
617 }
618
619 friend bool
620 operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
621 {
622 if (lhs.engaged() != rhs.engaged())
623 return false;
624 return !lhs.engaged() || *lhs == *rhs;
625 }
626
627 friend bool
629 {
630 return !(lhs == std::nullopt);
631 }
632
633 friend bool
635 {
636 return !(rhs == std::nullopt);
637 }
638
639 friend bool
640 operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
641 {
642 return !(lhs == rhs);
643 }
644
645 friend bool
646 operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
647 {
648 return !(lhs == rhs);
649 }
650
651 friend bool
652 operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
653 {
654 return !(lhs == rhs);
655 }
656
657 // Emulate std::optional::value_or
659 value_or(value_type val) const;
660
666 operator=(optional_type const& v);
667
668 template <class U>
670 operator=(U&& u);
671
672private:
673 friend class STObject;
674
675 OptionalProxy(STObject* st, TypedField<T> const* f);
676
677 bool
678 engaged() const noexcept;
679
680 void
681 disengage();
682
684 optional_value() const;
685};
686
687class STObject::FieldErr : public std::runtime_error
688{
690};
691
692template <class T>
694{
695 if (st_->mType)
696 {
697 // STObject has associated template
698 if (!st_->peekAtPField(*f_))
699 Throw<STObject::FieldErr>(
700 "Template field error '" + this->f_->getName() + "'");
701 style_ = st_->mType->style(*f_);
702 }
703 else
704 {
706 }
707}
708
709template <class T>
710auto
712{
713 auto const t = find();
714 if (t)
715 return t->value();
716 if (style_ == soeINVALID)
717 {
718 Throw<STObject::FieldErr>("Value requested from invalid STObject.");
719 }
720 if (style_ != soeDEFAULT)
721 {
722 Throw<STObject::FieldErr>(
723 "Missing field '" + this->f_->getName() + "'");
724 }
725 return value_type{};
726}
727
728template <class T>
729auto
731{
732 return this->value();
733}
734
735template <class T>
736T const*
738{
739 return this->find();
740}
741
742template <class T>
743inline T const*
745{
746 return dynamic_cast<T const*>(st_->peekAtPField(*f_));
747}
748
749template <class T>
750template <class U>
751void
753{
754 if (style_ == soeDEFAULT && u == value_type{})
755 {
756 st_->makeFieldAbsent(*f_);
757 return;
758 }
759 T* t;
760 if (style_ == soeINVALID)
761 t = dynamic_cast<T*>(st_->getPField(*f_, true));
762 else
763 t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
764 XRPL_ASSERT(t, "ripple::STObject::Proxy::assign : type cast succeeded");
765 *t = std::forward<U>(u);
766}
767
768//------------------------------------------------------------------------------
769
770template <class T>
771template <class U>
774{
775 this->assign(std::forward<U>(u));
776 return *this;
777}
778
779template <typename T>
780template <IsArithmetic U>
783{
784 this->assign(this->value() + u);
785 return *this;
786}
787
788template <class T>
789template <IsArithmetic U>
792{
793 this->assign(this->value() - u);
794 return *this;
795}
796
797template <class T>
799{
800 return this->value();
801}
802
803template <class T>
805 : Proxy<T>(st, f)
806{
807}
808
809//------------------------------------------------------------------------------
810
811template <class T>
813{
814 return engaged();
815}
816
817template <class T>
819 T>::optional_type() const
820{
821 return optional_value();
822}
823
824template <class T>
827{
828 return optional_value();
829}
830
831template <class T>
832auto
834{
835 disengage();
836 return *this;
837}
838
839template <class T>
840auto
842{
843 if (v)
844 this->assign(std::move(*v));
845 else
846 disengage();
847 return *this;
848}
849
850template <class T>
851auto
853{
854 if (v)
855 this->assign(*v);
856 else
857 disengage();
858 return *this;
859}
860
861template <class T>
862template <class U>
865{
866 this->assign(std::forward<U>(u));
867 return *this;
868}
869
870template <class T>
875
876template <class T>
877bool
879{
880 return this->style_ == soeDEFAULT || this->find() != nullptr;
881}
882
883template <class T>
884void
886{
887 if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
888 Throw<STObject::FieldErr>(
889 "Template field error '" + this->f_->getName() + "'");
890 if (this->style_ == soeINVALID)
891 this->st_->delField(*this->f_);
892 else
893 this->st_->makeFieldAbsent(*this->f_);
894}
895
896template <class T>
897auto
899{
900 if (!engaged())
901 return std::nullopt;
902 return this->value();
903}
904
905template <class T>
908{
909 return engaged() ? this->value() : val;
910}
911
912//------------------------------------------------------------------------------
913
914inline STBase const&
916{
917 return e.get();
918}
919
920//------------------------------------------------------------------------------
921
922inline STObject::STObject(SerialIter&& sit, SField const& name)
923 : STObject(sit, name)
924{
925}
926
929{
930 return iterator(v_.begin());
931}
932
935{
936 return iterator(v_.end());
937}
938
939inline bool
941{
942 return v_.empty();
943}
944
945inline void
950
951inline bool
953{
954 return mType == nullptr;
955}
956
957inline void
962
963// VFALCO NOTE does this return an expensive copy of an object with a
964// dynamic buffer?
965// VFALCO TODO Remove this function and fix the few callers.
966inline Serializer
968{
969 Serializer s;
970 add(s, withAllFields);
971 return s;
972}
973
974template <class... Args>
975inline std::size_t
977{
979 return v_.size() - 1;
980}
981
982inline int
984{
985 return v_.size();
986}
987
988inline STBase const&
989STObject::peekAtIndex(int offset) const
990{
991 return v_[offset].get();
992}
993
994inline STBase&
996{
997 return v_[offset].get();
998}
999
1000inline STBase const*
1001STObject::peekAtPIndex(int offset) const
1002{
1003 return &v_[offset].get();
1004}
1005
1006inline STBase*
1008{
1009 return &v_[offset].get();
1010}
1011
1012template <class T>
1013typename T::value_type
1015{
1016 return at(f);
1017}
1018
1019template <class T>
1022{
1023 return at(of);
1024}
1025
1026template <class T>
1027inline auto
1029{
1030 return at(f);
1031}
1032
1033template <class T>
1034inline auto
1036{
1037 return at(of);
1038}
1039
1040template <class T>
1041typename T::value_type
1043{
1044 auto const b = peekAtPField(f);
1045 if (!b)
1046 // This is a free object (no constraints)
1047 // with no template
1048 Throw<STObject::FieldErr>("Missing field: " + f.getName());
1049
1050 if (auto const u = dynamic_cast<T const*>(b))
1051 return u->value();
1052
1053 XRPL_ASSERT(
1054 mType,
1055 "ripple::STObject::at(TypedField auto) : field template non-null");
1056 XRPL_ASSERT(
1057 b->getSType() == STI_NOTPRESENT,
1058 "ripple::STObject::at(TypedField auto) : type not present");
1059
1060 if (mType->style(f) == soeOPTIONAL)
1061 Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
1062
1063 XRPL_ASSERT(
1064 mType->style(f) == soeDEFAULT,
1065 "ripple::STObject::at(TypedField auto) : template style is default");
1066
1067 // Used to help handle the case where value_type is a const reference,
1068 // otherwise we would return the address of a temporary.
1069 static std::decay_t<typename T::value_type> const dv{};
1070 return dv;
1071}
1072
1073template <class T>
1076{
1077 auto const b = peekAtPField(*of.f);
1078 if (!b)
1079 return std::nullopt;
1080 auto const u = dynamic_cast<T const*>(b);
1081 if (!u)
1082 {
1083 XRPL_ASSERT(
1084 mType,
1085 "ripple::STObject::at(OptionaledField auto) : field template "
1086 "non-null");
1087 XRPL_ASSERT(
1088 b->getSType() == STI_NOTPRESENT,
1089 "ripple::STObject::at(OptionaledField auto) : type not present");
1090 if (mType->style(*of.f) == soeOPTIONAL)
1091 return std::nullopt;
1092 XRPL_ASSERT(
1093 mType->style(*of.f) == soeDEFAULT,
1094 "ripple::STObject::at(OptionaledField auto) : template style is "
1095 "default");
1096 return typename T::value_type{};
1097 }
1098 return u->value();
1099}
1100
1101template <class T>
1102inline auto
1104{
1105 return ValueProxy<T>(this, &f);
1106}
1107
1108template <class T>
1109inline auto
1111{
1112 return OptionalProxy<T>(this, of.f);
1113}
1114
1115template <class Tag>
1116void
1118{
1119 STBase* rf = getPField(field, true);
1120
1121 if (!rf)
1122 throwFieldNotFound(field);
1123
1124 if (rf->getSType() == STI_NOTPRESENT)
1125 rf = makeFieldPresent(field);
1126
1127 using Bits = STBitString<160>;
1128 if (auto cf = dynamic_cast<Bits*>(rf))
1129 cf->setValue(v);
1130 else
1131 Throw<std::runtime_error>("Wrong field type");
1132}
1133
1134inline bool
1136{
1137 return !(*this == o);
1138}
1139
1140template <typename T, typename V>
1141V
1143{
1144 STBase const* rf = peekAtPField(field);
1145
1146 if (!rf)
1147 throwFieldNotFound(field);
1148
1149 SerializedTypeID id = rf->getSType();
1150
1151 if (id == STI_NOTPRESENT)
1152 return V(); // optional field not present
1153
1154 T const* cf = dynamic_cast<T const*>(rf);
1155
1156 if (!cf)
1157 Throw<std::runtime_error>("Wrong field type");
1158
1159 return cf->value();
1160}
1161
1162// Implementations for getting (most) fields that return by const reference.
1163//
1164// If an absent optional field is deserialized we don't have anything
1165// obvious to return. So we insist on having the call provide an
1166// 'empty' value we return in that circumstance.
1167template <typename T, typename V>
1168V const&
1169STObject::getFieldByConstRef(SField const& field, V const& empty) const
1170{
1171 STBase const* rf = peekAtPField(field);
1172
1173 if (!rf)
1174 throwFieldNotFound(field);
1175
1176 SerializedTypeID id = rf->getSType();
1177
1178 if (id == STI_NOTPRESENT)
1179 return empty; // optional field not present
1180
1181 T const* cf = dynamic_cast<T const*>(rf);
1182
1183 if (!cf)
1184 Throw<std::runtime_error>("Wrong field type");
1185
1186 return *cf;
1187}
1188
1189// Implementation for setting most fields with a setValue() method.
1190template <typename T, typename V>
1191void
1193{
1194 static_assert(!std::is_lvalue_reference<V>::value, "");
1195
1196 STBase* rf = getPField(field, true);
1197
1198 if (!rf)
1199 throwFieldNotFound(field);
1200
1201 if (rf->getSType() == STI_NOTPRESENT)
1202 rf = makeFieldPresent(field);
1203
1204 T* cf = dynamic_cast<T*>(rf);
1205
1206 if (!cf)
1207 Throw<std::runtime_error>("Wrong field type");
1208
1209 cf->setValue(std::move(value));
1210}
1211
1212// Implementation for setting fields using assignment
1213template <typename T>
1214void
1215STObject::setFieldUsingAssignment(SField const& field, T const& value)
1216{
1217 STBase* rf = getPField(field, true);
1218
1219 if (!rf)
1220 throwFieldNotFound(field);
1221
1222 if (rf->getSType() == STI_NOTPRESENT)
1223 rf = makeFieldPresent(field);
1224
1225 T* cf = dynamic_cast<T*>(rf);
1226
1227 if (!cf)
1228 Throw<std::runtime_error>("Wrong field type");
1229
1230 (*cf) = value;
1231}
1232
1233// Implementation for peeking STObjects and STArrays
1234template <typename T>
1235T&
1237{
1238 STBase* rf = getPField(field, true);
1239
1240 if (!rf)
1241 throwFieldNotFound(field);
1242
1243 if (rf->getSType() == STI_NOTPRESENT)
1244 rf = makeFieldPresent(field);
1245
1246 T* cf = dynamic_cast<T*>(rf);
1247
1248 if (!cf)
1249 Throw<std::runtime_error>("Wrong field type");
1250
1251 return *cf;
1252}
1253
1254} // namespace ripple
1255
1256#endif
T begin(T... args)
Represents a JSON value.
Definition json_value.h:149
Tracks the number of instances of an object.
Identifies fields.
Definition SField.h:146
std::string const & getName() const
Definition SField.h:211
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:113
SOEStyle style(SField const &sf) const
Definition SOTemplate.h:166
A type which can be exported to a well known binary format.
Definition STBase.h:135
virtual SerializedTypeID getSType() const
Definition STBase.cpp:75
void setValue(base_uint< Bits, Tag > const &v)
A serializable number.
Definition STNumber.h:43
friend bool operator!=(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition STObject.h:640
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition STObject.h:604
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:614
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:620
optional_type operator~() const
Explicit conversion to std::optional.
Definition STObject.h:826
OptionalProxy(OptionalProxy const &)=default
value_type value_or(value_type val) const
Definition STObject.h:907
friend bool operator!=(OptionalProxy const &lhs, std::nullopt_t) noexcept
Definition STObject.h:628
friend bool operator!=(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition STObject.h:634
std::enable_if_t< std::is_assignable_v< T, U >, OptionalProxy & > operator=(U &&u)
typename T::value_type value_type
Definition STObject.h:568
OptionalProxy & operator=(OptionalProxy const &)=delete
optional_type optional_value() const
Definition STObject.h:898
std::optional< typename std::decay< value_type >::type > optional_type
Definition STObject.h:570
friend bool operator!=(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:646
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition STObject.h:598
bool engaged() const noexcept
Definition STObject.h:878
friend bool operator!=(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition STObject.h:652
typename T::value_type value_type
Definition STObject.h:491
T const * find() const
Definition STObject.h:744
Proxy(Proxy const &)=default
TypedField< T > const * f_
Definition STObject.h:505
value_type value() const
Definition STObject.h:711
value_type operator*() const
Definition STObject.h:730
T const * operator->() const
Definition STObject.h:737
ValueProxy & operator-=(U const &u)
typename T::value_type value_type
Definition STObject.h:528
ValueProxy & operator+=(U const &u)
ValueProxy & operator=(ValueProxy const &)=delete
std::enable_if_t< std::is_assignable_v< T, U >, ValueProxy & > operator=(U &&u)
ValueProxy(ValueProxy const &)=default
friend bool operator==(U const &lhs, STObject::ValueProxy< T > const &rhs)
Definition STObject.h:553
STPathSet const & getFieldPathSet(SField const &field) const
Definition STObject.cpp:678
unsigned char getFieldU8(SField const &field) const
Definition STObject.cpp:603
uint192 getFieldH192(SField const &field) const
Definition STObject.cpp:639
STBase * getPField(SField const &field, bool createOkay=false)
Definition STObject.cpp:468
void setFieldIssue(SField const &field, STIssue const &)
Definition STObject.cpp:813
bool operator!=(STObject const &o) const
Definition STObject.h:1135
SOTemplate const * mType
Definition STObject.h:80
void applyTemplate(SOTemplate const &type)
Definition STObject.cpp:172
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:663
boost::transform_iterator< Transform, STObject::list_type::const_iterator > iterator
Definition STObject.h:84
bool hasMatchingEntry(STBase const &)
Definition STObject.cpp:299
bool clearFlag(std::uint32_t)
Definition STObject.cpp:519
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:657
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition STObject.cpp:919
T & peekField(SField const &field)
Definition STObject.h:1236
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:692
uint160 getFieldH160(SField const &field) const
Definition STObject.cpp:633
void setFieldCurrency(SField const &field, STCurrency const &)
Definition STObject.cpp:807
STBase const * peekAtPField(SField const &field) const
Definition STObject.cpp:457
STBase const * peekAtPIndex(int offset) const
Definition STObject.h:1001
void setFieldArray(SField const &field, STArray const &v)
Definition STObject.cpp:831
void setFieldPathSet(SField const &field, STPathSet const &)
Definition STObject.cpp:825
iterator end() const
Definition STObject.h:934
SField const & getFieldSType(int index) const
Definition STObject.cpp:451
STObject(STObject const &)=default
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1042
bool isFlag(std::uint32_t) const
Definition STObject.cpp:531
std::uint16_t getFieldU16(SField const &field) const
Definition STObject.cpp:609
virtual ~STObject()=default
void setFieldH256(SField const &field, uint256 const &)
Definition STObject.cpp:765
void setFieldNumber(SField const &field, STNumber const &)
Definition STObject.cpp:819
bool setFlag(std::uint32_t)
Definition STObject.cpp:507
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:615
void setFieldI32(SField const &field, std::int32_t)
Definition STObject.cpp:771
STBase * copy(std::size_t n, void *buf) const override
Definition STObject.cpp:117
void makeFieldAbsent(SField const &field)
Definition STObject.cpp:570
STObject & peekFieldObject(SField const &field)
Definition STObject.cpp:495
int getCount() const
Definition STObject.h:983
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:741
Serializer getSerializer() const
Definition STObject.h:967
std::uint64_t getFieldU64(SField const &field) const
Definition STObject.cpp:621
STBase * makeFieldPresent(SField const &field)
Definition STObject.cpp:548
void setFieldU8(SField const &field, unsigned char)
Definition STObject.cpp:735
void set(SOTemplate const &)
Definition STObject.cpp:156
void add(Serializer &s) const override
Definition STObject.cpp:141
STObject(SOTemplate const &type, SField const &name, F &&f)
Definition STObject.h:90
void setFieldAmount(SField const &field, STAmount const &)
Definition STObject.cpp:801
bool delField(SField const &field)
Definition STObject.cpp:585
STBase const & peekAtIndex(int offset) const
Definition STObject.h:989
STBase & getField(SField const &field)
Definition STObject.cpp:440
V const & getFieldByConstRef(SField const &field, V const &empty) const
STAmount const & getFieldAmount(SField const &field) const
Definition STObject.cpp:671
std::int32_t getFieldI32(SField const &field) const
Definition STObject.cpp:651
uint256 getSigningHash(HashPrefix prefix) const
Definition STObject.cpp:404
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1014
uint256 getHash(HashPrefix prefix) const
Definition STObject.cpp:395
int getFieldIndex(SField const &field) const
Definition STObject.cpp:413
STBase & getIndex(int offset)
Definition STObject.h:995
ValueProxy< T > operator[](TypedField< T > const &f)
Get a modifiable field value.
bool isFree() const
Definition STObject.h:952
void setFieldUsingAssignment(SField const &field, T const &value)
Definition STObject.h:1215
list_type v_
Definition STObject.h:79
bool empty() const
Definition STObject.h:940
SerializedTypeID getSType() const override
Definition STObject.cpp:129
std::string getFullText() const override
Definition STObject.cpp:310
std::string getText() const override
Definition STObject.cpp:341
iterator begin() const
Definition STObject.h:928
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:484
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:95
STCurrency const & getFieldCurrency(SField const &field) const
Definition STObject.cpp:699
bool operator==(STObject const &o) const
Definition STObject.cpp:850
void setAccountID(SField const &field, AccountID const &)
Definition STObject.cpp:783
uint128 getFieldH128(SField const &field) const
Definition STObject.cpp:627
void applyTemplateFromSField(SField const &)
Definition STObject.cpp:226
OptionalProxy< T > at(OptionaledField< T > const &of)
Return a modifiable field value as std::optional.
ValueProxy< T > at(TypedField< T > const &f)
Get a modifiable field value.
void setFieldV256(SField const &field, STVector256 const &v)
Definition STObject.cpp:777
void setFieldUsingSetValue(SField const &field, V value)
Definition STObject.h:1192
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STObject.cpp:837
void setFieldH128(SField const &field, uint128 const &)
Definition STObject.cpp:759
void setFieldU64(SField const &field, std::uint64_t)
Definition STObject.cpp:753
bool isEquivalent(STBase const &t) const override
Definition STObject.cpp:360
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:747
STBase const & peekAtField(SField const &field) const
Definition STObject.cpp:429
V getFieldByValue(SField const &field) const
STBase * move(std::size_t n, void *buf) override
Definition STObject.cpp:123
OptionalProxy< T > operator[](OptionaledField< T > const &of)
Return a modifiable field value as std::optional.
std::size_t emplace_back(Args &&... args)
Definition STObject.h:976
STBase * getPIndex(int offset)
Definition STObject.h:1007
STArray & peekFieldArray(SField const &field)
Definition STObject.cpp:501
STNumber const & getFieldNumber(SField const &field) const
Definition STObject.cpp:706
void reserve(std::size_t n)
Definition STObject.h:946
STObject & operator=(STObject const &)=default
void addWithoutSigningFields(Serializer &s) const
Definition STObject.h:958
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:789
std::uint32_t getFlags() const
Definition STObject.cpp:537
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:645
void setFieldH160(SField const &field, base_uint< 160, Tag > const &v)
Definition STObject.h:1117
STVector256 const & getFieldV256(SField const &field) const
Definition STObject.cpp:685
bool isDefault() const override
Definition STObject.cpp:135
An immutable linear range of bytes.
Definition Slice.h:46
STBase & get()
Definition STVar.h:94
T emplace_back(T... args)
T empty(T... args)
T end(T... args)
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
SerializedTypeID
Definition SField.h:110
Number operator*(Number const &x, Number const &y)
Definition Number.h:308
HashPrefix
Prefix for hashing functions.
Definition HashPrefix.h:55
SOEStyle
Kind of element in each entry of an SOTemplate.
Definition SOTemplate.h:33
@ soeOPTIONAL
Definition SOTemplate.h:36
@ soeREQUIRED
Definition SOTemplate.h:35
@ soeDEFAULT
Definition SOTemplate.h:37
@ soeINVALID
Definition SOTemplate.h:34
void throwFieldNotFound(SField const &field)
Definition STObject.h:51
STL namespace.
T reserve(T... args)
T runtime_error(T... args)
T size(T... args)
Note, should be treated as flags that can be | and &.
Definition STBase.h:37
Indicate std::optional field semantics.
Definition SField.h:330
TypedField< T > const * f
Definition SField.h:331
STBase const & operator()(detail::STVar const &e) const
Definition STObject.h:915
A field with a type known at compile time.
Definition SField.h:320