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