#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace xrpl { namespace detail { defaultObject_t defaultObject; nonPresentObject_t nonPresentObject; //------------------------------------------------------------------------------ STVar::~STVar() { destroy(); } STVar::STVar(STVar const& other) { if (other.p_ != nullptr) p_ = other.p_->copy(max_size, &d_); } STVar::STVar(STVar&& other) { if (other.on_heap()) { p_ = other.p_; other.p_ = nullptr; } else { p_ = other.p_->move(max_size, &d_); } } STVar& STVar::operator=(STVar const& rhs) { if (&rhs != this) { destroy(); if (rhs.p_) p_ = rhs.p_->copy(max_size, &d_); else p_ = nullptr; } return *this; } STVar& STVar::operator=(STVar&& rhs) { if (&rhs != this) { destroy(); if (rhs.on_heap()) { p_ = rhs.p_; rhs.p_ = nullptr; } else { p_ = rhs.p_->move(max_size, &d_); } } return *this; } STVar::STVar(defaultObject_t, SField const& name) : STVar(name.fieldType, name) { } STVar::STVar(nonPresentObject_t, SField const& name) : STVar(STI_NOTPRESENT, name) { } STVar::STVar(SerialIter& sit, SField const& name, int depth) { if (depth > 10) Throw("Maximum nesting depth of STVar exceeded"); constructST(name.fieldType, depth, sit, name); } STVar::STVar(SerializedTypeID id, SField const& name) { XRPL_ASSERT( (id == STI_NOTPRESENT) || (id == name.fieldType), "xrpl::detail::STVar::STVar(SerializedTypeID) : valid type input"); constructST(id, 0, name); } void STVar::destroy() { if (on_heap()) delete p_; else p_->~STBase(); p_ = nullptr; } template requires ValidConstructSTArgs void STVar::constructST(SerializedTypeID id, int depth, Args&&... args) { auto constructWithDepth = [&]() { if constexpr (std::is_same_v...>, std::tuple>) { construct(std::forward(args)...); } else if constexpr ( std:: is_same_v...>, std::tuple>) { construct(std::forward(args)..., depth); } else { constexpr bool alwaysFalse = !std::is_same_v, std::tuple>; static_assert(alwaysFalse, "Invalid STVar constructor arguments"); } }; switch (id) { case STI_NOTPRESENT: { // Last argument is always SField SField const& field = std::get(std::forward_as_tuple(args...)); construct(field); return; } case STI_UINT8: construct(std::forward(args)...); return; case STI_UINT16: construct(std::forward(args)...); return; case STI_UINT32: construct(std::forward(args)...); return; case STI_UINT64: construct(std::forward(args)...); return; case STI_AMOUNT: construct(std::forward(args)...); return; case STI_NUMBER: construct(std::forward(args)...); return; case STI_UINT128: construct(std::forward(args)...); return; case STI_UINT160: construct(std::forward(args)...); return; case STI_UINT192: construct(std::forward(args)...); return; case STI_UINT256: construct(std::forward(args)...); return; case STI_INT32: construct(std::forward(args)...); return; case STI_VECTOR256: construct(std::forward(args)...); return; case STI_VL: construct(std::forward(args)...); return; case STI_ACCOUNT: construct(std::forward(args)...); return; case STI_PATHSET: construct(std::forward(args)...); return; case STI_OBJECT: constructWithDepth.template operator()(); return; case STI_ARRAY: constructWithDepth.template operator()(); return; case STI_ISSUE: construct(std::forward(args)...); return; case STI_XCHAIN_BRIDGE: construct(std::forward(args)...); return; case STI_CURRENCY: construct(std::forward(args)...); return; default: Throw("Unknown object type"); } } } // namespace detail } // namespace xrpl