ores.cpp.service.service_header

Table of Contents

Entity service declarations. service profile (per entity). Application-layer service wrapping repository calls with business-rule validation, NATS event emission, and structured error handling.

See the Template variable reference for the complete list of available variables and their semantics.

1. Template

The full template source. Edit here and re-tangle with compass build --direct tangle_codegen_templates to regenerate library/templates/cpp_service.hpp.mustache.

{{! GENERATED FILE — tangled from projects/ores.codegen/library/templates/ores.cpp.service.service_header.org. Edit the org source. }}
{{{cpp_license}}}
{{#domain_entity}}
#ifndef ORES_{{component_core_upper}}_SERVICE_{{entity_singular_upper}}_SERVICE_HPP
#define ORES_{{component_core_upper}}_SERVICE_{{entity_singular_upper}}_SERVICE_HPP

#include <chrono>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
#include "ores.logging/make_logger.hpp"
#include "ores.database/domain/context.hpp"
#include "ores.{{component_include}}/domain/{{entity_singular}}.hpp"
{{#protocol_derived}}
#include "ores.{{component_include}}/messaging/{{entity_singular}}_protocol.hpp"
{{/protocol_derived}}
#include "ores.{{component_core}}/repository/{{entity_singular}}_repository.hpp"
#include "ores.{{component_core}}/export.hpp"
{{#gated}}
#include "ores.service/messaging/approval_gate.hpp"
{{/gated}}
{{#has_parent_id}}
#include "ores.utility/domain/hierarchy.hpp"
{{/has_parent_id}}
{{#has_uuid_include}}
#include <boost/uuid/uuid.hpp>
{{/has_uuid_include}}
<<paste:C5F35C7E-6EED-48D8-99F8-793145586882>>

namespace ores::{{component}}::service {

/**
 * @brief Service for managing {{entity_plural_words}}.
 *
 * Provides a higher-level interface for {{entity_singular_words}} operations,
 * wrapping the underlying repository.
 */
class ORES_{{component_core_upper}}_EXPORT {{entity_singular}}_service {
private:
    inline static std::string_view logger_name =
        "ores.{{component}}.service.{{entity_singular}}_service";

    [[nodiscard]] static auto& lg() {
        using namespace ores::logging;
        static auto instance = make_logger(logger_name);
        return instance;
    }

public:
    using context = ores::database::context;

    /**
     * @brief Constructs a {{entity_singular}}_service with a database context.
     *
     * @param ctx The database context for operations.
     */
    explicit {{entity_singular}}_service(context ctx);

{{#protocol_derived}}
    /**
     * @brief The protocol operations, one method per subject.
     *
     * A method takes the canonical request and answers its response, so the
     * handler that serves the subject decodes, calls and replies without
     * deciding anything. The result a caller reads -- missing, conflicting,
     * denied -- is filled here, where the storage call that decided it is
     * made, rather than being inferred from an exception.
     */
    /**@{*/
{{#operations}}
    ::ores::{{component}}::messaging::{{response}} {{method}}(const ::ores::{{component}}::messaging::{{request}}& request);
{{/operations}}
    /**@}*/
{{#gated}}

    /**
     * @brief Lets this service's writes carry out an approved request.
     *
     * The approval policy gates the writes of this entity. A write passes only
     * when it carries out a line that an approved request holds, so the
     * applier names the request here before it writes. The pass is set in
     * process: no field of a request a client sends can set it.
     */
    void carry_out_request(std::string request_id);

    /**
     * @brief Marks this service's writes as a rehearsal.
     *
     * A preview runs the real writes in a transaction it never commits. The
     * gate lets a rehearsal through, because nothing it writes lasts.
     */
    void rehearse();

    /**
     * @brief The columns a proposed write changes, by the names the approval
     * policy uses.
     *
     * The live row is read by the same key the real write reads, so the answer
     * is the one the gate gives. A write that creates a row changes every
     * column.
     */
    std::vector<std::string> changed_columns(const ::ores::{{component}}::messaging::{{entity_singular}}_write& proposed);
{{/gated}}
{{/protocol_derived}}

    /**
     * @brief Lists {{entity_plural_words}} with pagination support.
     *
     * @param offset Number of records to skip.
     * @param limit Maximum number of records to return.
     * @return Vector of {{entity_plural_words}} for the requested page.
     */
    std::vector<domain::{{entity_singular}}>
    list_{{entity_plural_short}}(std::uint32_t offset, std::uint32_t limit);

    /**
     * @brief Gets the total count of active {{entity_plural_words}}.
     *
     * @return Total number of active {{entity_plural_words}}.
     */
    std::uint32_t count_{{entity_plural_short}}();

{{#list_filter_column}}
    /**
     * @brief Lists a page of {{entity_plural_words}} under one {{list_filter_column}}.
     *
     * An empty {{list_filter_column}} covers every {{entity_singular_words}} the
     * tenant can see, so the caller need not special-case the unfiltered
     * listing.
     */
    std::vector<domain::{{entity_singular}}>
    list_{{entity_plural_short}}(std::uint32_t offset, std::uint32_t limit,
        const std::string& {{list_filter_column}});

    /**
     * @brief Counts the {{entity_plural_words}} under one {{list_filter_column}},
     * for the pager the page itself cannot supply.
     */
    std::uint32_t count_{{entity_plural_short}}(const std::string& {{list_filter_column}});

{{/list_filter_column}}


{{#foreign_keys}}
{{#list_by}}
    /**
     * @brief Lists {{entity_plural_words}} filtered by {{column}}, with pagination.
     *
     * @param {{column}} The {{column}} to filter by.
     * @param offset Number of records to skip.
     * @param limit Maximum number of records to return.
     * @return Vector of matching {{entity_plural_words}} for the requested page.
     */
    std::vector<domain::{{entity_singular}}>
    list_{{entity_plural_short}}_by_{{column}}(const std::string& {{column}},
                                              std::uint32_t offset, std::uint32_t limit);

    /**
     * @brief Gets the total count of active {{entity_plural_words}} filtered by {{column}}.
     *
     * @param {{column}} The {{column}} to filter by.
     * @return Total number of matching {{entity_plural_words}}.
     */
    std::uint32_t count_{{entity_plural_short}}_by_{{column}}(const std::string& {{column}});
{{#list_by_uuid}}

    /**
     * @brief Lists {{entity_plural_words}} filtered by {{column}}, with pagination.
     *
     * @param {{column}} The {{column}} to filter by.
     * @param offset Number of records to skip.
     * @param limit Maximum number of records to return.
     * @return Vector of matching {{entity_plural_words}} for the requested page.
     */
    std::vector<domain::{{entity_singular}}>
    list_{{entity_plural_short}}_by_{{column}}(const boost::uuids::uuid& {{column}},
                                              std::uint32_t offset, std::uint32_t limit);

    /**
     * @brief Gets the total count of active {{entity_plural_words}} filtered by {{column}}.
     *
     * @param {{column}} The {{column}} to filter by.
     * @return Total number of matching {{entity_plural_words}}.
     */
    std::uint32_t count_{{entity_plural_short}}_by_{{column}}(const boost::uuids::uuid& {{column}});
{{/list_by_uuid}}
{{/list_by}}


{{#list_by_as_of}}
    /**
     * @brief Lists {{entity_plural_words}} filtered by {{column}} that were live at
     * any point during a parent version's own [valid_from, valid_to) window.
     * See the "Temporal composite entity versioning" architecture doc.
     *
     * @param {{column}} The {{column}} to filter by.
     * @param valid_from_bound The parent version's own valid_from.
     * @param valid_to_bound The parent version's own valid_to.
     * @return Vector of matching {{entity_plural_words}}.
     */
    std::vector<domain::{{entity_singular}}>
    list_{{entity_plural_short}}_by_{{column}}_as_of(const std::string& {{column}},
                                                     std::chrono::system_clock::time_point valid_from_bound,
                                                     std::chrono::system_clock::time_point valid_to_bound);
{{/list_by_as_of}}

{{/foreign_keys}}
{{#has_audit_columns}}
    /**
     * @brief Retrieves a single {{entity_singular_words}} as it stood at a specific
     * version. See the "Temporal composite entity versioning" architecture doc.
     *
     * @param version The version to fetch.
     * @return The {{entity_singular_words}} at that version if found, std::nullopt otherwise.
     */
    std::optional<domain::{{entity_singular}}>
    get_{{entity_singular_short}}_at_version({{{primary_key.typed_params}}}, std::uint32_t version);
{{/has_audit_columns}}

    /**
     * @brief Retrieves a single {{entity_singular_words}} by its primary key.
{{#primary_key.is_single_uuid}}
     *
     * The storage key is a uuid, so the signature says which key is meant and
     * the human-readable key cannot be passed here by mistake.
{{/primary_key.is_single_uuid}}
     *
     * @return The {{entity_singular_words}} if found, std::nullopt otherwise.
     */
    std::optional<domain::{{entity_singular}}>
    {{#service_find_prefix}}find_{{/service_find_prefix}}{{^service_find_prefix}}get_{{/service_find_prefix}}{{entity_singular_short}}({{{primary_key.typed_params}}});
{{^key_is_primary}}

    /**
     * @brief Retrieves a single {{entity_singular_words}} by the key the model
     * declares -- the human-readable key a caller holds.
{{#primary_key.is_single_uuid}}
     *
     * This is the counterpart of the uuid overload above: the two keys an
     * entity holds are different keys, and a call site has to say which one it
     * means.
{{/primary_key.is_single_uuid}}
     *
     * @return The {{entity_singular_words}} if found, std::nullopt otherwise.
     */
    std::optional<domain::{{entity_singular}}>
    get_{{entity_singular_short}}_by_{{declared_key}}(const std::string& {{declared_key}});
{{/key_is_primary}}
{{#service_find_by_uuid}}

    /**
     * @brief Retrieves a single {{entity_singular_words}} by its uuid primary key.
     *
     * @return The {{entity_singular_words}} if found, std::nullopt otherwise.
     */
    std::optional<domain::{{entity_singular}}>
    find_{{entity_singular_short}}(const boost::uuids::uuid& {{primary_key.column}});
{{/service_find_by_uuid}}
{{#service_find_by_code}}
{{#parent_column}}

    /**
     * @brief Retrieves a single {{entity_singular_words}} by its
     * {{{key_label}}} (this entity's natural key is the
     * {{key_noun}}, not {{{key_tail}}} alone).
     *
     * @return The {{entity_singular_words}} if found, std::nullopt otherwise.
     */
    std::optional<domain::{{entity_singular}}>
    find_{{entity_singular_short}}_by_code({{{service_params}}});
{{/parent_column}}
{{^parent_column}}

    /**
     * @brief Retrieves a single {{entity_singular_words}} by its {{{key_label}}}.
     *
     * @return The {{entity_singular_words}} if found, std::nullopt otherwise.
     */
    std::optional<domain::{{entity_singular}}>
    find_{{entity_singular_short}}_by_code({{{service_params}}});
{{/parent_column}}
{{/service_find_by_code}}

    /**
     * @brief Retrieves a batch of {{entity_plural_words}} by primary key.
     */
    std::vector<domain::{{entity_singular}}>
    get_{{entity_plural_short}}({{{primary_key.batch_params}}});

    /**
     * @brief Saves a {{entity_singular_words}} (creates or updates).
     *
     * @param {{entity_singular_short}} The {{entity_singular_words}} to save.
     * @throws std::exception on failure.
     */
    void save_{{entity_singular_short}}(const domain::{{entity_singular}}& {{entity_singular_short}});

    /**
     * @brief Saves a batch of {{entity_plural_words}}.
     *
     * @param {{entity_plural_short}} The {{entity_plural_words}} to save.
     * @throws std::exception on failure.
     */
    void save_{{entity_plural_short}}(
        const std::vector<domain::{{entity_singular}}>& {{entity_plural_short}});

    /**
     * @brief Deletes a {{entity_singular_words}} by its primary key.
     *
     * @throws std::exception on failure.
     */
    void delete_{{entity_singular_short}}({{{primary_key.typed_params}}});
{{#service_find_by_uuid}}

    /**
     * @brief Removes a {{entity_singular_words}} by its uuid primary key.
     *
     * @throws std::exception on failure.
     */
    void remove_{{entity_singular_short}}(const boost::uuids::uuid& {{primary_key.column}});
{{/service_find_by_uuid}}

    /**
     * @brief Deletes {{entity_plural_words}} by their primary keys.
     */
    void delete_{{entity_plural_short}}({{{primary_key.batch_params}}});

{{^current_state}}
    /**
     * @brief Retrieves all historical versions of a {{entity_singular_words}}.
{{#key_is_primary}}
     *
     * Addressed by the entity's key, which is its storage key.
{{/key_is_primary}}
{{^key_is_primary}}
     *
     * Addressed by the key the model declares, which is the one a caller
     * holds; the storage key is resolved from it here, the same step every
     * other read makes.
{{/key_is_primary}}
     */
    std::vector<domain::{{entity_singular}}>
{{#key_is_primary}}
    get_{{entity_singular_short}}_history({{{primary_key.params}}});
{{/key_is_primary}}
{{^key_is_primary}}
    get_{{entity_singular_short}}_history(const std::string& key);
{{/key_is_primary}}
{{#service_find_by_uuid}}

    /**
     * @brief Retrieves all historical versions of a {{entity_singular_words}}
     * by its uuid primary key.
     */
    std::vector<domain::{{entity_singular}}>
    get_{{entity_singular_short}}_history(const boost::uuids::uuid& {{primary_key.column}});
{{/service_find_by_uuid}}
{{/current_state}}
{{#has_parent_id}}

    /**
     * @brief Gets the {{entity_singular}} hierarchy (as a forest of trees) rooted
     * at, or containing, the given {{entity_singular}}.
     *
     * @param root_id The {{entity_singular}} to start from.
     * @param from_root If true, returns the whole tree the given node
     * belongs to instead of just its subtree.
     * @return A forest of hierarchy_node trees (normally a single root).
     */
    std::vector<ores::utility::domain::hierarchy_node>
    get_hierarchy(const boost::uuids::uuid& root_id, bool from_root);
{{/has_parent_id}}

<<paste:2D4EA0F9-6AF6-45A5-A959-F672BF866C6A>>
private:
    context ctx_;
    repository::{{entity_singular}}_repository repo_;
{{#protocol_derived}}
{{#put_operations}}

    /**
     * @brief Checks one change against the row it names, and stamps it.
     *
     * A single write and a batch state the same claim, so the check, the
     * server-derived provenance and the version the store must match are one
     * decision made in one place. A batch that made the decision per element
     * would eventually make it differently from the single write.
     *
     * @param change The change as the caller stated it.
     * @param intent The reason and commentary the caller gave.
     * @param out The stamped domain object, written only when the result is ok.
     * @return ok, or why the change was refused.
     */
    ores::utility::domain::result prepare_change(
        const ::ores::{{component}}::messaging::{{entity_singular}}_change& change,
        const ores::utility::domain::change_intent& intent,
        domain::{{entity_singular}}& out);
{{/put_operations}}
{{#gated}}

    ores::service::messaging::write_pass pass_;

    /**
     * @brief Asks the approval policy whether a put may be written.
     *
     * @return nullopt when the write may go ahead, otherwise the refusal.
     */
    std::optional<ores::utility::domain::result>
    gate_put(const std::vector<domain::{{entity_singular}}>& current,
             const domain::{{entity_singular}}& next,
             const ores::utility::domain::precondition& claim);

    /**
     * @brief Asks the approval policy whether a removal may be written.
     *
     * @return nullopt when the removal may go ahead, otherwise the refusal.
     */
    std::optional<ores::utility::domain::result>
    gate_delete(const std::vector<domain::{{entity_singular}}>& live,
                std::optional<std::uint32_t> expected);

    /**
     * @brief True when the request named by the pass holds an unapplied line
     * for exactly this operation, row and version.
     */
    bool holds_line(const std::string& operation,
                    const boost::uuids::uuid& id,
                    int base_version);
{{/gated}}
{{/protocol_derived}}
<<paste:047A96EF-1CC4-4661-B80B-C6C4532076AB>>
};

}

#endif
{{/domain_entity}}
{{#junction}}
#ifndef ORES_{{component_upper}}_SERVICE_{{name_singular_upper}}_SERVICE_HPP
#define ORES_{{component_upper}}_SERVICE_{{name_singular_upper}}_SERVICE_HPP

#include <cstdint>
#include <optional>
#include <string>
#include <vector>
{{#has_uuid_left_or_right}}
#include <boost/uuid/uuid.hpp>
{{/has_uuid_left_or_right}}
#include "ores.logging/make_logger.hpp"
#include "ores.database/domain/context.hpp"
#include "ores.{{component_include}}/domain/{{name_singular}}.hpp"
{{#protocol_derived}}
#include "ores.{{component_include}}/messaging/{{name_singular}}_protocol.hpp"
{{/protocol_derived}}
#include "ores.{{component_core}}/repository/{{name_singular}}_repository.hpp"
#include "ores.{{component_core}}/export.hpp"
{{#gated}}
#include "ores.service/messaging/approval_gate.hpp"
{{/gated}}

namespace ores::{{component}}::service {

/**
 * @brief Service for managing {{name_words}}.
 *
 * Provides a higher-level interface for {{name_singular_words}} operations,
 * wrapping the underlying repository.
 */
class ORES_{{component_core_upper}}_EXPORT {{name_singular}}_service {
private:
    inline static std::string_view logger_name =
        "ores.{{component}}.service.{{name_singular}}_service";

    [[nodiscard]] static auto& lg() {
        using namespace ores::logging;
        static auto instance = make_logger(logger_name);
        return instance;
    }

public:
    using context = ores::database::context;

    /**
     * @brief Constructs a {{name_singular}}_service with a database context.
     *
     * @param ctx The database context for operations.
     */
    explicit {{name_singular}}_service(context ctx);

{{#protocol_derived}}
    /**
     * @brief The protocol operations, one method per subject.
     *
     * A method takes the canonical request and answers its response, so the
     * handler that serves the subject decodes, calls and replies without
     * deciding anything. The result a caller reads -- missing, conflicting,
     * denied -- is filled here, where the storage call that decided it is
     * made, rather than being inferred from an exception.
     */
    /**@{*/
{{#operations}}
    ::ores::{{component}}::messaging::{{response}} {{method}}(const ::ores::{{component}}::messaging::{{request}}& request);
{{/operations}}
    /**@}*/
{{#gated}}

    /**
     * @brief Lets this service's writes carry out an approved request.
     *
     * The approval policy gates the writes of this junction. A write passes
     * only when it carries out a line that an approved request holds, so the
     * applier names the request here before it writes. The pass is set in
     * process: no field of a request a client sends can set it.
     */
    void carry_out_request(std::string request_id);

    /**
     * @brief Marks this service's writes as a rehearsal.
     *
     * A preview runs the real writes in a transaction it never commits. The
     * gate lets a rehearsal through, because nothing it writes lasts.
     */
    void rehearse();
{{/gated}}
{{/protocol_derived}}

private:
    context ctx_;
    repository::{{name_singular}}_repository repo_;
{{#protocol_derived}}
{{#put_operations}}

    /**
     * @brief Checks one change against the row it names, and stamps it.
     *
     * A single write and a batch state the same claim, so the check, the
     * server-derived provenance and the version the store must match are one
     * decision made in one place. A batch that made the decision per element
     * would eventually make it differently from the single write.
     *
     * @param change The change as the caller stated it.
     * @param intent The reason and commentary the caller gave.
     * @param out The stamped domain object, written only when the result is ok.
     * @return ok, or why the change was refused.
     */
    ores::utility::domain::result prepare_change(
        const ::ores::{{component}}::messaging::{{name_singular}}_change& change,
        const ores::utility::domain::change_intent& intent,
        domain::{{name_singular}}& out);
{{/put_operations}}
{{#gated}}

    ores::service::messaging::write_pass pass_;

    /**
     * @brief Asks the approval policy whether a put may be written.
     *
     * A link has no columns of its own, so the policy is asked with none and a
     * row that names no column covers it.
     *
     * @return nullopt when the write may go ahead, otherwise the refusal.
     */
    std::optional<ores::utility::domain::result>
    gate_put(const domain::{{name_singular}}& next,
             const ores::utility::domain::precondition& claim);

    /**
     * @brief Asks the approval policy whether a removal may be written.
     *
     * @return nullopt when the removal may go ahead, otherwise the refusal.
     */
    std::optional<ores::utility::domain::result>
    gate_delete(const std::vector<domain::{{name_singular}}>& live,
                std::optional<std::uint32_t> expected);

    /**
     * @brief True when the request named by the pass holds an unapplied line
     * for exactly this operation, link and version.
     */
    bool holds_line(const std::string& operation,
                    const {{left.cpp_type}}& {{left.column}},
                    const {{right.cpp_type}}& {{right.column}},
                    int base_version);
{{/gated}}
{{/protocol_derived}}
};

}

#endif
{{/junction}}
{{#family}}
#ifndef ORES_{{component_core_upper}}_SERVICE_{{entity_singular_upper}}_SERVICE_HPP
#define ORES_{{component_core_upper}}_SERVICE_{{entity_singular_upper}}_SERVICE_HPP

#include <cstdint>
#include <optional>
#include <string>
#include <vector>
#include "ores.logging/make_logger.hpp"
#include "ores.database/domain/context.hpp"
#include "ores.{{component_include}}/domain/{{central.entity}}.hpp"
{{#parts}}
#include "ores.{{component_include}}/domain/{{entity}}.hpp"
{{/parts}}
#include "ores.{{component_include}}/messaging/{{entity_singular}}_protocol.hpp"
#include "ores.{{component_core}}/repository/{{central.entity}}_repository.hpp"
{{#parts}}
#include "ores.{{component_core}}/repository/{{entity}}_repository.hpp"
{{/parts}}
#include "ores.{{component_core}}/export.hpp"
#include "ores.utility/domain/protocol.hpp"

namespace ores::{{component}}::service {

/**
 * @brief Service for the composite {{entity_singular_words}} family.
 *
 * The family is one central row plus its parts. A read answers the central
 * row and every part live at the same instant; a write lands the central row
 * and reconciles each part in one transaction, so no reader sees the parts
 * disagree with the central version. See the "The atomised entity" and
 * "Temporal composite entity versioning" architecture documents.
 */
class ORES_{{component_core_upper}}_EXPORT {{entity_singular}}_service {
private:
    inline static std::string_view logger_name =
        "ores.{{component}}.service.{{entity_singular}}_service";

    [[nodiscard]] static auto& lg() {
        using namespace ores::logging;
        static auto instance = make_logger(logger_name);
        return instance;
    }

public:
    using context = ores::database::context;

    /**
     * @brief Constructs a {{entity_singular}}_service with a database context.
     *
     * @param ctx The database context for operations.
     */
    explicit {{entity_singular}}_service(context ctx);

    /**
     * @brief The family's protocol operations, one method per subject.
     *
     * A method takes the canonical request and answers its response, so the
     * handler that serves the subject decodes, calls and replies without
     * deciding anything.
     */
    /**@{*/
{{#operations}}
    ::ores::{{component}}::messaging::{{response}} {{method}}(const ::ores::{{component}}::messaging::{{request}}& request);
{{/operations}}
    /**@}*/

private:
    context ctx_;
    repository::{{central.entity}}_repository central_repo_;
{{#parts}}
    repository::{{entity}}_repository {{part}}_repo_;
{{/parts}}

    /**
     * @brief Assembles the family item: the central row and every part live
     * at the same instant.
     */
    ::ores::{{component}}::messaging::{{entity_singular}}_item assemble(
        const context& ctx,
        const ::ores::{{component}}::messaging::{{entity_singular}}_key& key,
        const std::optional<domain::{{central.entity}}>& central);

    /**
     * @brief Checks one central change against the row it names, and stamps it.
     *
     * A single write and a batch state the same claim, so the check and the
     * stamp are one decision made in one place.
     */
    ores::utility::domain::result prepare_{{central.entity}}(
        const ::ores::{{component}}::messaging::{{central.entity}}_change& change,
        const ores::utility::domain::change_intent& intent,
        const context& ctx,
        domain::{{central.entity}}& out);
{{#parts}}

    /**
     * @brief Checks one part change against the row it names, and stamps it.
     */
    ores::utility::domain::result prepare_{{part}}(
        const ::ores::{{component}}::messaging::{{entity}}_change& change,
        const ores::utility::domain::change_intent& intent,
        const context& ctx,
        domain::{{entity}}& out);

    /**
     * @brief Makes this part's rows for one central row exactly the rows the
     * request carries.
     *
     * The rows present are written and the rows currently live but absent are
     * closed. The part table's insert trigger bumps the central row's version,
     * so this method never does.
     */
    ores::utility::domain::result reconcile_{{part}}(
        const context& ctx,
        const domain::{{central.entity}}& central,
        const std::vector<::ores::{{component}}::messaging::{{entity}}_change>& requested,
        const ores::utility::domain::change_intent& intent);
{{/parts}}
};

}

#endif
{{/family}}

2. See also

Emacs 29.3 (Org mode 9.6.15)