diff --git a/include/xrpl/ledger/helpers/AccountRootHelpers.h b/include/xrpl/ledger/helpers/AccountRootHelpers.h index c8aae1a945..e818bddd06 100644 --- a/include/xrpl/ledger/helpers/AccountRootHelpers.h +++ b/include/xrpl/ledger/helpers/AccountRootHelpers.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/xrpl/ledger/helpers/SLEBase.h b/include/xrpl/ledger/helpers/SLEBase.h new file mode 100644 index 0000000000..e2183eabd7 --- /dev/null +++ b/include/xrpl/ledger/helpers/SLEBase.h @@ -0,0 +1,200 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace xrpl { + +/** + * Read-only base class for all ledger entry view classes. + * + * Provides common functionality for existence checking and raw SLE read access. + * Supports read-only (ReadView) contexts. + * + * Derived classes should provide domain-specific accessors that hide + * implementation details of the underlying ledger entry format. + */ +class ReadOnlySLE +{ +public: + virtual ~ReadOnlySLE() = default; + + // Copy/move constructors are fine (reference can be initialized from another) + ReadOnlySLE(ReadOnlySLE const&) = default; + ReadOnlySLE(ReadOnlySLE&&) = default; + // Assignment operators are deleted (cannot rebind reference members) + ReadOnlySLE& + operator=(ReadOnlySLE const&) = delete; + ReadOnlySLE& + operator=(ReadOnlySLE&&) = delete; + + /** Returns true if the ledger entry exists */ + bool + exists() const + { + return sle_ != nullptr; + } + + /** Explicit conversion to bool for convenient existence checking */ + explicit + operator bool() const + { + return exists(); + } + + /** Returns the underlying SLE for read access (always available) */ + std::shared_ptr const& + sle() const + { + return sle_; + } + + /** Returns the read view (always available) */ + ReadView const& + readView() const + { + return readView_; + } + + STLedgerEntry const* + operator->() const + { + XRPL_ASSERT(exists(), "xrpl::ReadOnlySLE::operator-> : exists"); + return sle_.get(); + } + + STLedgerEntry const& + operator*() const + { + XRPL_ASSERT(exists(), "xrpl::ReadOnlySLE::operator* : exists"); + return *sle_; + } + +protected: + // Default constructor is deleted (cannot leave reference uninitialized) + ReadOnlySLE() = delete; + + /** Constructor for read-only context (ReadView) */ + explicit ReadOnlySLE(std::shared_ptr sle, ReadView const& view) + : sle_(std::move(sle)), readView_(view) + { + } + + std::shared_ptr sle_; // Always valid (const view) + ReadView const& readView_; // Always valid +}; + +/** + * Writable base class for all ledger entry view classes. + * + * Extends ReadOnlySLE with write access capabilities. + * Supports read-write (ApplyView) contexts. + * + * Derived classes should provide domain-specific accessors that hide + * implementation details of the underlying ledger entry format. + */ +class WritableSLE +{ +public: + virtual ~WritableSLE() = default; + + // Copy/move constructors are fine (reference can be initialized from another) + WritableSLE(WritableSLE const&) = default; + WritableSLE(WritableSLE&&) = default; + // Assignment operators are deleted (cannot rebind reference members) + WritableSLE& + operator=(WritableSLE const&) = delete; + WritableSLE& + operator=(WritableSLE&&) = delete; + + /** Returns a mutable SLE for write operations */ + std::shared_ptr const& + mutableSle() const + { + return mutableSle_; + } + + /** Returns true if this wrapper supports write operations */ + bool + canModify() const + { + return mutableSle_ != nullptr; + } + + /** Returns the apply view for write operations */ + ApplyView& + applyView() const + { + return applyView_; + } + + STLedgerEntry* + operator->() + { + XRPL_ASSERT(canModify(), "xrpl::WritableSLE::operator-> : can modify"); + return mutableSle_.get(); + } + + STLedgerEntry& + operator*() + { + XRPL_ASSERT(canModify(), "xrpl::WritableSLE::operator* : can modify"); + return *mutableSle_; + } + + void + insert() + { + XRPL_ASSERT(canModify(), "xrpl::WritableSLE::insert : can modify"); + applyView_.insert(mutableSle_); + } + + void + erase() + { + XRPL_ASSERT(canModify(), "xrpl::WritableSLE::erase : can modify"); + applyView_.erase(mutableSle_); + } + + void + update() + { + XRPL_ASSERT(canModify(), "xrpl::WritableSLE::update : can modify"); + applyView_.update(mutableSle_); + } + + void + newSLE() + { + XRPL_ASSERT(!canModify(), "xrpl::WritableSLE::newSLE : mutableSle_ is not null"); + mutableSle_ = std::make_shared(key_); + } + +protected: + // Default constructor is deleted (cannot leave reference uninitialized) + WritableSLE() = delete; + + /** Constructor for read-write context (ApplyView) */ + explicit WritableSLE(std::shared_ptr sle, ApplyView& view) + : applyView_(view) + , key_(sle ? Keylet(sle->getType(), sle->key()) : Keylet(ltANY, uint256{})) + , mutableSle_(std::move(sle)) + { + } + + /** Constructor for read-write context (ApplyView) */ + explicit WritableSLE(Keylet const& key, ApplyView& view) + : applyView_(view), key_(key), mutableSle_(applyView_.peek(key)) + { + } + + ApplyView& applyView_; // ApplyView for write contexts (first for init order) + Keylet const key_; + std::shared_ptr mutableSle_; // Mutable SLE for write contexts +}; + +} // namespace xrpl