rippled
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 <ripple/basics/CountedObject.h>
24 #include <ripple/basics/FeeUnits.h>
25 #include <ripple/basics/Slice.h>
26 #include <ripple/basics/chrono.h>
27 #include <ripple/basics/contract.h>
28 #include <ripple/protocol/HashPrefix.h>
29 #include <ripple/protocol/SOTemplate.h>
30 #include <ripple/protocol/STAmount.h>
31 #include <ripple/protocol/STBase.h>
32 #include <ripple/protocol/STIssue.h>
33 #include <ripple/protocol/STPathSet.h>
34 #include <ripple/protocol/STVector256.h>
35 #include <ripple/protocol/impl/STVar.h>
36 #include <boost/iterator/transform_iterator.hpp>
37 #include <cassert>
38 #include <optional>
39 #include <stdexcept>
40 #include <type_traits>
41 #include <utility>
42 
43 namespace ripple {
44 
45 class STArray;
46 
47 inline void
49 {
50  Throw<std::runtime_error>("Field not found: " + field.getName());
51 }
52 
53 class STObject : public STBase, public CountedObject<STObject>
54 {
55  // Proxy value for a STBase derived class
56  template <class T>
57  class Proxy;
58  template <class T>
59  class ValueProxy;
60  template <class T>
62 
63  struct Transform
64  {
65  explicit Transform() = default;
66 
69 
70  STBase const&
71  operator()(detail::STVar const& e) const;
72  };
73 
75 
77  SOTemplate const* mType;
78 
79 public:
80  using iterator = boost::
81  transform_iterator<Transform, STObject::list_type::const_iterator>;
82 
83  virtual ~STObject() = default;
84  STObject(STObject const&) = default;
85 
86  template <typename F>
87  STObject(SOTemplate const& type, SField const& name, F&& f)
88  : STObject(type, name)
89  {
90  f(*this);
91  }
92 
93  STObject&
94  operator=(STObject const&) = default;
95  STObject(STObject&&);
96  STObject&
97  operator=(STObject&& other);
98 
99  STObject(const SOTemplate& type, SField const& name);
100  STObject(const SOTemplate& type, SerialIter& sit, SField const& name);
101  STObject(SerialIter& sit, SField const& name, int depth = 0);
102  STObject(SerialIter&& sit, SField const& name);
103  explicit STObject(SField const& name);
104 
105  iterator
106  begin() const;
107 
108  iterator
109  end() const;
110 
111  bool
112  empty() const;
113 
114  void
115  reserve(std::size_t n);
116 
117  void
118  applyTemplate(const SOTemplate& type);
119 
120  void
122 
123  bool
124  isFree() const;
125 
126  void
127  set(const SOTemplate&);
128 
129  bool
130  set(SerialIter& u, int depth = 0);
131 
133  getSType() const override;
134 
135  bool
136  isEquivalent(const STBase& t) const override;
137 
138  bool
139  isDefault() const override;
140 
141  void
142  add(Serializer& s) const override;
143 
145  getFullText() const override;
146 
148  getText() const override;
149 
150  // TODO(tom): options should be an enum.
152  getJson(JsonOptions options) const override;
153 
154  void
156 
157  Serializer
158  getSerializer() const;
159 
160  template <class... Args>
162  emplace_back(Args&&... args);
163 
164  int
165  getCount() const;
166 
167  bool setFlag(std::uint32_t);
168  bool clearFlag(std::uint32_t);
169  bool isFlag(std::uint32_t) const;
170 
172  getFlags() const;
173 
174  uint256
175  getHash(HashPrefix prefix) const;
176 
177  uint256
178  getSigningHash(HashPrefix prefix) const;
179 
180  const STBase&
181  peekAtIndex(int offset) const;
182 
183  STBase&
184  getIndex(int offset);
185 
186  const STBase*
187  peekAtPIndex(int offset) const;
188 
189  STBase*
190  getPIndex(int offset);
191 
192  int
193  getFieldIndex(SField const& field) const;
194 
195  SField const&
196  getFieldSType(int index) const;
197 
198  const STBase&
199  peekAtField(SField const& field) const;
200 
201  STBase&
202  getField(SField const& field);
203 
204  const STBase*
205  peekAtPField(SField const& field) const;
206 
207  STBase*
208  getPField(SField const& field, bool createOkay = false);
209 
210  // these throw if the field type doesn't match, or return default values
211  // if the field is optional but not present
212  unsigned char
213  getFieldU8(SField const& field) const;
215  getFieldU16(SField const& field) const;
217  getFieldU32(SField const& field) const;
219  getFieldU64(SField const& field) const;
220  uint128
221  getFieldH128(SField const& field) const;
222 
223  uint160
224  getFieldH160(SField const& field) const;
225  uint256
226  getFieldH256(SField const& field) const;
227  AccountID
228  getAccountID(SField const& field) const;
229 
230  Blob
231  getFieldVL(SField const& field) const;
232  STAmount const&
233  getFieldAmount(SField const& field) const;
234  STPathSet const&
235  getFieldPathSet(SField const& field) const;
236  const STVector256&
237  getFieldV256(SField const& field) const;
238  const STArray&
239  getFieldArray(SField const& field) const;
240 
248  template <class T>
249  typename T::value_type
250  operator[](TypedField<T> const& f) const;
251 
260  template <class T>
262  operator[](OptionaledField<T> const& of) const;
263 
271  template <class T>
272  ValueProxy<T>
273  operator[](TypedField<T> const& f);
274 
284  template <class T>
285  OptionalProxy<T>
286  operator[](OptionaledField<T> const& of);
287 
295  template <class T>
296  typename T::value_type
297  at(TypedField<T> const& f) const;
298 
307  template <class T>
309  at(OptionaledField<T> const& of) const;
310 
318  template <class T>
319  ValueProxy<T>
320  at(TypedField<T> const& f);
321 
331  template <class T>
332  OptionalProxy<T>
333  at(OptionaledField<T> const& of);
334 
338  void
340 
341  void
342  set(STBase* v);
343 
344  void
345  setFieldU8(SField const& field, unsigned char);
346  void
347  setFieldU16(SField const& field, std::uint16_t);
348  void
349  setFieldU32(SField const& field, std::uint32_t);
350  void
351  setFieldU64(SField const& field, std::uint64_t);
352  void
353  setFieldH128(SField const& field, uint128 const&);
354  void
355  setFieldH256(SField const& field, uint256 const&);
356  void
357  setFieldVL(SField const& field, Blob const&);
358  void
359  setFieldVL(SField const& field, Slice const&);
360 
361  void
362  setAccountID(SField const& field, AccountID const&);
363 
364  void
365  setFieldAmount(SField const& field, STAmount const&);
366  void
367  setFieldIssue(SField const& field, STIssue const&);
368  void
369  setFieldPathSet(SField const& field, STPathSet const&);
370  void
371  setFieldV256(SField const& field, STVector256 const& v);
372  void
373  setFieldArray(SField const& field, STArray const& v);
374 
375  template <class Tag>
376  void
377  setFieldH160(SField const& field, base_uint<160, Tag> const& v);
378 
379  STObject&
380  peekFieldObject(SField const& field);
381  STArray&
382  peekFieldArray(SField const& field);
383 
384  bool
385  isFieldPresent(SField const& field) const;
386  STBase*
387  makeFieldPresent(SField const& field);
388  void
389  makeFieldAbsent(SField const& field);
390  bool
391  delField(SField const& field);
392  void
393  delField(int index);
394 
395  bool
396  hasMatchingEntry(const STBase&);
397 
398  bool
399  operator==(const STObject& o) const;
400  bool
401  operator!=(const STObject& o) const;
402 
403  class FieldErr;
404 
405 private:
406  enum WhichFields : bool {
407  // These values are carefully chosen to do the right thing if passed
408  // to SField::shouldInclude (bool)
411  };
412 
413  void
414  add(Serializer& s, WhichFields whichFields) const;
415 
416  // Sort the entries in an STObject into the order that they will be
417  // serialized. Note: they are not sorted into pointer value order, they
418  // are sorted by SField::fieldCode.
420  getSortedFields(STObject const& objToSort, WhichFields whichFields);
421 
422  // Implementation for getting (most) fields that return by value.
423  //
424  // The remove_cv and remove_reference are necessitated by the STBitString
425  // types. Their value() returns by const ref. We return those types
426  // by value.
427  template <
428  typename T,
429  typename V = typename std::remove_cv<typename std::remove_reference<
430  decltype(std::declval<T>().value())>::type>::type>
431  V
432  getFieldByValue(SField const& field) const;
433 
434  // Implementations for getting (most) fields that return by const reference.
435  //
436  // If an absent optional field is deserialized we don't have anything
437  // obvious to return. So we insist on having the call provide an
438  // 'empty' value we return in that circumstance.
439  template <typename T, typename V>
440  V const&
441  getFieldByConstRef(SField const& field, V const& empty) const;
442 
443  // Implementation for setting most fields with a setValue() method.
444  template <typename T, typename V>
445  void
446  setFieldUsingSetValue(SField const& field, V value);
447 
448  // Implementation for setting fields using assignment
449  template <typename T>
450  void
451  setFieldUsingAssignment(SField const& field, T const& value);
452 
453  // Implementation for peeking STObjects and STArrays
454  template <typename T>
455  T&
456  peekField(SField const& field);
457 
458  STBase*
459  copy(std::size_t n, void* buf) const override;
460  STBase*
461  move(std::size_t n, void* buf) override;
462 
463  friend class detail::STVar;
464 };
465 
466 //------------------------------------------------------------------------------
467 
468 template <class T>
469 class STObject::Proxy
470 {
471 protected:
472  using value_type = typename T::value_type;
473 
477 
478  Proxy(Proxy const&) = default;
479 
480  Proxy(STObject* st, TypedField<T> const* f);
481 
482  value_type
483  value() const;
484 
485  T const*
486  find() const;
487 
488  template <class U>
489  void
490  assign(U&& u);
491 };
492 
493 template <class T>
494 class STObject::ValueProxy : private Proxy<T>
495 {
496 private:
497  using value_type = typename T::value_type;
498 
499 public:
500  ValueProxy(ValueProxy const&) = default;
501  ValueProxy&
502  operator=(ValueProxy const&) = delete;
503 
504  template <class U>
506  operator=(U&& u);
507 
508  operator value_type() const;
509 
510 private:
511  friend class STObject;
512 
513  ValueProxy(STObject* st, TypedField<T> const* f);
514 };
515 
516 template <class T>
517 class STObject::OptionalProxy : private Proxy<T>
518 {
519 private:
520  using value_type = typename T::value_type;
521 
523 
524 public:
525  OptionalProxy(OptionalProxy const&) = default;
527  operator=(OptionalProxy const&) = delete;
528 
534  explicit operator bool() const noexcept;
535 
542  value_type
543  operator*() const;
544 
545  operator optional_type() const;
546 
549  operator~() const;
550 
551  friend bool
552  operator==(OptionalProxy const& lhs, std::nullopt_t) noexcept
553  {
554  return !lhs.engaged();
555  }
556 
557  friend bool
559  {
560  return rhs == std::nullopt;
561  }
562 
563  friend bool
564  operator==(OptionalProxy const& lhs, optional_type const& rhs) noexcept
565  {
566  if (!lhs.engaged())
567  return !rhs;
568  if (!rhs)
569  return false;
570  return *lhs == *rhs;
571  }
572 
573  friend bool
574  operator==(optional_type const& lhs, OptionalProxy const& rhs) noexcept
575  {
576  return rhs == lhs;
577  }
578 
579  friend bool
580  operator==(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
581  {
582  if (lhs.engaged() != rhs.engaged())
583  return false;
584  return !lhs.engaged() || *lhs == *rhs;
585  }
586 
587  friend bool
589  {
590  return !(lhs == std::nullopt);
591  }
592 
593  friend bool
595  {
596  return !(rhs == std::nullopt);
597  }
598 
599  friend bool
600  operator!=(OptionalProxy const& lhs, optional_type const& rhs) noexcept
601  {
602  return !(lhs == rhs);
603  }
604 
605  friend bool
606  operator!=(optional_type const& lhs, OptionalProxy const& rhs) noexcept
607  {
608  return !(lhs == rhs);
609  }
610 
611  friend bool
612  operator!=(OptionalProxy const& lhs, OptionalProxy const& rhs) noexcept
613  {
614  return !(lhs == rhs);
615  }
616 
617  // Emulate std::optional::value_or
618  value_type
619  value_or(value_type val) const;
620 
622  operator=(std::nullopt_t const&);
626  operator=(optional_type const& v);
627 
628  template <class U>
630  operator=(U&& u);
631 
632 private:
633  friend class STObject;
634 
635  OptionalProxy(STObject* st, TypedField<T> const* f);
636 
637  bool
638  engaged() const noexcept;
639 
640  void
641  disengage();
642 
644  optional_value() const;
645 };
646 
647 class STObject::FieldErr : public std::runtime_error
648 {
650 };
651 
652 template <class T>
653 STObject::Proxy<T>::Proxy(STObject* st, TypedField<T> const* f) : st_(st), f_(f)
654 {
655  if (st_->mType)
656  {
657  // STObject has associated template
658  if (!st_->peekAtPField(*f_))
659  Throw<STObject::FieldErr>(
660  "Template field error '" + this->f_->getName() + "'");
661  style_ = st_->mType->style(*f_);
662  }
663  else
664  {
665  style_ = soeINVALID;
666  }
667 }
668 
669 template <class T>
670 auto
672 {
673  auto const t = find();
674  if (t)
675  return t->value();
676  if (style_ == soeINVALID)
677  {
678  Throw<STObject::FieldErr>("Value requested from invalid STObject.");
679  }
680  if (style_ != soeDEFAULT)
681  {
682  Throw<STObject::FieldErr>(
683  "Missing field '" + this->f_->getName() + "'");
684  }
685  return value_type{};
686 }
687 
688 template <class T>
689 inline T const*
691 {
692  return dynamic_cast<T const*>(st_->peekAtPField(*f_));
693 }
694 
695 template <class T>
696 template <class U>
697 void
699 {
700  if (style_ == soeDEFAULT && u == value_type{})
701  {
702  st_->makeFieldAbsent(*f_);
703  return;
704  }
705  T* t;
706  if (style_ == soeINVALID)
707  t = dynamic_cast<T*>(st_->getPField(*f_, true));
708  else
709  t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
710  assert(t);
711  *t = std::forward<U>(u);
712 }
713 
714 //------------------------------------------------------------------------------
715 
716 template <class T>
717 template <class U>
720 {
721  this->assign(std::forward<U>(u));
722  return *this;
723 }
724 
725 template <class T>
727 {
728  return this->value();
729 }
730 
731 template <class T>
733  : Proxy<T>(st, f)
734 {
735 }
736 
737 //------------------------------------------------------------------------------
738 
739 template <class T>
741 {
742  return engaged();
743 }
744 
745 template <class T>
746 auto
748 {
749  return this->value();
750 }
751 
752 template <class T>
754  T>::optional_type() const
755 {
756  return optional_value();
757 }
758 
759 template <class T>
762 {
763  return optional_value();
764 }
765 
766 template <class T>
767 auto
769 {
770  disengage();
771  return *this;
772 }
773 
774 template <class T>
775 auto
777 {
778  if (v)
779  this->assign(std::move(*v));
780  else
781  disengage();
782  return *this;
783 }
784 
785 template <class T>
786 auto
788 {
789  if (v)
790  this->assign(*v);
791  else
792  disengage();
793  return *this;
794 }
795 
796 template <class T>
797 template <class U>
800 {
801  this->assign(std::forward<U>(u));
802  return *this;
803 }
804 
805 template <class T>
807  : Proxy<T>(st, f)
808 {
809 }
810 
811 template <class T>
812 bool
814 {
815  return this->style_ == soeDEFAULT || this->find() != nullptr;
816 }
817 
818 template <class T>
819 void
821 {
822  if (this->style_ == soeREQUIRED || this->style_ == soeDEFAULT)
823  Throw<STObject::FieldErr>(
824  "Template field error '" + this->f_->getName() + "'");
825  if (this->style_ == soeINVALID)
826  this->st_->delField(*this->f_);
827  else
828  this->st_->makeFieldAbsent(*this->f_);
829 }
830 
831 template <class T>
832 auto
834 {
835  if (!engaged())
836  return std::nullopt;
837  return this->value();
838 }
839 
840 template <class T>
843 {
844  return engaged() ? this->value() : val;
845 }
846 
847 //------------------------------------------------------------------------------
848 
849 inline STBase const&
851 {
852  return e.get();
853 }
854 
855 //------------------------------------------------------------------------------
856 
857 inline STObject::STObject(SerialIter&& sit, SField const& name)
858  : STObject(sit, name)
859 {
860 }
861 
862 inline STObject::iterator
864 {
865  return iterator(v_.begin());
866 }
867 
868 inline STObject::iterator
870 {
871  return iterator(v_.end());
872 }
873 
874 inline bool
876 {
877  return v_.empty();
878 }
879 
880 inline void
882 {
883  v_.reserve(n);
884 }
885 
886 inline bool
888 {
889  return mType == nullptr;
890 }
891 
892 inline void
894 {
896 }
897 
898 // VFALCO NOTE does this return an expensive copy of an object with a
899 // dynamic buffer?
900 // VFALCO TODO Remove this function and fix the few callers.
901 inline Serializer
903 {
904  Serializer s;
905  add(s, withAllFields);
906  return s;
907 }
908 
909 template <class... Args>
910 inline std::size_t
911 STObject::emplace_back(Args&&... args)
912 {
913  v_.emplace_back(std::forward<Args>(args)...);
914  return v_.size() - 1;
915 }
916 
917 inline int
919 {
920  return v_.size();
921 }
922 
923 inline const STBase&
924 STObject::peekAtIndex(int offset) const
925 {
926  return v_[offset].get();
927 }
928 
929 inline STBase&
931 {
932  return v_[offset].get();
933 }
934 
935 inline const STBase*
936 STObject::peekAtPIndex(int offset) const
937 {
938  return &v_[offset].get();
939 }
940 
941 inline STBase*
943 {
944  return &v_[offset].get();
945 }
946 
947 template <class T>
948 typename T::value_type
950 {
951  return at(f);
952 }
953 
954 template <class T>
957 {
958  return at(of);
959 }
960 
961 template <class T>
962 inline auto
964 {
965  return at(f);
966 }
967 
968 template <class T>
969 inline auto
971 {
972  return at(of);
973 }
974 
975 template <class T>
976 typename T::value_type
978 {
979  auto const b = peekAtPField(f);
980  if (!b)
981  // This is a free object (no constraints)
982  // with no template
983  Throw<STObject::FieldErr>("Missing field: " + f.getName());
984 
985  if (auto const u = dynamic_cast<T const*>(b))
986  return u->value();
987 
988  assert(mType);
989  assert(b->getSType() == STI_NOTPRESENT);
990 
991  if (mType->style(f) == soeOPTIONAL)
992  Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
993 
994  assert(mType->style(f) == soeDEFAULT);
995 
996  // Used to help handle the case where value_type is a const reference,
997  // otherwise we would return the address of a temporary.
998  static std::decay_t<typename T::value_type> const dv{};
999  return dv;
1000 }
1001 
1002 template <class T>
1005 {
1006  auto const b = peekAtPField(*of.f);
1007  if (!b)
1008  return std::nullopt;
1009  auto const u = dynamic_cast<T const*>(b);
1010  if (!u)
1011  {
1012  assert(mType);
1013  assert(b->getSType() == STI_NOTPRESENT);
1014  if (mType->style(*of.f) == soeOPTIONAL)
1015  return std::nullopt;
1016  assert(mType->style(*of.f) == soeDEFAULT);
1017  return typename T::value_type{};
1018  }
1019  return u->value();
1020 }
1021 
1022 template <class T>
1023 inline auto
1025 {
1026  return ValueProxy<T>(this, &f);
1027 }
1028 
1029 template <class T>
1030 inline auto
1032 {
1033  return OptionalProxy<T>(this, of.f);
1034 }
1035 
1036 template <class Tag>
1037 void
1039 {
1040  STBase* rf = getPField(field, true);
1041 
1042  if (!rf)
1043  throwFieldNotFound(field);
1044 
1045  if (rf->getSType() == STI_NOTPRESENT)
1046  rf = makeFieldPresent(field);
1047 
1048  using Bits = STBitString<160>;
1049  if (auto cf = dynamic_cast<Bits*>(rf))
1050  cf->setValue(v);
1051  else
1052  Throw<std::runtime_error>("Wrong field type");
1053 }
1054 
1055 inline bool
1057 {
1058  return !(*this == o);
1059 }
1060 
1061 template <typename T, typename V>
1062 V
1064 {
1065  const STBase* rf = peekAtPField(field);
1066 
1067  if (!rf)
1068  throwFieldNotFound(field);
1069 
1070  SerializedTypeID id = rf->getSType();
1071 
1072  if (id == STI_NOTPRESENT)
1073  return V(); // optional field not present
1074 
1075  const T* cf = dynamic_cast<const T*>(rf);
1076 
1077  if (!cf)
1078  Throw<std::runtime_error>("Wrong field type");
1079 
1080  return cf->value();
1081 }
1082 
1083 // Implementations for getting (most) fields that return by const reference.
1084 //
1085 // If an absent optional field is deserialized we don't have anything
1086 // obvious to return. So we insist on having the call provide an
1087 // 'empty' value we return in that circumstance.
1088 template <typename T, typename V>
1089 V const&
1090 STObject::getFieldByConstRef(SField const& field, V const& empty) const
1091 {
1092  const STBase* rf = peekAtPField(field);
1093 
1094  if (!rf)
1095  throwFieldNotFound(field);
1096 
1097  SerializedTypeID id = rf->getSType();
1098 
1099  if (id == STI_NOTPRESENT)
1100  return empty; // optional field not present
1101 
1102  const T* cf = dynamic_cast<const T*>(rf);
1103 
1104  if (!cf)
1105  Throw<std::runtime_error>("Wrong field type");
1106 
1107  return *cf;
1108 }
1109 
1110 // Implementation for setting most fields with a setValue() method.
1111 template <typename T, typename V>
1112 void
1114 {
1115  static_assert(!std::is_lvalue_reference<V>::value, "");
1116 
1117  STBase* rf = getPField(field, true);
1118 
1119  if (!rf)
1120  throwFieldNotFound(field);
1121 
1122  if (rf->getSType() == STI_NOTPRESENT)
1123  rf = makeFieldPresent(field);
1124 
1125  T* cf = dynamic_cast<T*>(rf);
1126 
1127  if (!cf)
1128  Throw<std::runtime_error>("Wrong field type");
1129 
1130  cf->setValue(std::move(value));
1131 }
1132 
1133 // Implementation for setting fields using assignment
1134 template <typename T>
1135 void
1136 STObject::setFieldUsingAssignment(SField const& field, T const& value)
1137 {
1138  STBase* rf = getPField(field, true);
1139 
1140  if (!rf)
1141  throwFieldNotFound(field);
1142 
1143  if (rf->getSType() == STI_NOTPRESENT)
1144  rf = makeFieldPresent(field);
1145 
1146  T* cf = dynamic_cast<T*>(rf);
1147 
1148  if (!cf)
1149  Throw<std::runtime_error>("Wrong field type");
1150 
1151  (*cf) = value;
1152 }
1153 
1154 // Implementation for peeking STObjects and STArrays
1155 template <typename T>
1156 T&
1158 {
1159  STBase* rf = getPField(field, true);
1160 
1161  if (!rf)
1162  throwFieldNotFound(field);
1163 
1164  if (rf->getSType() == STI_NOTPRESENT)
1165  rf = makeFieldPresent(field);
1166 
1167  T* cf = dynamic_cast<T*>(rf);
1168 
1169  if (!cf)
1170  Throw<std::runtime_error>("Wrong field type");
1171 
1172  return *cf;
1173 }
1174 
1175 } // namespace ripple
1176 
1177 #endif
ripple::STObject::getFieldSType
SField const & getFieldSType(int index) const
Definition: STObject.cpp:395
ripple::STObject::peekAtField
const STBase & peekAtField(SField const &field) const
Definition: STObject.cpp:373
ripple::STObject::OptionalProxy::operator==
friend bool operator==(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:564
ripple::STObject::OptionalProxy::value_type
typename T::value_type value_type
Definition: STObject.h:520
ripple::STObject::getSortedFields
static std::vector< STBase const * > getSortedFields(STObject const &objToSort, WhichFields whichFields)
Definition: STObject.cpp:812
ripple::STObject::setAccountID
void setAccountID(SField const &field, AccountID const &)
Definition: STObject.cpp:689
ripple::STBase::STBase
STBase()
Definition: STBase.cpp:27
ripple::STObject::STObject
STObject(STObject const &)=default
ripple::STObject::OptionalProxy::engaged
bool engaged() const noexcept
Definition: STObject.h:813
ripple::STObject::getFieldArray
const STArray & getFieldArray(SField const &field) const
Definition: STObject.cpp:624
ripple::STObject::applyTemplate
void applyTemplate(const SOTemplate &type)
Definition: STObject.cpp:116
ripple::STBase::getSType
virtual SerializedTypeID getSType() const
Definition: STBase.cpp:69
ripple::SOTemplate::style
SOEStyle style(SField const &sf) const
Definition: SOTemplate.h:136
ripple::CountedObject
Tracks the number of instances of an object.
Definition: CountedObject.h:124
ripple::STObject::makeFieldAbsent
void makeFieldAbsent(SField const &field)
Definition: STObject.cpp:514
std::string
STL class.
ripple::STObject::hasMatchingEntry
bool hasMatchingEntry(const STBase &)
Definition: STObject.cpp:243
utility
ripple::TypedField
A field with a type known at compile time.
Definition: SField.h:304
std::is_lvalue_reference
ripple::STObject::setFieldH128
void setFieldH128(SField const &field, uint128 const &)
Definition: STObject.cpp:671
ripple::STObject::setFieldU16
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:653
ripple::STObject::setFieldIssue
void setFieldIssue(SField const &field, STIssue const &)
Definition: STObject.cpp:713
ripple::STObject::at
T::value_type at(TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:977
ripple::STObject::setFieldV256
void setFieldV256(SField const &field, STVector256 const &v)
Definition: STObject.cpp:683
ripple::STObject::Transform::operator()
STBase const & operator()(detail::STVar const &e) const
Definition: STObject.h:850
ripple::STObject::getFieldU64
std::uint64_t getFieldU64(SField const &field) const
Definition: STObject.cpp:565
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::STObject::peekAtPIndex
const STBase * peekAtPIndex(int offset) const
Definition: STObject.h:936
ripple::STObject::getFieldV256
const STVector256 & getFieldV256(SField const &field) const
Definition: STObject.cpp:617
ripple::STObject::v_
list_type v_
Definition: STObject.h:76
ripple::STObject::OptionalProxy::operator!=
friend bool operator!=(OptionalProxy const &lhs, optional_type const &rhs) noexcept
Definition: STObject.h:600
std::vector::reserve
T reserve(T... args)
ripple::STObject::Proxy::value_type
typename T::value_type value_type
Definition: STObject.h:472
ripple::STObject::OptionalProxy::operator!=
friend bool operator!=(OptionalProxy const &lhs, std::nullopt_t) noexcept
Definition: STObject.h:588
ripple::STObject::getFieldByConstRef
V const & getFieldByConstRef(SField const &field, V const &empty) const
Definition: STObject.h:1090
std::vector< detail::STVar >
std::vector::size
T size(T... args)
ripple::STObject::getFieldU8
unsigned char getFieldU8(SField const &field) const
Definition: STObject.cpp:547
ripple::SerializedTypeID
SerializedTypeID
Definition: SField.h:104
ripple::STObject::withAllFields
@ withAllFields
Definition: STObject.h:410
ripple::STObject::empty
bool empty() const
Definition: STObject.h:875
ripple::STObject::getSerializer
Serializer getSerializer() const
Definition: STObject.h:902
ripple::STObject::getFieldH128
uint128 getFieldH128(SField const &field) const
Definition: STObject.cpp:571
ripple::STObject::WhichFields
WhichFields
Definition: STObject.h:406
ripple::soeREQUIRED
@ soeREQUIRED
Definition: SOTemplate.h:35
ripple::OptionaledField
Indicate std::optional field semantics.
Definition: SField.h:314
ripple::STObject::OptionalProxy::operator=
OptionalProxy & operator=(OptionalProxy const &)=delete
ripple::STObject::move
STBase * move(std::size_t n, void *buf) override
Definition: STObject.cpp:67
ripple::STObject::setFieldVL
void setFieldVL(SField const &field, Blob const &)
Definition: STObject.cpp:695
ripple::STObject::getFieldVL
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:595
ripple::STObject::isDefault
bool isDefault() const override
Definition: STObject.cpp:79
ripple::STBitString::setValue
void setValue(base_uint< Bits, Tag > const &v)
Definition: STBitString.h:173
ripple::STObject::OptionalProxy::operator==
friend bool operator==(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:558
ripple::STObject::~STObject
virtual ~STObject()=default
ripple::STObject::getFieldH160
uint160 getFieldH160(SField const &field) const
Definition: STObject.cpp:577
ripple::STBitString
Definition: SField.h:49
ripple::STPathSet
Definition: STPathSet.h:176
ripple::STObject::getFullText
std::string getFullText() const override
Definition: STObject.cpp:254
ripple::STObject::isEquivalent
bool isEquivalent(const STBase &t) const override
Definition: STObject.cpp:304
ripple::STObject::Proxy::assign
void assign(U &&u)
Definition: STObject.h:698
stdexcept
ripple::base_uint< 256 >
ripple::STObject::peekAtIndex
const STBase & peekAtIndex(int offset) const
Definition: STObject.h:924
ripple::STObject::setFieldH160
void setFieldH160(SField const &field, base_uint< 160, Tag > const &v)
Definition: STObject.h:1038
ripple::STObject::OptionalProxy::operator!=
friend bool operator!=(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:606
ripple::STObject::operator=
STObject & operator=(STObject const &)=default
ripple::STObject::FieldErr
Definition: STObject.h:647
ripple::STObject::OptionalProxy::OptionalProxy
OptionalProxy(OptionalProxy const &)=default
ripple::STObject::Proxy::st_
STObject * st_
Definition: STObject.h:474
ripple::STObject::delField
bool delField(SField const &field)
Definition: STObject.cpp:529
ripple::STObject::ValueProxy::value_type
typename T::value_type value_type
Definition: STObject.h:497
ripple::STObject::ValueProxy
Definition: STObject.h:59
ripple::STObject::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STObject.cpp:61
ripple::SOTemplate
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:82
ripple::STObject::OptionalProxy
Definition: STObject.h:61
ripple::STObject::setFieldArray
void setFieldArray(SField const &field, STArray const &v)
Definition: STObject.cpp:725
ripple::STObject::iterator
boost::transform_iterator< Transform, STObject::list_type::const_iterator > iterator
Definition: STObject.h:81
ripple::HashPrefix
HashPrefix
Prefix for hashing functions.
Definition: HashPrefix.h:54
ripple::STObject::Proxy::f_
TypedField< T > const * f_
Definition: STObject.h:476
ripple::STObject::setFieldU8
void setFieldU8(SField const &field, unsigned char)
Definition: STObject.cpp:647
std::enable_if_t
ripple::STObject::peekFieldArray
STArray & peekFieldArray(SField const &field)
Definition: STObject.cpp:445
ripple::STObject::OptionalProxy::optional_type
std::optional< typename std::decay< value_type >::type > optional_type
Definition: STObject.h:522
ripple::STObject::operator==
bool operator==(const STObject &o) const
Definition: STObject.cpp:744
ripple::STObject::setFieldAmount
void setFieldAmount(SField const &field, STAmount const &)
Definition: STObject.cpp:707
ripple::STObject::operator!=
bool operator!=(const STObject &o) const
Definition: STObject.h:1056
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:589
ripple::STObject::setFieldH256
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:677
ripple::STObject::end
iterator end() const
Definition: STObject.h:869
ripple::soeOPTIONAL
@ soeOPTIONAL
Definition: SOTemplate.h:36
ripple::SOEStyle
SOEStyle
Kind of element in each entry of an SOTemplate.
Definition: SOTemplate.h:33
ripple::throwFieldNotFound
void throwFieldNotFound(SField const &field)
Definition: STObject.h:48
ripple::STArray
Definition: STArray.h:28
ripple::STAmount
Definition: STAmount.h:46
ripple::STObject::clearFlag
bool clearFlag(std::uint32_t)
Definition: STObject.cpp:463
ripple::STObject::getFlags
std::uint32_t getFlags() const
Definition: STObject.cpp:481
ripple::soeINVALID
@ soeINVALID
Definition: SOTemplate.h:34
ripple::STObject::begin
iterator begin() const
Definition: STObject.h:863
std::runtime_error::runtime_error
T runtime_error(T... args)
ripple::SerialIter
Definition: Serializer.h:311
std::uint32_t
ripple::STObject::OptionalProxy::operator!=
friend bool operator!=(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:612
ripple::STObject::addWithoutSigningFields
void addWithoutSigningFields(Serializer &s) const
Definition: STObject.h:893
ripple::STObject::reserve
void reserve(std::size_t n)
Definition: STObject.h:881
ripple::STObject::getFieldU16
std::uint16_t getFieldU16(SField const &field) const
Definition: STObject.cpp:553
ripple::STObject::setFieldUsingAssignment
void setFieldUsingAssignment(SField const &field, T const &value)
Definition: STObject.h:1136
ripple::STObject::STObject
STObject(SOTemplate const &type, SField const &name, F &&f)
Definition: STObject.h:87
ripple::STIssue
Definition: STIssue.h:31
ripple::STObject::getPField
STBase * getPField(SField const &field, bool createOkay=false)
Definition: STObject.cpp:412
ripple::STObject::setFieldPathSet
void setFieldPathSet(SField const &field, STPathSet const &)
Definition: STObject.cpp:719
std::decay_t
ripple::Serializer
Definition: Serializer.h:40
ripple::STObject::mType
SOTemplate const * mType
Definition: STObject.h:77
ripple::STObject::getFieldIndex
int getFieldIndex(SField const &field) const
Definition: STObject.cpp:357
ripple::STObject::makeFieldPresent
STBase * makeFieldPresent(SField const &field)
Definition: STObject.cpp:492
ripple::STObject::emplace_back
std::size_t emplace_back(Args &&... args)
Definition: STObject.h:911
ripple::STObject::ValueProxy::ValueProxy
ValueProxy(ValueProxy const &)=default
ripple::STObject::add
void add(Serializer &s) const override
Definition: STObject.cpp:85
ripple::STObject
Definition: STObject.h:53
ripple::STObject::Proxy
Definition: STObject.h:57
ripple::STObject::Proxy::find
T const * find() const
Definition: STObject.h:690
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STObject::Proxy::style_
SOEStyle style_
Definition: STObject.h:475
std::remove_reference
ripple::STObject::getIndex
STBase & getIndex(int offset)
Definition: STObject.h:930
ripple::STObject::peekFieldObject
STObject & peekFieldObject(SField const &field)
Definition: STObject.cpp:439
ripple::JsonOptions
Note, should be treated as flags that can be | and &.
Definition: STBase.h:35
ripple::STObject::getSigningHash
uint256 getSigningHash(HashPrefix prefix) const
Definition: STObject.cpp:348
ripple::STObject::peekAtPField
const STBase * peekAtPField(SField const &field) const
Definition: STObject.cpp:401
std::nullopt_t
ripple::SField
Identifies fields.
Definition: SField.h:139
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:121
ripple::STObject::getField
STBase & getField(SField const &field)
Definition: STObject.cpp:384
ripple::STObject::getSType
SerializedTypeID getSType() const override
Definition: STObject.cpp:73
std::vector::begin
T begin(T... args)
ripple::SField::getName
std::string const & getName() const
Definition: SField.h:202
std
STL namespace.
ripple::STObject::peekField
T & peekField(SField const &field)
Definition: STObject.h:1157
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:428
cassert
ripple::detail::STVar::get
STBase & get()
Definition: STVar.h:82
ripple::STObject::Transform
Definition: STObject.h:63
ripple::STObject::OptionalProxy::operator==
friend bool operator==(OptionalProxy const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:580
ripple::STObject::OptionalProxy::operator~
optional_type operator~() const
Explicit conversion to std::optional.
Definition: STObject.h:761
ripple::STObject::Proxy::Proxy
Proxy(Proxy const &)=default
ripple::STObject::OptionalProxy::operator==
friend bool operator==(optional_type const &lhs, OptionalProxy const &rhs) noexcept
Definition: STObject.h:574
ripple::STObject::setFieldUsingSetValue
void setFieldUsingSetValue(SField const &field, V value)
Definition: STObject.h:1113
ripple::STObject::setFlag
bool setFlag(std::uint32_t)
Definition: STObject.cpp:451
ripple::STVector256
Definition: STVector256.h:30
ripple::STObject::isFlag
bool isFlag(std::uint32_t) const
Definition: STObject.cpp:475
std::vector::empty
T empty(T... args)
ripple::STObject::OptionalProxy::operator*
value_type operator*() const
Return the contained value.
Definition: STObject.h:747
std::remove_cv
ripple::STObject::Proxy::value
value_type value() const
Definition: STObject.h:671
ripple::STObject::OptionalProxy::operator!=
friend bool operator!=(std::nullopt_t, OptionalProxy const &rhs) noexcept
Definition: STObject.h:594
optional
ripple::STObject::getCount
int getCount() const
Definition: STObject.h:918
std::size_t
ripple::OptionaledField::f
TypedField< T > const * f
Definition: SField.h:316
ripple::STObject::applyTemplateFromSField
void applyTemplateFromSField(SField const &)
Definition: STObject.cpp:170
std::vector::end
T end(T... args)
ripple::STObject::OptionalProxy::optional_value
optional_type optional_value() const
Definition: STObject.h:833
ripple::STObject::operator[]
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition: STObject.h:949
ripple::STObject::getFieldU32
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:559
ripple::STObject::getFieldByValue
V getFieldByValue(SField const &field) const
ripple::STObject::Transform::Transform
Transform()=default
ripple::STObject::OptionalProxy::value_or
value_type value_or(value_type val) const
Definition: STObject.h:842
ripple::STObject::setFieldU64
void setFieldU64(SField const &field, std::uint64_t)
Definition: STObject.cpp:665
ripple::STObject::getJson
Json::Value getJson(JsonOptions options) const override
Definition: STObject.cpp:731
std::unique_ptr
STL class.
ripple::STObject::getFieldPathSet
STPathSet const & getFieldPathSet(SField const &field) const
Definition: STObject.cpp:610
ripple::STObject::omitSigningFields
@ omitSigningFields
Definition: STObject.h:409
ripple::STObject::set
void set(const SOTemplate &)
Definition: STObject.cpp:100
ripple::STObject::setFieldU32
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:659
ripple::STObject::OptionalProxy::disengage
void disengage()
Definition: STObject.h:820
type_traits
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::STObject::getPIndex
STBase * getPIndex(int offset)
Definition: STObject.h:942
ripple::soeDEFAULT
@ soeDEFAULT
Definition: SOTemplate.h:37
ripple::detail::STVar
Definition: STVar.h:49
ripple::STObject::isFree
bool isFree() const
Definition: STObject.h:887
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::STObject::ValueProxy::operator=
ValueProxy & operator=(ValueProxy const &)=delete
ripple::STObject::getHash
uint256 getHash(HashPrefix prefix) const
Definition: STObject.cpp:339
ripple::STObject::getText
std::string getText() const override
Definition: STObject.cpp:285
ripple::STObject::getFieldH256
uint256 getFieldH256(SField const &field) const
Definition: STObject.cpp:583