diff --git a/examples/c/common.c b/examples/c/common.c index eaeae2b571d8495a574ad3ec57e5c321d2694dfb..c5b97ae499228e8edf5b5aacd02f2a852b349389 100644 --- a/examples/c/common.c +++ b/examples/c/common.c @@ -17,7 +17,7 @@ prepare_nodes(size_t n) { size_t len = snprintf(NULL, 0, "node-%02zu", i); char* id = (char*) alloca(len + 1); snprintf(id, len + 1, "node-%02zu", i); - nodes[i] = ADM_node_create(id); + nodes[i] = ADM_node_create(id, ADM_NODE_REGULAR); if(!nodes[i]) { return NULL; } diff --git a/src/lib/scord/types.h b/src/lib/scord/types.h index f1f24923d809f780fdec61dce2839f3b028db3af..487b80ecb93074c6b318668ebf470c3f57d48b15 100644 --- a/src/lib/scord/types.h +++ b/src/lib/scord/types.h @@ -61,6 +61,12 @@ typedef enum { /** A RPC server */ typedef struct adm_server* ADM_server_t; +/** Node types */ +typedef enum { + ADM_NODE_REGULAR, + ADM_NODE_ADMINISTRATIVE, +} ADM_node_type_t; + /** A node */ typedef struct adm_node* ADM_node_t; @@ -247,7 +253,7 @@ ADM_server_destroy(ADM_server_t server); * @return A valid ADM_server_t if successful or NULL in case of failure. */ ADM_node_t -ADM_node_create(const char* hostname); +ADM_node_create(const char* hostname, ADM_node_type_t type); /** * Destroy a node created by ADM_node_create(). diff --git a/src/lib/scord/types.hpp b/src/lib/scord/types.hpp index e017f2fbd87a25c89b0434469e5dbb0635040763..3f0c45e71ac811d1d82d7380e2b77ab1b7cf7a38 100644 --- a/src/lib/scord/types.hpp +++ b/src/lib/scord/types.hpp @@ -142,8 +142,14 @@ private: struct node { + enum class type : std::underlying_type::type { + regular = ADM_NODE_REGULAR, + administrative = ADM_NODE_ADMINISTRATIVE, + }; + node(); - explicit node(std::string hostname); + explicit node(std::string hostname, + node::type node_type = node::type::regular); explicit node(const ADM_node_t& srv); node(const node&) noexcept; node(node&&) noexcept; @@ -156,6 +162,9 @@ struct node { std::string hostname() const; + node::type + get_type() const; + // The implementation for this must be deferred until // after the declaration of the PIMPL class template @@ -637,14 +646,38 @@ struct fmt::formatter : formatter { } }; +template <> +struct fmt::formatter : fmt::formatter { + // parse is inherited from formatter. + template + auto + format(const scord::node::type& t, FormatContext& ctx) const { + + using scord::node; + std::string_view name = "unknown"; + + switch(t) { + case node::type::regular: + name = "regular"; + break; + + case node::type::administrative: + name = "administrative"; + break; + } + + return formatter::format(name, ctx); + } +}; + template <> struct fmt::formatter : formatter { // parse is inherited from formatter. template auto format(const scord::node& n, FormatContext& ctx) const { - const auto str = - fmt::format("{{hostname: {}}}", std::quoted(n.hostname())); + const auto str = fmt::format("{{hostname: {}, type: {}}}", + std::quoted(n.hostname()), n.get_type()); return formatter::format(str, ctx); } }; diff --git a/src/lib/types.c b/src/lib/types.c index 0a44d15f7034a397d93e263c26faf5e53b1d05f7..b7480a974c709fa2cbdbcadfbd61b6b26f62a360 100644 --- a/src/lib/types.c +++ b/src/lib/types.c @@ -66,7 +66,7 @@ ADM_server_destroy(ADM_server_t server) { } ADM_node_t -ADM_node_create(const char* hostname) { +ADM_node_create(const char* hostname, ADM_node_type_t type) { struct adm_node* adm_node = (struct adm_node*) malloc(sizeof(struct adm_node)); @@ -80,6 +80,7 @@ ADM_node_create(const char* hostname) { size_t n = strlen(hostname); adm_node->n_hostname = (const char*) calloc(n + 1, sizeof(char)); strcpy((char*) adm_node->n_hostname, hostname); + adm_node->n_type = type; } return adm_node; diff --git a/src/lib/types.cpp b/src/lib/types.cpp index 2b23bd7325ca8811e9ae5f4e39306841c55b28ea..779c1ab816eb6924ea948dd457d71ba238b18d11 100644 --- a/src/lib/types.cpp +++ b/src/lib/types.cpp @@ -96,35 +96,45 @@ class node::impl { public: impl() = default; - explicit impl(std::string hostname) : m_hostname(std::move(hostname)) {} + explicit impl(std::string hostname, node::type node_type) + : m_hostname(std::move(hostname)), m_type(node_type) {} std::string hostname() const { return m_hostname; } + node::type + get_type() const { + return m_type; + } + template void load(Archive& ar) { ar(SCORD_SERIALIZATION_NVP(m_hostname)); + ar(SCORD_SERIALIZATION_NVP(m_type)); } template void save(Archive& ar) const { ar(SCORD_SERIALIZATION_NVP(m_hostname)); + ar(SCORD_SERIALIZATION_NVP(m_type)); } private: std::string m_hostname; + node::type m_type; }; node::node() = default; -node::node(std::string hostname) - : m_pimpl(std::make_unique(std::move(hostname))) {} +node::node(std::string hostname, node::type type) + : m_pimpl(std::make_unique(std::move(hostname), type)) {} -node::node(const ADM_node_t& node) : node::node(node->n_hostname) {} +node::node(const ADM_node_t& node) + : node::node(node->n_hostname, static_cast(node->n_type)) {} node::node(const node& other) noexcept : m_pimpl(std::make_unique(*other.m_pimpl)) {} @@ -147,6 +157,11 @@ node::hostname() const { return m_pimpl->hostname(); } +node::type +node::get_type() const { + return m_pimpl->get_type(); +} + // since the PIMPL class is fully defined at this point, we can now // define the serialization function template @@ -528,7 +543,9 @@ adhoc_storage::resources::operator ADM_adhoc_resources_t() const { std::vector tmp; std::transform(m_nodes.cbegin(), m_nodes.cend(), std::back_inserter(tmp), [](const scord::node& n) { - return ADM_node_create(n.hostname().c_str()); + return ADM_node_create( + n.hostname().c_str(), + static_cast(n.get_type())); }); // N.B. This works because AMD_adhoc_resources_create() internally copies diff --git a/src/lib/types_private.h b/src/lib/types_private.h index db44caf5dd896f24341082fffeddcb6814cf5d60..b66b0b722acf31649cadaa8762fc4fbb64a53de6 100644 --- a/src/lib/types_private.h +++ b/src/lib/types_private.h @@ -38,6 +38,7 @@ struct adm_server { struct adm_node { const char* n_hostname; + ADM_node_type_t n_type; }; struct adm_dataset {