diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index bcd38172d7..2da8934454 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -15,6 +15,8 @@ add_library( outputHandler.cpp outputHandler.h parserLibrary.cpp + serialiser.h + serialiser.cpp sysFunc.cpp sysFunc.h timer.cpp diff --git a/src/base/geometry.cpp b/src/base/geometry.cpp index 1eaebeda5e..de6b229309 100644 --- a/src/base/geometry.cpp +++ b/src/base/geometry.cpp @@ -34,3 +34,39 @@ int Geometry::indices(int i) const { return indices_[i]; } bool Geometry::operator==(const Geometry &rhs) const { return value_ == rhs.value_ && indices_ == rhs.indices_; } bool Geometry::operator!=(const Geometry &rhs) const { return !(rhs == *this); } + +namespace Serialisable +{ +void serialiseOnto(const Geometry::GeometryType &e, std::string tag, SerialisedValue &node) +{ + switch (e) + { + case Geometry::GeometryType::AngleType: + node["tag"] = "angle"; + case Geometry::GeometryType::DistanceType: + node["tag"] = "distance"; + case Geometry::GeometryType::TorsionType: + node["tag"] = "torsion"; + default: + throw std::runtime_error("Unhandled geometry type - can't convert to TOML value.\n"); + } +} +}; // namespace Serialisable + +namespace Deserialisable +{ +void deserialiseOnto(Geometry::GeometryType &e, const SerialisedValue &target) +{ + auto typeString = target.as_string(); + if (typeString == "angle") + e = Geometry::GeometryType::AngleType; + else if (typeString == "distance") + e = Geometry::GeometryType::DistanceType; + else if (typeString == "torsion") + e = Geometry::GeometryType::TorsionType; + else + throw toml::type_error( + std::format("Unhandled geometry type '{}' - can't convert from TOML value.\n", std::string(typeString)), + target.location()); +} +} // namespace Deserialisable diff --git a/src/base/geometry.h b/src/base/geometry.h index f7754d68bd..1bd6da33c3 100644 --- a/src/base/geometry.h +++ b/src/base/geometry.h @@ -3,9 +3,9 @@ #pragma once +#include "base/serialiser.h" #include #include -#include // Geometry Definition class Geometry @@ -42,41 +42,12 @@ class Geometry }; // TOML Conversion -namespace toml +namespace Serialisable { -template <> struct from -{ - static Geometry::GeometryType from_toml(const toml::value &node) - { - auto typeString = node.as_string(); - if (typeString == "angle") - return Geometry::GeometryType::AngleType; - else if (typeString == "distance") - return Geometry::GeometryType::DistanceType; - else if (typeString == "torsion") - return Geometry::GeometryType::TorsionType; - else - throw toml::type_error( - std::format("Unhandled geometry type '{}' - can't convert from TOML value.\n", std::string(typeString)), - node.location()); - } +void serialiseOnto(const Geometry::GeometryType &e, std::string tag, SerialisedValue &node); }; -template <> struct into +namespace Deserialisable { - static toml::basic_value into_toml(const Geometry::GeometryType &e) - { - switch (e) - { - case Geometry::GeometryType::AngleType: - return "angle"; - case Geometry::GeometryType::DistanceType: - return "distance"; - case Geometry::GeometryType::TorsionType: - return "torsion"; - default: - throw std::runtime_error("Unhandled geometry type - can't convert to TOML value.\n"); - } - } -}; -} // namespace toml +void deserialiseOnto(Geometry::GeometryType &e, const SerialisedValue &target); +} diff --git a/src/base/serialiser.cpp b/src/base/serialiser.cpp new file mode 100644 index 0000000000..1c42af04d6 --- /dev/null +++ b/src/base/serialiser.cpp @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 Team Dissolve and contributors + +#include "base/serialiser.h" + +namespace Serialisable +{ +void serialiseOnto(int a, std::string tag, SerialisedValue &target) { target[tag] = a; } +void serialiseOnto(double a, std::string tag, SerialisedValue &target) { target[tag] = a; } +void serialiseOnto(std::string a, std::string tag, SerialisedValue &target) { target[tag] = a; } +} // namespace Serialisable + +namespace Deserialisable +{ +void deserialiseOnto(bool &a, const SerialisedValue &target) { a = target.as_boolean(); } +void deserialiseOnto(int &a, const SerialisedValue &target) { a = target.as_integer(); } +void deserialiseOnto(long &a, const SerialisedValue &target) { a = target.as_integer(); } +void deserialiseOnto(float &a, const SerialisedValue &target) { a = target.as_floating(); } +void deserialiseOnto(double &a, const SerialisedValue &target) { a = target.as_floating(); } +void deserialiseOnto(std::string &a, const SerialisedValue &target) { a = target.as_string(); } +} // namespace Deserialisable diff --git a/src/base/serialiser.h b/src/base/serialiser.h index e77fca1082..44e0876a20 100644 --- a/src/base/serialiser.h +++ b/src/base/serialiser.h @@ -3,252 +3,28 @@ #pragma once -#include "templates/keyedVector.h" #include "templates/orderedMap.h" -#include "templates/resolvableKeyedVector.h" -#include #include #include // The type we use for the nodes of our serialisation tree using SerialisedValue = toml::basic_value; -// We need a way at compile time to detect all the types of smart -// pointers for things that can be serialised -template -concept serialisablePointer = requires(T a, std::string tag, SerialisedValue target) { a->serialise(tag, target); }; - -// An interface for classes that can be serialised into an input file -class Serialisable +namespace Serialisable { - public: - Serialisable() = default; - virtual ~Serialisable() = default; - // Express as a serialisable value - virtual void serialise(std::string tag, SerialisedValue &target) const = 0; - // Read values from a serialisable value - virtual void deserialise(const SerialisedValue &node) {} - - /* Functions that hook into the toml11 library */ - // Wrapper for deserialise that toml11 will check for - void from_toml(const toml::value &node) { deserialise(node); } - // Wrapper for serialise that toml11 will check for - SerialisedValue into_toml() const - { - SerialisedValue result; - serialise("inner", result); - return result["inner"]; - } - - // Perform an action on a child node in a table if the node exists. - // This cuts out quite a bit of boilerplate. - template static bool optionalOn(const SerialisedValue &node, std::string name, Lambda action) - { - if (node.contains(name)) - { - auto child = toml::find(node, name); - if (!node.is_uninitialized()) - action(child); - return true; - } - - return false; - } - // Place the named value into the supplied object, but only if it exists - template bool getIfPresent(const SerialisedValue &node, std::string name, U &destination) - { - if (!node.contains(name)) - return false; - destination = toml::find(node, name); - return true; - } - // A helper function to add elements of a vector to a node under the named heading - template - static void fromVectorToTable(const std::vector &vector, std::string name, SerialisedValue &node) - { - fromVectorToTable(vector, name, node, [](const auto &item) { return item->name().data(); }); - } - // A helper function to add elements of a vector to a node - template - static SerialisedValue fromVectorToTable(const std::vector &vector, Lambda getName) - { - SerialisedValue group; - for (const auto &value : vector) - value->serialise(getName(value), group); - return group; - }; - // A helper function to add elements of a KeyedVector to a node - template - static SerialisedValue fromVectorToTable(const KeyedVector &keyedVector, Lambda getName) - { - SerialisedValue group; - for (const auto &[key, value] : keyedVector) - group[std::string(getName(key))] = value; - return group; - }; - // A helper function to add elements of a ResolvableKeyedVector to a node - template - static SerialisedValue fromVectorToTable(const ResolvableKeyedVector &keyedVector) - { - SerialisedValue group; - for (const auto &[resolvable, value] : keyedVector) - group[std::string(resolvable.name())] = value; - return group; - } - template - static SerialisedValue fromVectorToTable(const ResolvableKeyedVector &keyedVector, Lambda getInner) - { - SerialisedValue group; - for (const auto &[resolvable, value] : keyedVector) - group[std::string(resolvable.name())] = getInner(value); - return group; - } - // A helper function to add elements of a vector to a node under the named heading - template - static void fromVectorToTable(const std::vector &vector, std::string name, SerialisedValue &node, Lambda getName) - { - if (vector.empty()) - return; - node[name] = fromVectorToTable(vector, getName); - }; - // A helper function to add elements of a vector to a node. This - // is more generic than fromVectorToTable and the later could be - // be implemented in terms of this function, but the two template - // types conflict with the resolution of other overloads. While - // this could be solved with C++20 Concepts, it's probably better - // to just remove the other overloads. That should be another - // issue before TOML is merged. - template - static SerialisedValue fromVectorToMap(const std::vector &vector, Lambda getName, Lambda2 getValue) - { - SerialisedValue group; - for (auto &value : vector) - group[getName(value)] = getValue(value); - return group; - }; - // A helper function to add the elements of a vector to a node under a name - template - static void fromVector(const std::vector> &vector, std::string name, SerialisedValue &node) - { - fromVector(vector, name, node, - [](const auto &item) - { - SerialisedValue outer; - item->serialise("inner", outer); - return outer["inner"]; - }); - } - // A helper function to add the elements of a vector to a node under a name - template - static void fromVector(const std::vector> &vector, std::string name, SerialisedValue &node) - { - fromVector(vector, name, node, [](const auto &item) { return item->serialise(); }); - } - // A helper function to add the elements of a vector to a node under a name - template static void fromVector(const std::vector &vector, std::string name, SerialisedValue &node) - { - fromVector(vector, name, node, - [](const auto &item) - { - SerialisedValue outer; - item.serialise("inner", outer); - return outer["inner"]; - }); - } - // A helper function to add the elements of a vector to a node under a name - template - static void fromVector(const std::vector &vector, std::string name, SerialisedValue &node, Lambda toSerial) - { - if (vector.empty()) - return; - node[name] = fromVector(vector, toSerial); - } - // A helper function to add the elements of a vector to a node under a name - template static SerialisedValue fromVector(const std::vector &vector, Lambda toSerial) - { - SerialisedValue result = SerialisedValue::array_type{}; - std::transform(vector.begin(), vector.end(), std::back_inserter(result), toSerial); - return result; - } - // A helper function to add the elements of a ranged object to a node under a name - template - static SerialisedValue fromRange(const Range &range, Lambda toSerial) - { - SerialisedValue result = SerialisedValue::array_type{}; - std::ranges::transform(range, std::back_inserter(result), toSerial); - return result; - } - // A helper function to add the elements of a map to a node under a name - template static void fromMap(const std::map &map, std::string name, SerialisedValue &node) - { - SerialisedValue result; - for (auto &[key, value] : map) - if constexpr (serialisablePointer) - value->serialise(std::format("{}", key), result); - else if constexpr (std::is_base_of_v) - value.serialise(std::format("{}", key), result); - else - // We use the direct value (with casting) instead of - // value.serialise() to handle the case where the value - // is a raw type (e.g. int) - result[std::format("{}", key)] = value; - if (!map.empty()) - node[name] = result; - } - // A helper function to add the elements of a map to a node under a name - // Only add values that pass the test lambda - template - static void fromMap(const std::map &map, std::string name, SerialisedValue &node, Lambda filter) - { - SerialisedValue result; - bool changed = false; - for (auto &[key, value] : map) - { - if (!filter(key, value)) - continue; - changed = true; - if constexpr (serialisablePointer) - value->serialise(std::string(key), result); - else - // We use the direct value (with casting) instead of - // value.serialise() to handle the case where the value - // is a raw type (e.g. int) - result[std::string(key)] = value; - } - if (changed) - node[name] = result; - } - // Act over each value in a node table, if the key exists - template static void toMap(const SerialisedValue &node, Lambda action) - { - for (auto &[key, value] : node.as_table()) - action(key, value); - } +void serialiseOnto(const int a, std::string tag, SerialisedValue &target); +void serialiseOnto(const double a, std::string tag, SerialisedValue &target); +void serialiseOnto(const std::string a, std::string tag, SerialisedValue &target); +} // namespace Serialisable - // Act over each value in a node table, if the key exists - template static void toMap(const SerialisedValue &node, std::string key, Lambda action) - { - if (!node.contains(key)) - return; - - for (auto &[subKey, value] : toml::find(node, key)) - action(subKey, value); - } - - // Act over each value in a node array - template static void toVector(const SerialisedValue &node, Lambda action) - { - for (auto &item : node.as_array()) - action(item); - } - - // Act over each value in a node table, if the key exists - template static void toVector(const SerialisedValue &node, std::string key, Lambda action) - { - if (!node.contains(key)) - return; +namespace Deserialisable +{ - toVector(node.at(key), action); - } -}; +void deserialiseOnto(bool &a, const SerialisedValue &target); +void deserialiseOnto(int &a, const SerialisedValue &target); +void deserialiseOnto(long &a, const SerialisedValue &target); +void deserialiseOnto(float &a, const SerialisedValue &target); +void deserialiseOnto(double &a, const SerialisedValue &target); +void deserialiseOnto(std::string &a, const SerialisedValue &target); +} // namespace Deserialisable diff --git a/src/base/serialiserLibrary.h b/src/base/serialiserLibrary.h new file mode 100644 index 0000000000..16f4a57837 --- /dev/null +++ b/src/base/serialiserLibrary.h @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2026 Team Dissolve and contributors + +#pragma once + +#include "base/serialiser.h" +#include "templates/resolvableKeyedVector.h" +#include +#include +#include + +namespace Serialisable +{ + +// We need a way at compile time to detect all the types of smart +// pointers for things that can be serialised +template +concept SerialisablePointer = requires(T a, std::string tag, SerialisedValue target) { a->serialise(tag, target); }; + +template +concept SerialisableClass = requires(T a, std::string tag, SerialisedValue &target) { a.serialise(tag, target); }; + +template void serialiseOnto(const T &a, std::string tag, SerialisedValue &target) +{ + a->serialise(tag, target); +} + +template void serialiseOnto(const T &a, std::string tag, SerialisedValue &target) +{ + a.serialise(tag, target); +} + +template +concept Serialisable = requires(const T a, std::string tag, SerialisedValue &target) { serialiseOnto(a, tag, target); }; + +template SerialisedValue ser(const T &a) +{ + SerialisedValue temp; + serialiseOnto(a, "inner", temp); + return temp["inner"]; +} +// A helper function to add the elements of a map to a node under a name +template void map(const std::map &map, std::string name, SerialisedValue &node) +{ + if (map.empty()) + return; + + SerialisedValue result; + for (auto &[key, value] : map) + serialiseOnto(value, std::format("{}", key), result); + node[name] = result; +} + +// A helper function to add elements of a vector to a node under the named heading +template void fromVectorToTable(const std::vector &vec, std::string name, SerialisedValue &node) +{ + fromVectorToTable(vec, name, node, [](const auto &item) { return item->name().data(); }); +} +// A helper function to add elements of a ResolvableKeyedVector to a node +template +SerialisedValue vector(const ResolvableKeyedVector &keyedVector) +{ + SerialisedValue group; + for (const auto &[resolvable, value] : keyedVector) + group[std::string(resolvable.name())] = value; + return group; +} +template +SerialisedValue vector(const ResolvableKeyedVector &keyedVector, Lambda getInner) +{ + SerialisedValue group; + for (const auto &[resolvable, value] : keyedVector) + group[std::string(resolvable.name())] = getInner(value); + return group; +} +// A helper function to add elements of a vector to a node under the named heading +template +void fromVectorToTable(const std::vector &vec, std::string name, SerialisedValue &node, Lambda getName) +{ + if (vec.empty()) + return; + SerialisedValue group; + for (const auto &value : vec) + serialiseOnto(value, getName(value), group); + node[name] = group; +}; +// A helper function to add elements of a vector to a node. This +// is more generic than fromVectorToTable and the later could be +// be implemented in terms of this function, but the two template +// types conflict with the resolution of other overloads. While +// this could be solved with C++20 Concepts, it's probably better +// to just remove the other overloads. That should be another +// issue before TOML is merged. +template +SerialisedValue fromVectorToMap(const std::vector &vec, Lambda getName, Lambda2 getValue) + requires requires(T x) { std::is_same::value; } +{ + SerialisedValue group; + for (auto &value : vec) + group[getName(value)] = getValue(value); + return group; +}; +// A helper function to add the elements of a vector to a node under a name +template void vector(const std::vector> &vec, std::string name, SerialisedValue &node) +{ + vector(vec, name, node, + [](const auto &item) + { + SerialisedValue outer; + item->serialise("inner", outer); + return outer["inner"]; + }); +} +// A helper function to add the elements of a vector to a node under a name +template void vector(const std::vector> &vec, std::string name, SerialisedValue &node) +{ + vector(vector, name, node, [](const auto &item) { return item->serialise(); }); +} +// A helper function to add the elements of a vector to a node under a name +template void vector(const std::vector &vec, std::string name, SerialisedValue &node) +{ + vector(vec, name, node, + [](const auto &item) + { + SerialisedValue outer; + item.serialise("inner", outer); + return outer["inner"]; + }); +} +// A helper function to add the elements of a vector to a node under a name +template +SerialisedValue vector(const std::vector &vec, Lambda toSerial) + requires(requires(T a) { std::is_same_v; }) +{ + SerialisedValue result = SerialisedValue::array_type{}; + std::transform(vec.begin(), vec.end(), std::back_inserter(result), toSerial); + return result; +} +// A helper function to add the elements of a vector to a node under a name +template +void vector(const std::vector &vec, std::string name, SerialisedValue &node, Lambda toSerial) +{ + if (vec.empty()) + return; + node[name] = vector(vec, toSerial); +} +// A helper function to add the elements of a ranged object to a node under a name +template SerialisedValue fromRange(const Range &range, Lambda toSerial) +{ + SerialisedValue result = SerialisedValue::array_type{}; + std::ranges::transform(range, std::back_inserter(result), toSerial); + return result; +} +// A helper function to add the elements of a map to a node under a name +// Only add values that pass the test lambda +template +void fromMap(const std::map &map, std::string name, SerialisedValue &node, Lambda filter) +{ + SerialisedValue result; + bool changed = false; + for (auto &[key, value] : map) + { + if (!filter(key, value)) + continue; + changed = true; + if constexpr (SerialisablePointer) + value->serialise(std::string(key), result); + else + // We use the direct value (with casting) instead of + // value.serialise() to handle the case where the value + // is a raw type (e.g. int) + result[std::string(key)] = value; + } + if (changed) + node[name] = result; +} + +} // namespace Serialisable + +namespace Deserialisable +{ +template +concept DeserialisibleClass = requires(T a, SerialisedValue &node) { a.deserialise(node); }; + +template void deserialiseOnto(T &a, const SerialisedValue &target) { a.deserialise(target); } + +template +concept Deserialisible = requires(T &a, const SerialisedValue &target) { deserialiseOnto(a, target); }; + +template T deser(const SerialisedValue &target) +{ + T a; + deserialiseOnto(a, target); + return a; +} + +template T deser_or(const SerialisedValue &target, std::string tag, T def) +{ + T a; + if (target.contains(tag)) + { + deserialiseOnto(a, target.at(tag)); + return a; + } + else + return def; +} + +// Perform an action on a child node in a table if the node exists. +// This cuts out quite a bit of boilerplate. +template bool optionalOn(const SerialisedValue &node, std::string name, Lambda action) +{ + if (node.contains(name)) + { + auto child = toml::find(node, name); + if (!node.is_uninitialized()) + action(child); + return true; + } + + return false; +} +// Act over each value in a node table, if the key exists +template void map(const SerialisedValue &node, Lambda action) +{ + for (auto &[key, value] : node.as_table()) + action(key, value); +} + +// Act over each value in a node table, if the key exists +template void map(const SerialisedValue &node, std::string key, Lambda action) +{ + if (!node.contains(key)) + return; + + for (auto &[subKey, value] : toml::find(node, key)) + action(subKey, value); +} + +// Act over each value in a node array +template void vector(const SerialisedValue &node, Lambda action) +{ + for (auto &item : node.as_array()) + action(item); +} + +template std::vector vector(const SerialisedValue &node) +{ + std::vector result; + for (auto &x : node.as_array()) + result.push_back(deser(x)); + return result; +} + +// Act over each value in a node table, if the key exists +template void vector(const SerialisedValue &node, std::string key, Lambda action) +{ + if (!node.contains(key)) + return; + + vector(node.at(key), action); +} + +// Place the named value into the supplied object, but only if it exists +template bool getIfPresent(const SerialisedValue &node, std::string name, U &destination) +{ + if (!node.contains(name)) + return false; + destination = toml::find(node, name); + return true; +} +} // namespace Deserialisable diff --git a/src/classes/atom.cpp b/src/classes/atom.cpp index 91fe3f0ad9..7fc1ee0858 100644 --- a/src/classes/atom.cpp +++ b/src/classes/atom.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/atom.h" +#include "base/serialiserLibrary.h" #include "classes/box.h" /* @@ -135,3 +136,17 @@ AtomBase::AtomGeometry AtomBase::geometry() const // Return whether the geometry of this atom matches that specified bool AtomBase::isGeometry(AtomGeometry geom) const { return geometry() == geom; } + +// Express as a serialisable value +void AtomBase::serialise(std::string tag, SerialisedValue &target) const +{ + target[tag] = {{"index", index_}, {"z", Serialisable::ser(Z_)}, {"r", Serialisable::ser(r_)}, {"q", q_}}; +} +// Read values from a serialisable value +void AtomBase::deserialise(const SerialisedValue &node) +{ + index_ = Deserialisable::deser(node.at("index")); + + set(Deserialisable::deser(node.at("z")), Deserialisable::deser(node.at("r")), + Deserialisable::deser_or(node, "q", 0)); +} diff --git a/src/classes/atom.h b/src/classes/atom.h index 525e14954e..4357241f5e 100644 --- a/src/classes/atom.h +++ b/src/classes/atom.h @@ -86,14 +86,24 @@ class AtomBase AtomGeometry geometry() const; // Return whether the geometry of this atom matches that specified bool isGeometry(AtomGeometry geom) const; + + /* + * Serialisation + */ + public: + // Express as a serialisable value + void serialise(std::string tag, SerialisedValue &target) const; + + // Read values from a serialisable value + void deserialise(const SerialisedValue &node); }; // Atom -template class Atom : public AtomBase, public Serialisable +template class Atom : public AtomBase { public: Atom() = default; - virtual ~Atom() override = default; + virtual ~Atom() = default; /* * Coordinate Manipulation Operators @@ -134,21 +144,4 @@ template class Atom : public AtomBase, public Serialisable connections.emplace_back(bond->partner(this)); return connections; } - - /* - * Serialisation - */ - public: - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override - { - target[tag] = {{"index", index_}, {"z", Z_}, {"r", r_}, {"q", q_}}; - } - // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override - { - index_ = toml::find(node, "index"); - - set(toml::find(node, "z"), toml::find(node, "r"), toml::find_or(node, "q", 0)); - } }; diff --git a/src/classes/atomType.cpp b/src/classes/atomType.cpp index 69ef25584f..f9ca13c26b 100644 --- a/src/classes/atomType.cpp +++ b/src/classes/atomType.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/atomType.h" +#include "base/serialiserLibrary.h" #include "data/elements.h" #include "templates/algorithms.h" #include @@ -87,21 +88,21 @@ void AtomType::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void AtomType::deserialise(SerialisedValue node) { - Z_ = toml::find(node, "z"); - charge_ = toml::find_or(node, "charge", 0.0); - exchangeable_ = toml::find_or(node, "exchangeable", false); + Z_ = Deserialisable::deser(node.at("z")); + charge_ = Deserialisable::deser_or(node, "charge", 0.0); + exchangeable_ = Deserialisable::deser_or(node, "exchangeable", false); - Serialisable::optionalOn( + Deserialisable::optionalOn( node, "form", [this](const auto node) { interactionPotential_.setForm(ShortRangeFunctions::forms().enumeration(std::string(node.as_string()))); }); - Serialisable::optionalOn(node, "parameters", - [this](const auto node) - { - auto ¶meters = ShortRangeFunctions::parameters(interactionPotential_.form()); - std::vector values; - std::transform(parameters.begin(), parameters.end(), std::back_inserter(values), - [&node](const auto parameter) { return node.at(parameter).as_floating(); }); - interactionPotential_.setFormAndParameters(interactionPotential_.form(), values); - }); + Deserialisable::optionalOn(node, "parameters", + [this](const auto node) + { + auto ¶meters = ShortRangeFunctions::parameters(interactionPotential_.form()); + std::vector values; + std::transform(parameters.begin(), parameters.end(), std::back_inserter(values), + [&node](const auto parameter) { return node.at(parameter).as_floating(); }); + interactionPotential_.setFormAndParameters(interactionPotential_.form(), values); + }); } diff --git a/src/classes/atomType.h b/src/classes/atomType.h index c5209c3f1e..37a52e91a1 100644 --- a/src/classes/atomType.h +++ b/src/classes/atomType.h @@ -14,7 +14,7 @@ #include // AtomType Definition -class AtomType : public Serialisable, public std::enable_shared_from_this +class AtomType : public std::enable_shared_from_this { public: AtomType(Elements::Element Z = Elements::Unknown); @@ -72,7 +72,7 @@ class AtomType : public Serialisable, public std::enable_shared_from_this class Bond : public Serialisable +template class Bond { public: Bond(AtomClass *i = nullptr, AtomClass *j = nullptr) : i_(i), j_(j) {} @@ -32,8 +32,5 @@ template class Bond : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override - { - target[tag] = {{"i", i_->index()}, {"j", j_->index()}}; - } + void serialise(std::string tag, SerialisedValue &target) const { target[tag] = {{"i", i_->index()}, {"j", j_->index()}}; } }; diff --git a/src/classes/box.cpp b/src/classes/box.cpp index 38f2ba5da0..260297474e 100644 --- a/src/classes/box.cpp +++ b/src/classes/box.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/box.h" +#include "base/serialiser.h" #include "classes/cell.h" #include "math/mathFunc.h" @@ -275,7 +276,7 @@ void Box::scale(Vector3 scaleFactors) */ // Convert specified fractional coordinates to real-space coordinates -inline void Box::toReal(Vector3 &r) const +void Box::toReal(Vector3 &r) const { switch (type_) { @@ -327,7 +328,7 @@ Vector3 Box::getReal(Vector3 r) const } // Convert specified real-space coordinates to fractional coordinates -inline void Box::toFractional(Vector3 &r) const +void Box::toFractional(Vector3 &r) const { switch (type_) { @@ -566,4 +567,4 @@ void Box::serialise(std::string tag, SerialisedValue &target) const auto &box = target[tag]; box["lengths"] = {a_, b_, c_}; box["angles"] = {alpha_, beta_, gamma_}; -} \ No newline at end of file +} diff --git a/src/classes/box.h b/src/classes/box.h index eaba7a9e2c..e06c9b2258 100644 --- a/src/classes/box.h +++ b/src/classes/box.h @@ -9,7 +9,7 @@ #include "math/vector3.h" // Basic Box Definition -class Box : public Serialisable +class Box { public: // Box Type Enum @@ -156,5 +156,5 @@ class Box : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; }; diff --git a/src/classes/braggReflection.cpp b/src/classes/braggReflection.cpp index 1574dd2835..a1c5cac763 100644 --- a/src/classes/braggReflection.cpp +++ b/src/classes/braggReflection.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/braggReflection.h" +#include "base/serialiserLibrary.h" BraggReflectionVector::BraggReflectionVector(const BraggReflectionVector &other) : reflections_(other.reflections_) {} @@ -32,14 +33,14 @@ const BraggReflection &BraggReflectionVector::operator[](int i) const { return r // Express as a serialisable value void BraggReflectionVector::serialise(std::string tag, SerialisedValue &target) const { - Serialisable::fromVector(reflections_, tag, target); + Serialisable::vector(reflections_, tag, target); } // Read values from a serialisable value void BraggReflectionVector::deserialise(const SerialisedValue &node) { reflections_.clear(); - return Serialisable::toVector(node, + return Deserialisable::vector(node, [&](const auto &value) { auto &reflection = reflections_.emplace_back(); @@ -139,9 +140,9 @@ const Vector3i &BraggReflection::hkl() const { return hkl_; } // Read values from a serialisable value void BraggReflection::deserialise(const SerialisedValue &node) { - index_ = toml::find(node, "index"); - q_ = toml::find(node, "q"); - nKVectors_ = toml::find(node, "nKVectors"); + index_ = Deserialisable::deser(node.at("index")); + q_ = Deserialisable::deser(node.at("q")); + nKVectors_ = Deserialisable::deser(node.at("nKVectors")); hkl_.zero(); hkl_.deserialise(node); } diff --git a/src/classes/braggReflection.h b/src/classes/braggReflection.h index fb46194dc4..706592fb0c 100644 --- a/src/classes/braggReflection.h +++ b/src/classes/braggReflection.h @@ -8,7 +8,7 @@ #include "templates/array2D.h" // BraggReflection Class -class BraggReflection : public Serialisable +class BraggReflection { public: BraggReflection(); @@ -68,13 +68,13 @@ class BraggReflection : public Serialisable */ public: // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; }; // BraggReflectionVector class -class BraggReflectionVector : public Serialisable +class BraggReflectionVector { public: BraggReflectionVector() = default; @@ -101,7 +101,7 @@ class BraggReflectionVector : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/configuration.cpp b/src/classes/configuration.cpp index 0aeea3e9de..460816bbee 100644 --- a/src/classes/configuration.cpp +++ b/src/classes/configuration.cpp @@ -63,7 +63,7 @@ void Configuration::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Configuration::deserialise(const SerialisedValue &node) { - setTemperature(toml::find_or(node, "temperature", defaultTemperature_)); - requestedSizeFactor_ = toml::find_or(node, "sizeFactor", defaultSizeFactor_); - requestedCellDivisionLength_ = toml::find_or(node, "cellDivisionLength", defaultCellDivisionLength_); + setTemperature(Deserialisable::deser_or(node, "temperature", defaultTemperature_)); + requestedSizeFactor_ = Deserialisable::deser_or(node, "sizeFactor", defaultSizeFactor_); + requestedCellDivisionLength_ = Deserialisable::deser_or(node, "cellDivisionLength", defaultCellDivisionLength_); } diff --git a/src/classes/configuration.h b/src/classes/configuration.h index eef064a863..eb5014b188 100644 --- a/src/classes/configuration.h +++ b/src/classes/configuration.h @@ -11,6 +11,7 @@ #include "classes/configurationAtom.h" #include "classes/molecule.h" #include "classes/siteStack.h" +#include "templates/keyedVector.h" #include #include #include @@ -23,7 +24,7 @@ class ProcessPool; class Species; // Configuration -class Configuration : public Serialisable +class Configuration { public: Configuration(); @@ -222,7 +223,7 @@ class Configuration : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/isotopeMix.h b/src/classes/isotopeMix.h index ecdc66a9c9..a77ee6f99e 100644 --- a/src/classes/isotopeMix.h +++ b/src/classes/isotopeMix.h @@ -3,6 +3,7 @@ #pragma once +#include "classes/species.h" #include "data/isotopes.h" #include "templates/keyedVector.h" diff --git a/src/classes/isotopologue.h b/src/classes/isotopologue.h index 24bf78a39b..f9cefa9b7c 100644 --- a/src/classes/isotopologue.h +++ b/src/classes/isotopologue.h @@ -19,7 +19,7 @@ class Species; /* * Isotopologue Definition */ -class Isotopologue : public Serialisable +class Isotopologue { public: Isotopologue(const Species *parent, std::string name = ""); @@ -65,7 +65,7 @@ class Isotopologue : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/isotopologueSet.cpp b/src/classes/isotopologueSet.cpp index 35c1db876a..755013c40e 100644 --- a/src/classes/isotopologueSet.cpp +++ b/src/classes/isotopologueSet.cpp @@ -2,8 +2,8 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/isotopologueSet.h" +#include "base/serialiserLibrary.h" #include "classes/species.h" -#include IsotopologueSet::IsotopologueSet(const std::vector> &topes) { @@ -94,8 +94,9 @@ void IsotopologueSet::serialise(std::string tag, SerialisedValue &target) const return; SerialisedValue value; - value["set"] = fromVectorToTable(isotopologues_, [](const auto &topes) - { return fromVectorToTable(topes, [](const auto isoWeight) { return isoWeight; }); }); + value["set"] = + Serialisable::vector(isotopologues_, [](const auto &topes) + { return Serialisable::vector(topes, [](const auto isoWeight) { return isoWeight; }); }); target[tag] = value; } @@ -104,13 +105,13 @@ void IsotopologueSet::deserialise(const SerialisedValue &node) { clear(); - toMap(node, "set", - [&](const std::string &speciesName, const SerialisedValue &topes) - { - auto &set = isotopologues_[speciesName]; - toMap(topes, [&](const std::string &isoName, const SerialisedValue &population) - { set[isoName] = population.as_floating(); }); - }); + Deserialisable::map(node, "set", + [&](const std::string &speciesName, const SerialisedValue &topes) + { + auto &set = isotopologues_[speciesName]; + Deserialisable::map(topes, [&](const std::string &isoName, const SerialisedValue &population) + { set[isoName] = population.as_floating(); }); + }); } // Resolve internal resolvable name references with supplied data diff --git a/src/classes/isotopologueSet.h b/src/classes/isotopologueSet.h index 68c67d2ed9..5e118567f0 100644 --- a/src/classes/isotopologueSet.h +++ b/src/classes/isotopologueSet.h @@ -4,13 +4,14 @@ #pragma once #include "base/serialiser.h" +#include "templates/resolvableKeyedVector.h" // Forward Declarations class Species; class Isotopologue; // IsotopologueSet - Isotopologues for one or more Species -class IsotopologueSet : public Serialisable, ResolvableContext +class IsotopologueSet : ResolvableContext { public: IsotopologueSet() = default; @@ -50,9 +51,9 @@ class IsotopologueSet : public Serialisable, ResolvableContext */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); // Resolve internal resolvable name references with supplied data void resolve(const std::map &speciesInScope) override; }; diff --git a/src/classes/pairPotential.cpp b/src/classes/pairPotential.cpp index 46882008aa..7787c1af61 100644 --- a/src/classes/pairPotential.cpp +++ b/src/classes/pairPotential.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/pairPotential.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include "classes/atomType.h" #include "math/derivative.h" @@ -480,22 +481,22 @@ void PairPotential::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void PairPotential::deserialise(const SerialisedValue &node) { - nameI_ = toml::find(node, "nameI"); - nameJ_ = toml::find(node, "nameJ"); + nameI_ = Deserialisable::deser(node.at("nameI")); + nameJ_ = Deserialisable::deser(node.at("nameJ")); Functions1D::Form form; - Serialisable::optionalOn(node, "form", - [&](const auto node) { form = Functions1D::forms().enumeration(std::string(node.as_string())); }); + Deserialisable::optionalOn(node, "form", [&](const auto node) + { form = Functions1D::forms().enumeration(std::string(node.as_string())); }); std::vector parameters; - Serialisable::optionalOn(node, "parameters", - [&](const auto node) - { - auto ¶meterNames = Functions1D::parameters(form); - std::transform(parameterNames.begin(), parameterNames.end(), std::back_inserter(parameters), - [&node](const auto parameterName) - { return node.at(parameterName).as_floating(); }); - }); + Deserialisable::optionalOn(node, "parameters", + [&](const auto node) + { + auto ¶meterNames = Functions1D::parameters(form); + std::transform(parameterNames.begin(), parameterNames.end(), std::back_inserter(parameters), + [&node](const auto parameterName) + { return node.at(parameterName).as_floating(); }); + }); setInteractionPotential({form, parameters}); } diff --git a/src/classes/pairPotential.h b/src/classes/pairPotential.h index 28b57e3198..effa3fee72 100644 --- a/src/classes/pairPotential.h +++ b/src/classes/pairPotential.h @@ -13,7 +13,7 @@ class AtomType; // PairPotential Definition -class PairPotential : public Serialisable +class PairPotential { public: PairPotential(std::string_view nameI = {}, std::string_view nameJ = {}); @@ -220,7 +220,7 @@ class PairPotential : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/pairPotentialOverride.cpp b/src/classes/pairPotentialOverride.cpp index a424ab1b5e..b97dcc9f7a 100644 --- a/src/classes/pairPotentialOverride.cpp +++ b/src/classes/pairPotentialOverride.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/pairPotentialOverride.h" +#include "base/serialiserLibrary.h" #include "classes/atomType.h" PairPotentialOverride::PairPotentialOverride() : interactionPotential_(Functions1D::Form::None) {} @@ -72,23 +73,23 @@ void PairPotentialOverride::serialise(std::string tag, SerialisedValue &target) // Read values from a serialisable value void PairPotentialOverride::deserialise(const SerialisedValue &node) { - matchI_ = toml::find(node, "matchI"); - matchJ_ = toml::find(node, "matchJ"); + matchI_ = Deserialisable::deser(node.at("matchI")); + matchJ_ = Deserialisable::deser(node.at("matchJ")); - Serialisable::optionalOn(node, "type", [this](const auto node) - { type_ = pairPotentialOverrideTypes().enumeration(std::string(node.as_string())); }); + Deserialisable::optionalOn(node, "type", [this](const auto node) + { type_ = pairPotentialOverrideTypes().enumeration(std::string(node.as_string())); }); - Serialisable::optionalOn( + Deserialisable::optionalOn( node, "form", [this](const auto node) { interactionPotential_.setForm(Functions1D::forms().enumeration(std::string(node.as_string()))); }); - Serialisable::optionalOn(node, "parameters", - [this](const auto node) - { - auto ¶meters = Functions1D::parameters(interactionPotential_.form()); - std::vector values; - std::transform(parameters.begin(), parameters.end(), std::back_inserter(values), - [&node](const auto parameter) { return node.at(parameter).as_floating(); }); - interactionPotential_.setFormAndParameters(interactionPotential_.form(), values); - }); + Deserialisable::optionalOn(node, "parameters", + [this](const auto node) + { + auto ¶meters = Functions1D::parameters(interactionPotential_.form()); + std::vector values; + std::transform(parameters.begin(), parameters.end(), std::back_inserter(values), + [&node](const auto parameter) { return node.at(parameter).as_floating(); }); + interactionPotential_.setFormAndParameters(interactionPotential_.form(), values); + }); } diff --git a/src/classes/pairPotentialOverride.h b/src/classes/pairPotentialOverride.h index 5041936afd..3eeaa05d00 100644 --- a/src/classes/pairPotentialOverride.h +++ b/src/classes/pairPotentialOverride.h @@ -9,7 +9,7 @@ #include // PairPotential Override Definition -class PairPotentialOverride : public Serialisable +class PairPotentialOverride { public: // Override Types @@ -56,7 +56,7 @@ class PairPotentialOverride : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/partialSet.cpp b/src/classes/partialSet.cpp index 989a431193..fa6017dad7 100644 --- a/src/classes/partialSet.cpp +++ b/src/classes/partialSet.cpp @@ -459,22 +459,22 @@ void PartialSet::serialise(std::string tag, SerialisedValue &target) const { auto &result = target[tag]; - result["realSpeciesPopulations"] = Serialisable::fromVectorToTable(realSpeciesPopulations_); + result["realSpeciesPopulations"] = Serialisable::vector(realSpeciesPopulations_); partials_.serialise("partials", result); boundPartials_.serialise("boundPartials", result); unboundPartials_.serialise("unboundPartials", result); - result["total"] = total_; - result["boundTotal"] = boundTotal_; - result["unboundTotal"] = unboundTotal_; + result["total"] = Serialisable::ser(total_); + result["boundTotal"] = Serialisable::ser(boundTotal_); + result["unboundTotal"] = Serialisable::ser(unboundTotal_); } // Read values from a serialisable value void PartialSet::deserialise(SerialisedValue node) { // Real species populations - Serialisable::toMap(node, "realSpeciesPopulations", [&](const std::string &name, const SerialisedValue &population) + Deserialisable::map(node, "realSpeciesPopulations", [&](const std::string &name, const SerialisedValue &population) { realSpeciesPopulations_[name] = population.as_floating(); }); partials_.deserialise(node["partials"]); diff --git a/src/classes/partialSet.h b/src/classes/partialSet.h index 5cac9541d1..971bff16be 100644 --- a/src/classes/partialSet.h +++ b/src/classes/partialSet.h @@ -10,7 +10,7 @@ #include "templates/resolvable.h" // Set of Partials -class PartialSet : public Serialisable, ResolvableContext +class PartialSet : ResolvableContext { public: PartialSet() = default; @@ -115,7 +115,7 @@ class PartialSet : public Serialisable, ResolvableContext */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value void deserialise(SerialisedValue node); // Resolve internal resolvable name references with supplied data diff --git a/src/classes/potentialSet.h b/src/classes/potentialSet.h index 893685d346..5750efe7e8 100644 --- a/src/classes/potentialSet.h +++ b/src/classes/potentialSet.h @@ -10,7 +10,7 @@ class AtomType; // Set of Potentials -class PotentialSet : public Serialisable +class PotentialSet { public: PotentialSet(); @@ -50,7 +50,7 @@ class PotentialSet : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value void deserialise(SerialisedValue node); }; diff --git a/src/classes/species.cpp b/src/classes/species.cpp index d4b6ed55a9..96ccadb281 100644 --- a/src/classes/species.cpp +++ b/src/classes/species.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/species.h" +#include "base/serialiserLibrary.h" #include "classes/atomType.h" #include "data/ff/ff.h" #include "data/isotopes.h" @@ -179,15 +180,15 @@ void Species::serialise(std::string tag, SerialisedValue &target) const result["name"] = name_; Serialisable::fromVectorToTable(atomTypes_, "atomTypes", result); - Serialisable::fromVector<>(atoms_, "atoms", result); + Serialisable::vector<>(atoms_, "atoms", result); Serialisable::fromVectorToTable<>(commonBonds_, "commonBonds", result); - Serialisable::fromVector<>(bonds_, "bonds", result); + Serialisable::vector<>(bonds_, "bonds", result); Serialisable::fromVectorToTable<>(commonAngles_, "commonAngles", result); - Serialisable::fromVector<>(angles_, "angles", result); + Serialisable::vector<>(angles_, "angles", result); Serialisable::fromVectorToTable<>(commonTorsions_, "commonTorsions", result); - Serialisable::fromVector<>(torsions_, "torsions", result); + Serialisable::vector<>(torsions_, "torsions", result); Serialisable::fromVectorToTable<>(commonImpropers_, "commonImpropers", result); - Serialisable::fromVector<>(impropers_, "impropers", result); + Serialisable::vector<>(impropers_, "impropers", result); Serialisable::fromVectorToTable<>(isotopologues_, "isotopologues", result); Serialisable::fromVectorToTable<>(sites_, "sites", result); } @@ -195,66 +196,69 @@ void Species::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Species::deserialise(const SerialisedValue &node) { - setName(toml::find(node, "name")); + setName(Deserialisable::deser(node.at("name"))); - Serialisable::toMap(node, "atomTypes", [this](const std::string &name, const auto &data) + Deserialisable::map(node, "atomTypes", [this](const std::string &name, const auto &data) { atomTypes_.emplace_back(std::make_shared(name))->deserialise(data); }); - Serialisable::toVector(node, "atoms", [this](const SerialisedValue &atom) { atoms_.emplace_back(this).deserialise(atom); }); + Deserialisable::vector(node, "atoms", [this](const SerialisedValue &atom) { atoms_.emplace_back(this).deserialise(atom); }); - Serialisable::toMap(node, "commonBonds", [this](const std::string &name, const SerialisedValue &bond) + Deserialisable::map(node, "commonBonds", [this](const std::string &name, const SerialisedValue &bond) { commonBonds_.emplace_back(std::make_unique(name))->deserialise(bond); }); - Serialisable::toVector( - node, "bonds", - [this](const SerialisedValue &bond) - { - bonds_.emplace_back(this, &atoms_.at(toml::find(bond, "i")), &atoms_.at(toml::find(bond, "j"))) - .deserialise(bond); - }); + Deserialisable::vector(node, "bonds", + [this](const SerialisedValue &bond) + { + bonds_ + .emplace_back(this, &atoms_.at(Deserialisable::deser(bond.at("i"))), + &atoms_.at(Deserialisable::deser(bond.at("j")))) + .deserialise(bond); + }); - Serialisable::toMap(node, "commonAngles", [this](const std::string &name, const SerialisedValue &bond) + Deserialisable::map(node, "commonAngles", [this](const std::string &name, const SerialisedValue &bond) { commonAngles_.emplace_back(std::make_unique(name))->deserialise(bond); }); - Serialisable::toVector(node, "angles", + Deserialisable::vector(node, "angles", [this](const SerialisedValue &angle) { angles_ - .emplace_back(this, &atoms_.at(toml::find(angle, "i")), - &atoms_.at(toml::find(angle, "j")), - &atoms_.at(toml::find(angle, "k"))) + .emplace_back(this, &atoms_.at(Deserialisable::deser(angle.at("i"))), + &atoms_.at(Deserialisable::deser(angle.at("j"))), + &atoms_.at(Deserialisable::deser(angle.at("k")))) .deserialise(angle); }); - Serialisable::toMap(node, "commonImpropers", [this](const std::string &name, const SerialisedValue &bond) + Deserialisable::map(node, "commonImpropers", [this](const std::string &name, const SerialisedValue &bond) { commonImpropers_.emplace_back(std::make_unique(name))->deserialise(bond); }); - Serialisable::toVector( - node, "impropers", - [this](const SerialisedValue &improper) - { - impropers_ - .emplace_back(this, &atoms_.at(toml::find(improper, "i")), &atoms_.at(toml::find(improper, "j")), - &atoms_.at(toml::find(improper, "k")), &atoms_.at(toml::find(improper, "l"))) - .deserialise(improper); - }); + Deserialisable::vector(node, "impropers", + [this](const SerialisedValue &improper) + { + impropers_ + .emplace_back(this, &atoms_.at(Deserialisable::deser(improper.at("i"))), + &atoms_.at(Deserialisable::deser(improper.at("j"))), + &atoms_.at(Deserialisable::deser(improper.at("k"))), + &atoms_.at(Deserialisable::deser(improper.at("l")))) + .deserialise(improper); + }); - Serialisable::toMap(node, "commonTorsions", [this](const std::string &name, const SerialisedValue &bond) + Deserialisable::map(node, "commonTorsions", [this](const std::string &name, const SerialisedValue &bond) { commonTorsions_.emplace_back(std::make_unique(name))->deserialise(bond); }); - Serialisable::toVector( - node, "torsions", - [this](const SerialisedValue &torsion) - { - torsions_ - .emplace_back(this, &atoms_.at(toml::find(torsion, "i")), &atoms_.at(toml::find(torsion, "j")), - &atoms_.at(toml::find(torsion, "k")), &atoms_.at(toml::find(torsion, "l"))) - .deserialise(torsion); - }); + Deserialisable::vector(node, "torsions", + [this](const SerialisedValue &torsion) + { + torsions_ + .emplace_back(this, &atoms_.at(Deserialisable::deser(torsion.at("i"))), + &atoms_.at(Deserialisable::deser(torsion.at("j"))), + &atoms_.at(Deserialisable::deser(torsion.at("k"))), + &atoms_.at(Deserialisable::deser(torsion.at("l")))) + .deserialise(torsion); + }); - Serialisable::toMap(node, "isotopologues", [this](const std::string &name, const SerialisedValue &iso) + Deserialisable::map(node, "isotopologues", [this](const std::string &name, const SerialisedValue &iso) { isotopologues_.emplace_back(std::make_unique(this, name))->deserialise(iso); }); // We must finalise the intramolecular data before we attempt to add sites as Fragment sites need the bond connectivity finaliseIntramolecularData(false); - Serialisable::toMap(node, "sites", [this](const std::string &name, const SerialisedValue &site) + Deserialisable::map(node, "sites", [this](const std::string &name, const SerialisedValue &site) { sites_.emplace_back(std::make_unique(this, name))->deserialise(site); }); // Always update type indexing after deserialisation diff --git a/src/classes/species.h b/src/classes/species.h index 0996ef6db5..4c2d66fca1 100644 --- a/src/classes/species.h +++ b/src/classes/species.h @@ -24,7 +24,7 @@ class CommonImproper; class Structure; // Species Definition -class Species : public Serialisable +class Species { public: Species(std::string name = "Unnamed"); @@ -309,7 +309,7 @@ class Species : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/speciesAngle.h b/src/classes/speciesAngle.h index 3846514884..ca40fe0548 100644 --- a/src/classes/speciesAngle.h +++ b/src/classes/speciesAngle.h @@ -57,9 +57,9 @@ class SpeciesAngle : public SpeciesIntra */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; // CommonAngle Definition diff --git a/src/classes/speciesAtom.cpp b/src/classes/speciesAtom.cpp index 516b1341ac..951c353762 100644 --- a/src/classes/speciesAtom.cpp +++ b/src/classes/speciesAtom.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/speciesAtom.h" +#include "base/serialiserLibrary.h" #include "classes/atomType.h" #include "classes/box.h" #include "classes/species.h" @@ -167,24 +168,25 @@ SpeciesAtom::ScaledInteractionDefinition SpeciesAtom::scaling(const SpeciesAtom // Express as a serialisable value void SpeciesAtom::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"index", index_}, {"z", Z_}, {"r", r_}, {"q", q_}}; + target[tag] = {{"index", index_}, {"z", Serialisable::ser(Z_)}, {"r", Serialisable::ser(r_)}, {"q", q_}}; if (atomType_) target[tag]["type"] = atomType_->name().data(); } void SpeciesAtom::deserialise(const SerialisedValue &node) { - index_ = toml::find(node, "index"); - - set(toml::find(node, "z"), toml::find(node, "r"), toml::find_or(node, "q", 0)); - - Serialisable::optionalOn(node, "type", - [&](const auto innerNode) - { - if (Z_ == Elements::Unknown) - return; - std::string name = toml::get(innerNode); - atomType_ = parent_->findAtomType(name); - if (atomType_ == nullptr) - atomType_ = parent_->addAtomType(Z_, name); - }); + index_ = Deserialisable::deser(node.at("index")); + + set(Deserialisable::deser(node.at("z")), Deserialisable::deser(node.at("r")), + Deserialisable::deser_or(node, "q", 0)); + + Deserialisable::optionalOn(node, "type", + [&](const auto innerNode) + { + if (Z_ == Elements::Unknown) + return; + std::string name = Deserialisable::deser(innerNode); + atomType_ = parent_->findAtomType(name); + if (atomType_ == nullptr) + atomType_ = parent_->addAtomType(Z_, name); + }); } diff --git a/src/classes/speciesAtom.h b/src/classes/speciesAtom.h index a8cdc4efac..fbbe92d6db 100644 --- a/src/classes/speciesAtom.h +++ b/src/classes/speciesAtom.h @@ -13,6 +13,7 @@ // Forward Declarations class AtomType; +class Species; class SpeciesAngle; class SpeciesBond; class SpeciesImproper; @@ -87,7 +88,7 @@ class SpeciesAtom : public Atom */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/classes/speciesBond.h b/src/classes/speciesBond.h index 5e6461072d..72f2b2085e 100644 --- a/src/classes/speciesBond.h +++ b/src/classes/speciesBond.h @@ -44,9 +44,9 @@ class SpeciesBond : public Bond, public SpeciesIntra */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; // CommonImproper Definition diff --git a/src/classes/speciesIntra.h b/src/classes/speciesIntra.h index 5e1388ddb2..c20fadcec0 100644 --- a/src/classes/speciesIntra.h +++ b/src/classes/speciesIntra.h @@ -14,7 +14,7 @@ class Species; // Base class for intramolecular interactions within Species -template class SpeciesIntra : public Serialisable +template class SpeciesIntra { public: explicit SpeciesIntra(Species *parent, typename Functions::Form form) : parent_(parent), interactionPotential_(form) {}; @@ -162,7 +162,7 @@ template class SpeciesIntra : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override + void serialise(std::string tag, SerialisedValue &target) const { auto &result = target[tag]; @@ -191,46 +191,45 @@ template class SpeciesIntra : public Serialisable { // Common tag - used by individual species terms (not the common terms themselves) to specify a reference to a common // term. If it doesn't exist, serialise form and parameters as normal. - if (!Serialisable::optionalOn(node, "common", - [this, &lambda](const SerialisedValue &node) - { - std::string form = node.as_string(); - auto common = lambda(form); - if (!common) - throw std::runtime_error("Common Term not found."); - setCommonTerm(&common->get()); - })) + if (node.contains("common")) + { + std::string cmmn = node.at("common").as_string(); + auto common = lambda(cmmn); + if (!common) + throw std::runtime_error("Common Term not found."); + setCommonTerm(&common->get()); + } + else SpeciesIntra::deserialise(node); } // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override + void deserialise(const SerialisedValue &node) { - Serialisable::optionalOn(node, "form", - [this](const SerialisedValue &node) - { - std::string form = node.as_string(); - setInteractionForm(Functions::forms().enumeration(form)); - }); - Serialisable::optionalOn(node, "parameters", - [this](const auto node) - { - auto names = Functions::parameters(interactionForm()); - std::vector values; - std::map map; - switch (node.type()) - { - case toml::value_t::array: - values = toml::get>(node); - break; - case toml::value_t::table: - map = toml::get>(node); - std::transform(names.begin(), names.end(), std::back_inserter(values), - [&map](const auto &name) { return map[name]; }); - break; - default: - throw toml::type_error("Cannot understand parameter value", node.location()); - } - setInteractionFormAndParameters(interactionForm(), values); - }); + if (node.contains("form")) + { + std::string form = node.at("form").as_string(); + setInteractionForm(Functions::forms().enumeration(form)); + } + if (node.contains("parameters")) + { + auto params = node.at("parameters"); + auto names = Functions::parameters(interactionForm()); + std::vector values; + std::map map; + switch (params.type()) + { + case toml::value_t::array: + values = toml::get>(params); + break; + case toml::value_t::table: + map = toml::get>(params); + std::transform(names.begin(), names.end(), std::back_inserter(values), + [&map](const auto &name) { return map[name]; }); + break; + default: + throw toml::type_error("Cannot understand parameter value", params.location()); + } + setInteractionFormAndParameters(interactionForm(), values); + } } }; diff --git a/src/classes/speciesSite.cpp b/src/classes/speciesSite.cpp index 5911ad76a1..a568d69dd5 100644 --- a/src/classes/speciesSite.cpp +++ b/src/classes/speciesSite.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/speciesSite.h" +#include "base/serialiserLibrary.h" #include "classes/site.h" #include "classes/species.h" #include "data/atomicMasses.h" @@ -519,12 +520,11 @@ void SpeciesSite::serialise(std::string tag, SerialisedValue &target) const site["description"] = fragment_.definitionString(); break; case SiteType::Static: - Serialisable::fromVector(staticOriginAtoms_, "originAtoms", site, [](const auto &item) { return item->index(); }); - Serialisable::fromVector(staticXAxisAtoms_, "xAxisAtoms", site, [](const auto &item) { return item->index(); }); - Serialisable::fromVector(staticYAxisAtoms_, "yAxisAtoms", site, [](const auto &item) { return item->index(); }); - Serialisable::fromVector(dynamicElements_, "elements", site, - [](const auto &item) { return Elements::symbol(item); }); - Serialisable::fromVector(dynamicAtomTypes_, "atomTypes", site, [](const auto &item) { return item->name(); }); + Serialisable::vector(staticOriginAtoms_, "originAtoms", site, [](const auto &item) { return item->index(); }); + Serialisable::vector(staticXAxisAtoms_, "xAxisAtoms", site, [](const auto &item) { return item->index(); }); + Serialisable::vector(staticYAxisAtoms_, "yAxisAtoms", site, [](const auto &item) { return item->index(); }); + Serialisable::vector(dynamicElements_, "elements", site, [](const auto &item) { return Elements::symbol(item); }); + Serialisable::vector(dynamicAtomTypes_, "atomTypes", site, [](const auto &item) { return item->name(); }); break; } } @@ -532,30 +532,33 @@ void SpeciesSite::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void SpeciesSite::deserialise(const SerialisedValue &node) { - type_ = siteTypes().deserialise(toml::find_or(node, "type", "static")); + type_ = siteTypes().deserialise(Deserialisable::deser_or(node, "type", std::string("static"))); switch (type_) { case SiteType::Static: - toVector(node, "originAtoms", [this](const auto &originAtom) { addStaticOriginAtom(originAtom.as_integer()); }); - toVector(node, "xAxisAtoms", [this](const auto &xAxisAtom) { addStaticXAxisAtom(xAxisAtom.as_integer()); }); - toVector(node, "yAxisAtoms", [this](const auto &yAxisAtom) { addStaticYAxisAtom(yAxisAtom.as_integer()); }); - toVector(node, "elements", - [this](const auto &el) { addDynamicElement(Elements::element(std::string(el.as_string()))); }); - toVector(node, "atomTypes", - [&, this](const auto &at) { addDynamicAtomType(parent_->findAtomType(std::string(at.as_string()))); }); + Deserialisable::vector(node, "originAtoms", + [this](const auto &originAtom) { addStaticOriginAtom(originAtom.as_integer()); }); + Deserialisable::vector(node, "xAxisAtoms", + [this](const auto &xAxisAtom) { addStaticXAxisAtom(xAxisAtom.as_integer()); }); + Deserialisable::vector(node, "yAxisAtoms", + [this](const auto &yAxisAtom) { addStaticYAxisAtom(yAxisAtom.as_integer()); }); + Deserialisable::vector(node, "elements", [this](const auto &el) + { addDynamicElement(Elements::element(std::string(el.as_string()))); }); + Deserialisable::vector(node, "atomTypes", [&, this](const auto &at) + { addDynamicAtomType(parent_->findAtomType(std::string(at.as_string()))); }); break; case SiteType::Fragment: - fragment_.create(toml::find(node, "description")); + fragment_.create(Deserialisable::deser(node.at("description"))); break; case SiteType::Dynamic: - toVector(node, "element", - [this](const auto &element) { addDynamicElement(toml::get(element)); }); + Deserialisable::vector(node, "element", [this](const auto &element) + { addDynamicElement(Deserialisable::deser(element)); }); break; } - originMassWeighted_ = toml::find_or(node, "originMassWeighted", false); + originMassWeighted_ = Deserialisable::deser_or(node, "originMassWeighted", false); generateInstances(); } diff --git a/src/classes/speciesSite.h b/src/classes/speciesSite.h index 81426f66c0..06f35e8117 100644 --- a/src/classes/speciesSite.h +++ b/src/classes/speciesSite.h @@ -21,7 +21,7 @@ class Species; class SpeciesAtom; // Species Site Definition -class SpeciesSite : public Serialisable +class SpeciesSite { public: // Site Type @@ -184,9 +184,9 @@ class SpeciesSite : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; template <> struct Context diff --git a/src/classes/speciesSites.cpp b/src/classes/speciesSites.cpp index 005507bf37..767c9fbda0 100644 --- a/src/classes/speciesSites.cpp +++ b/src/classes/speciesSites.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/speciesSites.h" +#include "base/serialiserLibrary.h" #include "classes/species.h" SpeciesSites::SpeciesSites(const std::vector &sites) @@ -71,8 +72,8 @@ void SpeciesSites::serialise(std::string tag, SerialisedValue &target) const return; SerialisedValue value; - value["sites"] = fromVectorToTable(sites_, [](const auto &sites) - { return fromVectorToTable(sites, [](const auto isoWeight) { return isoWeight; }); }); + value["sites"] = Serialisable::vector( + sites_, [](const auto &sites) { return Serialisable::vector(sites, [](const auto isoWeight) { return isoWeight; }); }); target[tag] = value; } @@ -81,13 +82,13 @@ void SpeciesSites::deserialise(const SerialisedValue &node) { clear(); - toMap(node, "set", - [&](const std::string &speciesName, const SerialisedValue &sites) - { - auto &set = sites_[speciesName]; - toMap(sites, [&](const std::string &siteName, const SerialisedValue &population) - { set[siteName] = population.as_floating(); }); - }); + Deserialisable::map(node, "set", + [&](const std::string &speciesName, const SerialisedValue &sites) + { + auto &set = sites_[speciesName]; + Deserialisable::map(sites, [&](const std::string &siteName, const SerialisedValue &population) + { set[siteName] = population.as_floating(); }); + }); } // Resolve internal resolvable name references with supplied data diff --git a/src/classes/speciesSites.h b/src/classes/speciesSites.h index d5fe075ce3..45c0585631 100644 --- a/src/classes/speciesSites.h +++ b/src/classes/speciesSites.h @@ -4,13 +4,15 @@ #pragma once #include "base/serialiser.h" +#include "templates/resolvable.h" +#include "templates/resolvableKeyedVector.h" // Forward Declarations class SpeciesSite; class Species; // SpeciesSites - Sites from one or more Species -class SpeciesSites : public Serialisable, ResolvableContext +class SpeciesSites : ResolvableContext { public: SpeciesSites() = default; @@ -42,9 +44,9 @@ class SpeciesSites : public Serialisable, ResolvableContext */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); // Resolve internal resolvable name references with supplied data void resolve(const std::map &speciesInScope) override; }; diff --git a/src/classes/speciesTorsion.cpp b/src/classes/speciesTorsion.cpp index ff35c37cb8..933f5ed4fe 100644 --- a/src/classes/speciesTorsion.cpp +++ b/src/classes/speciesTorsion.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/speciesTorsion.h" +#include "base/serialiserLibrary.h" #include "classes/species.h" #include "classes/speciesAtom.h" #include "math/mathFunc.h" @@ -399,7 +400,7 @@ void SpeciesTorsion::deserialise(const SerialisedValue &node) SpeciesIntra::deserialise(node, [&](auto &form) { return parent_->getCommonTorsion(form); }); - electrostatic14Scaling_ = toml::find_or(node, "q14", 0.5); + electrostatic14Scaling_ = Deserialisable::deser_or(node, "q14", 0.5); - Serialisable::optionalOn(node, "v14", [this](const auto node) { vdw14Scaling_ = node.as_floating(); }); + Deserialisable::optionalOn(node, "v14", [this](const auto node) { vdw14Scaling_ = node.as_floating(); }); } diff --git a/src/classes/speciesTorsion.h b/src/classes/speciesTorsion.h index 4622e5be9a..a6a18d5360 100644 --- a/src/classes/speciesTorsion.h +++ b/src/classes/speciesTorsion.h @@ -79,9 +79,9 @@ class SpeciesTorsion : public SpeciesIntra */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; // CommonTorsion Definition diff --git a/src/classes/structure.cpp b/src/classes/structure.cpp index 4253ab307c..f64564d103 100644 --- a/src/classes/structure.cpp +++ b/src/classes/structure.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/structure.h" +#include "base/serialiserLibrary.h" #include "classes/bond.h" #include "classes/species.h" #include "templates/algorithms.h" @@ -308,20 +309,20 @@ void Structure::unFold() void Structure::serialise(std::string tag, SerialisedValue &target) const { auto &result = target[tag]; - Serialisable::fromVector<>(atoms_, "atoms", result); - Serialisable::fromVector<>(bonds_, "bonds", result); + Serialisable::vector<>(atoms_, "atoms", result); + Serialisable::vector<>(bonds_, "bonds", result); } // Read values from a serialisable value void Structure::deserialise(const SerialisedValue &node) { - Serialisable::toVector(node, "atoms", [this](const SerialisedValue &atom) { atoms_.emplace_back()->deserialise(atom); }); + Deserialisable::vector(node, "atoms", [this](const SerialisedValue &atom) { atoms_.emplace_back()->deserialise(atom); }); - Serialisable::toVector(node, "bonds", + Deserialisable::vector(node, "bonds", [this](const SerialisedValue &bond) { - auto &i = atoms_.at(toml::find(bond, "i")); - auto &j = atoms_.at(toml::find(bond, "j")); + auto &i = atoms_.at(Deserialisable::deser(bond.at("i"))); + auto &j = atoms_.at(Deserialisable::deser(bond.at("j"))); bonds_.emplace_back(std::make_unique>(i.get(), j.get())); }); } diff --git a/src/classes/structure.h b/src/classes/structure.h index 71a2c0f0f2..b59efb38d2 100644 --- a/src/classes/structure.h +++ b/src/classes/structure.h @@ -36,7 +36,7 @@ class StructureAtom : public Atom> }; // Structure -class Structure : public Serialisable +class Structure { public: Structure() = default; @@ -140,7 +140,7 @@ class Structure : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/data/elements.cpp b/src/data/elements.cpp index b3beb0acfa..0875681698 100644 --- a/src/data/elements.cpp +++ b/src/data/elements.cpp @@ -3,6 +3,7 @@ #include "data/elements.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include #include @@ -230,3 +231,20 @@ bool isMetallic(Element Z) } } // namespace Elements + +// TOML Conversion +namespace Serialisable +{ +void serialiseOnto(const Elements::Element &elem, std::string tag, SerialisedValue node) +{ + node[tag] = Elements::symbol(elem).data(); +} +}; // namespace Serialisable + +namespace Deserialisable +{ +void deserialiseOnto(Elements::Element &elem, const SerialisedValue &node) +{ + elem = Elements::element(Deserialisable::deser(node)); +} +}; // namespace Deserialisable diff --git a/src/data/elements.h b/src/data/elements.h index 14f7006583..0acd9d54d3 100644 --- a/src/data/elements.h +++ b/src/data/elements.h @@ -180,18 +180,12 @@ bool isMetallic(Element Z); }; // namespace Elements // TOML Conversion -namespace toml +namespace Serialisable { -template <> struct from -{ - static Elements::Element from_toml(const toml::value &node) { return Elements::element(toml::get(node)); } -}; +void serialiseOnto(const Elements::Element &elem, std::string tag, SerialisedValue node); +}; // namespace Serialisable -template <> struct into +namespace Deserialisable { - static toml::basic_value into_toml(const Elements::Element &e) - { - return Elements::symbol(e).data(); - } -}; -} // namespace toml +void deserialiseOnto(Elements::Element &elem, const SerialisedValue &node); +}; // namespace Deserialisable diff --git a/src/expression/value.h b/src/expression/value.h index 954b168c5f..e957222268 100644 --- a/src/expression/value.h +++ b/src/expression/value.h @@ -7,7 +7,7 @@ #include // Expression Value -class ExpressionValue : public Serialisable +class ExpressionValue { public: ExpressionValue(); @@ -67,7 +67,7 @@ class ExpressionValue : public Serialisable // Return the supplied ExpressionValues both contain double types static bool bothDoubles(const ExpressionValue &a, const ExpressionValue &b); // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/expression/variable.cpp b/src/expression/variable.cpp index d82cde6ed9..54ded9de26 100644 --- a/src/expression/variable.cpp +++ b/src/expression/variable.cpp @@ -3,6 +3,7 @@ #include "expression/variable.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include ExpressionVariable::ExpressionVariable(const ExpressionValue &value) @@ -61,12 +62,12 @@ ExpressionValue *ExpressionVariable::valuePointer() { return &value_; } // Express as a serialisable value void ExpressionVariable::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"name", baseName_}, {"value", value_}}; + target[tag] = {{"name", Serialisable::ser(baseName_)}, {"value", Serialisable::ser(value_)}}; } // Read values from a serialisable value void ExpressionVariable::deserialise(const SerialisedValue &node) { - value_ = toml::find(node, "value"); - setBaseName(toml::find(node, "name")); + value_ = Deserialisable::deser(node.at("value")); + setBaseName(Deserialisable::deser(node.at("name"))); } diff --git a/src/expression/variable.h b/src/expression/variable.h index c9e35cad5d..8c5c415bd6 100644 --- a/src/expression/variable.h +++ b/src/expression/variable.h @@ -6,7 +6,7 @@ #include "expression/value.h" // Variable -class ExpressionVariable : public Serialisable +class ExpressionVariable { public: ExpressionVariable(const ExpressionValue &value = ExpressionValue()); @@ -46,7 +46,7 @@ class ExpressionVariable : public Serialisable // Return pointer to value ExpressionValue *valuePointer(); // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/main.cpp b/src/main.cpp index a9bf9b711f..6748c84d3d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,7 +60,7 @@ int main(int args, char **argv) Messenger::print("Saving input file to '{}'...\n", filename.string()); bool result; - auto toml = dissolve.into_toml(); + auto toml = Serialisable::ser(&dissolve); std::ofstream outfile; outfile.open(options.writeInputFilename().value()); outfile << toml; diff --git a/src/main/dissolve.h b/src/main/dissolve.h index 19285823f0..1c90770f25 100644 --- a/src/main/dissolve.h +++ b/src/main/dissolve.h @@ -18,7 +18,7 @@ class Isotopologue; class Molecule; // Dissolve Main Class -class Dissolve : public Serialisable +class Dissolve { public: Dissolve(); @@ -119,13 +119,13 @@ class Dissolve : public Serialisable // Read pair potentials from a serialisable value void deserialisePairPotentials(const SerialisedValue &node); // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); // Save TOML file bool saveToml(std::string_view filename) const; // Express pair potentials as a serialisable value SerialisedValue serialisePairPotentials() const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Return whether an input filename has been set bool hasInputFilename() const; // Set current input filename diff --git a/src/main/io.cpp b/src/main/io.cpp index dd6ef107c1..f69538fb97 100644 --- a/src/main/io.cpp +++ b/src/main/io.cpp @@ -11,7 +11,6 @@ #include "main/version.h" #include "nodes/dissolve.h" #include -#include // Serialise pair potential SerialisedValue Dissolve::serialisePairPotentials() const @@ -26,17 +25,17 @@ SerialisedValue Dissolve::serialisePairPotentials() const if (!useCombinationRules_) { pairPotentials["useCombinationRules"] = false; - Serialisable::fromVector(pairPotentials_, "potentials", pairPotentials, - [](const auto &term) - { - const auto &[at1, at2, pot] = term; - SerialisedValue target; - pot->serialise("inner", target); - auto &value = target["inner"]; - value["atomTypeI"] = at1->name(); - value["atomTypeJ"] = at2->name(); - return value; - }); + Serialisable::vector(pairPotentials_, "potentials", pairPotentials, + [](const auto &term) + { + const auto &[at1, at2, pot] = term; + SerialisedValue target; + pot->serialise("inner", target); + auto &value = target["inner"]; + value["atomTypeI"] = at1->name(); + value["atomTypeJ"] = at2->name(); + return value; + }); } return pairPotentials; } @@ -92,9 +91,9 @@ void Dissolve::deserialise(const SerialisedValue &originalNode) Messenger::warn("File does not contain version information. Assuming the current version: {}", Version::semantic()); const SerialisedValue node = hasVersion ? dissolve::backwardsUpgrade(originalNode) : originalNode; - Serialisable::optionalOn(node, "graph", [this](const auto node) { graphNode_->deserialise(node); }); + Deserialisable::optionalOn(node, "graph", [this](const auto node) { graphNode_->deserialise(node); }); - Serialisable::optionalOn(node, "pairPotentials", [this](const auto node) { deserialisePairPotentials(node); }); + Deserialisable::optionalOn(node, "pairPotentials", [this](const auto node) { deserialisePairPotentials(node); }); } // Load input from supplied file @@ -156,7 +155,7 @@ bool Dissolve::saveToml(std::string_view filename) const { std::ofstream outfile; outfile.open(std::string(filename)); - outfile << into_toml() << std::endl; + outfile << Serialisable::ser(*this) << std::endl; outfile.close(); return true; } diff --git a/src/math/data1D.cpp b/src/math/data1D.cpp index b8c27d72bd..a135f067b4 100644 --- a/src/math/data1D.cpp +++ b/src/math/data1D.cpp @@ -3,6 +3,7 @@ #include "math/data1D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include "templates/algorithms.h" #include @@ -427,14 +428,14 @@ void Data1D::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Data1D::deserialise(const SerialisedValue &node) { - tag_ = toml::find(node, "tag"); - x_ = toml::find>(node, "x"); - values_ = toml::find>(node, "y"); + tag_ = Deserialisable::deser(node.at("tag")); + x_ = Deserialisable::vector(node.at("x")); + values_ = Deserialisable::vector(node.at("y")); - Serialisable::optionalOn(node, "errors", - [this](const auto errors) - { - hasError_ = true; - errors_ = toml::get>(errors); - }); + Deserialisable::optionalOn(node, "errors", + [this](const auto errors) + { + hasError_ = true; + errors_ = Deserialisable::vector(errors); + }); } diff --git a/src/math/data1D.h b/src/math/data1D.h index 1ec9036baf..d1dd59f480 100644 --- a/src/math/data1D.h +++ b/src/math/data1D.h @@ -9,7 +9,7 @@ #include // One-Dimensional Data -class Data1D : public Data1DBase, public Serialisable +class Data1D : public Data1DBase { public: Data1D(); @@ -114,7 +114,7 @@ class Data1D : public Data1DBase, public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/data2D.cpp b/src/math/data2D.cpp index 52350363d1..b0e96c9d24 100644 --- a/src/math/data2D.cpp +++ b/src/math/data2D.cpp @@ -3,6 +3,7 @@ #include "math/data2D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include "math/data1D.h" #include "math/histogram2D.h" @@ -330,17 +331,17 @@ void Data2D::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Data2D::deserialise(const SerialisedValue &node) { - tag_ = toml::find(node, "tag"); - x_ = toml::find>(node, "x"); - y_ = toml::find>(node, "y"); + tag_ = Deserialisable::deser(node.at("tag")); + x_ = Deserialisable::vector(node.at("x")); + y_ = Deserialisable::vector(node.at("y")); values_.initialise(x_.size(), y_.size()); - values_.linearArray() = toml::find>(node, "values"); - - Serialisable::optionalOn(node, "errors", - [this](const auto errors) - { - hasError_ = true; - errors_.initialise(x_.size(), y_.size()); - errors_.linearArray() = toml::get>(errors); - }); + values_.linearArray() = Deserialisable::vector(node.at("values")); + + Deserialisable::optionalOn(node, "errors", + [this](const auto errors) + { + hasError_ = true; + errors_.initialise(x_.size(), y_.size()); + errors_.linearArray() = Deserialisable::vector(errors); + }); } diff --git a/src/math/data2D.h b/src/math/data2D.h index 12a157df9f..c74c28696f 100644 --- a/src/math/data2D.h +++ b/src/math/data2D.h @@ -12,7 +12,7 @@ class Histogram2D; // One-Dimensional Data -class Data2D : public Data2DBase, public Serialisable +class Data2D : public Data2DBase { public: Data2D(); @@ -109,7 +109,7 @@ class Data2D : public Data2DBase, public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/data3D.cpp b/src/math/data3D.cpp index 763af68ddb..4dd725d38d 100644 --- a/src/math/data3D.cpp +++ b/src/math/data3D.cpp @@ -3,6 +3,7 @@ #include "math/data3D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include "math/histogram3D.h" #include "templates/array3D.h" @@ -339,18 +340,18 @@ void Data3D::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Data3D::deserialise(const SerialisedValue &node) { - tag_ = toml::find(node, "tag"); - x_ = toml::find>(node, "x"); - y_ = toml::find>(node, "y"); - z_ = toml::find>(node, "z"); + tag_ = Deserialisable::deser(node.at("tag")); + x_ = Deserialisable::vector(node.at("x")); + y_ = Deserialisable::vector(node.at("y")); + z_ = Deserialisable::vector(node.at("z")); values_.initialise(x_.size(), y_.size(), z_.size()); - values_.linearArray() = toml::find>(node, "values"); - - Serialisable::optionalOn(node, "errors", - [this](const auto errors) - { - hasError_ = true; - errors_.initialise(x_.size(), y_.size(), z_.size()); - errors_.linearArray() = toml::get>(errors); - }); + values_.linearArray() = Deserialisable::vector(node.at("values")); + + Deserialisable::optionalOn(node, "errors", + [this](const auto errors) + { + hasError_ = true; + errors_.initialise(x_.size(), y_.size(), z_.size()); + errors_.linearArray() = Deserialisable::vector(errors); + }); } diff --git a/src/math/data3D.h b/src/math/data3D.h index 729efc8252..893b8d6a51 100644 --- a/src/math/data3D.h +++ b/src/math/data3D.h @@ -11,7 +11,7 @@ class Histogram3D; // One-Dimensional Data -class Data3D : public Data3DBase, public Serialisable +class Data3D : public Data3DBase { public: Data3D(); @@ -119,7 +119,7 @@ class Data3D : public Data3DBase, public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/function1D.cpp b/src/math/function1D.cpp index 7a94e248cd..64098a51b3 100644 --- a/src/math/function1D.cpp +++ b/src/math/function1D.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "math/function1D.h" +#include "base/serialiserLibrary.h" #include "classes/pairPotential.h" #include "math/mathFunc.h" #include "templates/algorithms.h" @@ -584,7 +585,7 @@ void Function1DWrapper::serialise(std::string tag, SerialisedValue &target) cons result["form"] = Functions1D::forms().keywordByIndex(static_cast(form_)); - Serialisable::fromVector(parameters_, "parameters", result, [](const auto &x) { return x; }); + Serialisable::vector(parameters_, "parameters", result, [](const auto &x) { return x; }); } // Read values from a serialisable value @@ -593,5 +594,6 @@ void Function1DWrapper::deserialise(const SerialisedValue &node) Functions1D::Form proxy; form_ = getEnumOptions(proxy).deserialise(node); - Serialisable::toVector(node, "parameters", [this](const auto &x) { parameters_.emplace_back(toml::get(x)); }); + Deserialisable::vector(node, "parameters", + [this](const auto &x) { parameters_.emplace_back(Deserialisable::deser(x)); }); } diff --git a/src/math/function1D.h b/src/math/function1D.h index b198a25043..23bd076097 100644 --- a/src/math/function1D.h +++ b/src/math/function1D.h @@ -111,7 +111,7 @@ class Functions1D }; // Function 1D Wrapper -class Function1DWrapper : public Serialisable +class Function1DWrapper { public: Function1DWrapper(Functions1D::Form form = Functions1D::Form::None, const std::vector ¶ms = {}); @@ -164,7 +164,7 @@ class Function1DWrapper : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/histogram1D.cpp b/src/math/histogram1D.cpp index 0573ee30c1..f03b7dff0f 100644 --- a/src/math/histogram1D.cpp +++ b/src/math/histogram1D.cpp @@ -3,6 +3,7 @@ #include "math/histogram1D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "templates/algorithms.h" #include @@ -214,8 +215,9 @@ Histogram1D Histogram1D::operator+(const Histogram1D &other) const // Express as a serialisable value void Histogram1D::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"minimum", minimum_}, {"maximum", maximum_}, {"binWidth", binWidth_}, - {"nBinned", nBinned_}, {"nMissed", nMissed_}, {"averages", averages_}}; + target[tag] = { + {"minimum", minimum_}, {"maximum", maximum_}, {"binWidth", binWidth_}, {"nBinned", nBinned_}, {"nMissed", nMissed_}}; + Serialisable::vector(averages_, "averages", target[tag]); } // Read values from a serialisable value @@ -223,12 +225,13 @@ void Histogram1D::deserialise(const SerialisedValue &node) { clear(); - initialise(toml::find(node, "minimum"), toml::find(node, "maximum"), toml::find(node, "binWidth")); + initialise(Deserialisable::deser(node.at("minimum")), Deserialisable::deser(node.at("maximum")), + Deserialisable::deser(node.at("binWidth"))); - nBinned_ = toml::find(node, "nBinned"); - nMissed_ = toml::find(node, "nMissed"); + nBinned_ = Deserialisable::deser(node.at("nBinned")); + nMissed_ = Deserialisable::deser(node.at("nMissed")); - averages_ = toml::find>(node, "averages"); + averages_ = Deserialisable::vector(node.at("averages")); updateAccumulatedData(); } diff --git a/src/math/histogram1D.h b/src/math/histogram1D.h index af5c4c0e0e..5e7a5e0dcb 100644 --- a/src/math/histogram1D.h +++ b/src/math/histogram1D.h @@ -8,7 +8,7 @@ #include "math/vector3.h" // One-Dimensional Histogram -class Histogram1D : public Serialisable +class Histogram1D { public: Histogram1D(); @@ -92,7 +92,7 @@ class Histogram1D : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/histogram2D.cpp b/src/math/histogram2D.cpp index 2b0528616e..fb0236101c 100644 --- a/src/math/histogram2D.cpp +++ b/src/math/histogram2D.cpp @@ -3,6 +3,7 @@ #include "math/histogram2D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "math/histogram1D.h" Histogram2D::Histogram2D() @@ -222,9 +223,9 @@ void Histogram2D::operator=(const Histogram2D &source) // Express as a serialisable value void Histogram2D::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"xMinimum", xMinimum_}, {"xMaximum", xMaximum_}, {"xBinWidth", xBinWidth_}, - {"yMinimum", yMinimum_}, {"yMaximum", yMaximum_}, {"yBinWidth", yBinWidth_}, - {"nBinned", nBinned_}, {"nMissed", nMissed_}, {"averages", averages_.linearArray()}}; + target[tag] = {{"xMinimum", xMinimum_}, {"xMaximum", xMaximum_}, {"xBinWidth", xBinWidth_}, {"yMinimum", yMinimum_}, + {"yMaximum", yMaximum_}, {"yBinWidth", yBinWidth_}, {"nBinned", nBinned_}, {"nMissed", nMissed_}}; + Serialisable::vector(averages_.linearArray(), "averages", target[tag]); } // Read values from a serialisable value @@ -232,14 +233,12 @@ void Histogram2D::deserialise(const SerialisedValue &node) { clear(); - initialise(toml::find(node, "xMinimum"), toml::find(node, "xMaximum"), - toml::find(node, "yBinWidth"), toml::find(node, "yMinimum"), - toml::find(node, "yMaximum"), toml::find(node, "yBinWidth")); - - nBinned_ = toml::find(node, "nBinned"); - nMissed_ = toml::find(node, "nMissed"); - - averages_.linearArray() = toml::find>(node, "averages"); + initialise(Deserialisable::deser(node.at("xMinimum")), Deserialisable::deser(node.at("xMaximum")), + Deserialisable::deser(node.at("yBinWidth")), Deserialisable ::deser(node.at("yMinimum")), + Deserialisable::deser(node.at("yMaximum")), Deserialisable::deser(node.at("yBinWidth"))); + nBinned_ = Deserialisable::deser(node.at("nBinned")); + nMissed_ = Deserialisable::deser(node.at("nMissed")); + averages_.linearArray() = Deserialisable::vector(node.at("averages")); updateAccumulatedData(); } diff --git a/src/math/histogram2D.h b/src/math/histogram2D.h index a7f89efd82..72c7767902 100644 --- a/src/math/histogram2D.h +++ b/src/math/histogram2D.h @@ -8,7 +8,7 @@ #include "templates/array2D.h" // Two-Dimensional Histogram -class Histogram2D : public Serialisable +class Histogram2D { public: Histogram2D(); @@ -106,7 +106,7 @@ class Histogram2D : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/histogram3D.cpp b/src/math/histogram3D.cpp index ef14ef1a78..b0a9cd9bc8 100644 --- a/src/math/histogram3D.cpp +++ b/src/math/histogram3D.cpp @@ -3,6 +3,7 @@ #include "math/histogram3D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "math/histogram1D.h" Histogram3D::Histogram3D() @@ -244,10 +245,10 @@ void Histogram3D::operator=(const Histogram3D &source) // Express as a serialisable value void Histogram3D::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"xMinimum", xMinimum_}, {"xMaximum", xMaximum_}, {"xBinWidth", xBinWidth_}, - {"yMinimum", yMinimum_}, {"yMaximum", yMaximum_}, {"yBinWidth", yBinWidth_}, - {"zMinimum", zMinimum_}, {"zMaximum", zMaximum_}, {"zBinWidth", zBinWidth_}, - {"nBinned", nBinned_}, {"nMissed", nMissed_}, {"averages", averages_.linearArray()}}; + target[tag] = {{"xMinimum", xMinimum_}, {"xMaximum", xMaximum_}, {"xBinWidth", xBinWidth_}, {"yMinimum", yMinimum_}, + {"yMaximum", yMaximum_}, {"yBinWidth", yBinWidth_}, {"zMinimum", zMinimum_}, {"zMaximum", zMaximum_}, + {"zBinWidth", zBinWidth_}, {"nBinned", nBinned_}, {"nMissed", nMissed_}}; + Serialisable::vector(averages_.linearArray(), "averages", target[tag]); } // Read values from a serialisable value @@ -255,15 +256,14 @@ void Histogram3D::deserialise(const SerialisedValue &node) { clear(); - initialise( - toml::find(node, "xMinimum"), toml::find(node, "xMaximum"), toml::find(node, "yBinWidth"), - toml::find(node, "yMinimum"), toml::find(node, "yMaximum"), toml::find(node, "yBinWidth"), - toml::find(node, "zMinimum"), toml::find(node, "zMaximum"), toml::find(node, "zBinWidth")); - - nBinned_ = toml::find(node, "nBinned"); - nMissed_ = toml::find(node, "nMissed"); - - averages_.linearArray() = toml::find>(node, "averages"); + initialise(Deserialisable::deser(node.at("xMinimum")), Deserialisable::deser(node.at("xMaximum")), + Deserialisable::deser(node.at("yBinWidth")), Deserialisable ::deser(node.at("yMinimum")), + Deserialisable::deser(node.at("yMaximum")), Deserialisable::deser(node.at("yBinWidth")), + Deserialisable::deser(node.at("zMinimum")), Deserialisable::deser(node.at("zMaximum")), + Deserialisable::deser(node.at("zBinWidth"))); + nBinned_ = Deserialisable::deser(node.at("nBinned")); + nMissed_ = Deserialisable::deser(node.at("nMissed")); + averages_.linearArray() = Deserialisable::vector(node.at("averages")); updateAccumulatedData(); } diff --git a/src/math/histogram3D.h b/src/math/histogram3D.h index 118fe50109..3a28a666bf 100644 --- a/src/math/histogram3D.h +++ b/src/math/histogram3D.h @@ -7,7 +7,7 @@ #include "math/sampledDouble.h" #include "templates/array3D.h" -class Histogram3D : public Serialisable +class Histogram3D { public: Histogram3D(); @@ -128,7 +128,7 @@ class Histogram3D : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/history.h b/src/math/history.h index b5ceb8b030..7ce7168a3e 100644 --- a/src/math/history.h +++ b/src/math/history.h @@ -4,6 +4,7 @@ #pragma once #include "base/serialiser.h" +#include "base/serialiserLibrary.h" #include #include #include @@ -11,7 +12,7 @@ // Serialisable Data History // Requires that the template class T is itself a Serialisable and implements the += and * operators -template class History : public Serialisable +template class History { public: History(std::function initialiser = {}) : initialiser_(std::move(initialiser)) {} @@ -55,15 +56,15 @@ template class History : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override + void serialise(std::string tag, SerialisedValue &target) const { - return Serialisable::fromVector(history_, tag, target, [&](const auto &itemPtr) { return itemPtr->into_toml(); }); + return Serialisable::vector(history_, tag, target, [&](const auto &itemPtr) { return Serialisable::ser(*itemPtr); }); } // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override + void deserialise(const SerialisedValue &node) { history_.clear(); - return Serialisable::toVector(node, + return Deserialisable::vector(node, [&](const auto &value) { auto &unique = @@ -75,7 +76,7 @@ template class History : public Serialisable // Serialisable POD Data History // History for PODs, e.g. double, int -template class PODHistory : public Serialisable +template class PODHistory { private: // Stored historical data @@ -110,7 +111,7 @@ template class PODHistory : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override + void serialise(std::string tag, SerialisedValue &target) const { if (history_.empty()) return; @@ -119,5 +120,5 @@ template class PODHistory : public Serialisable target[tag] = data; } // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override { history_ = toml::find>(node, "history"); } + void deserialise(const SerialisedValue &node) { history_ = Deserialisable::vector(node.at("history")); } }; diff --git a/src/math/integerHistogram1D.cpp b/src/math/integerHistogram1D.cpp index 73157ba083..6e0a021e61 100644 --- a/src/math/integerHistogram1D.cpp +++ b/src/math/integerHistogram1D.cpp @@ -3,6 +3,7 @@ #include "math/integerHistogram1D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include "math/mathFunc.h" #include "templates/algorithms.h" @@ -155,14 +156,14 @@ const Data1D &IntegerHistogram1D::accumulatedData() const { return accumulatedDa // Express as a serialisable value void IntegerHistogram1D::serialise(std::string tag, SerialisedValue &target) const { - target[tag] = {{"zeroCounter", zeroCounter_}, {"nBinned", nBinned_}, {"nMissed", nMissed_}}; + target[tag] = {{"zeroCounter", Serialisable::ser(zeroCounter_)}, {"nBinned", nBinned_}, {"nMissed", nMissed_}}; if (minimum_) target[tag]["minimum"] = *minimum_; if (maximum_) target[tag]["maximum"] = *maximum_; - fromMap(averages_, "averages", target); + Serialisable::map(averages_, "averages", target); } // Read values from a serialisable value @@ -170,14 +171,14 @@ void IntegerHistogram1D::deserialise(const SerialisedValue &node) { clear(); - getIfPresent(node, "minimum", minimum_); - getIfPresent(node, "maximum", maximum_); + Deserialisable::getIfPresent(node, "minimum", minimum_); + Deserialisable::getIfPresent(node, "maximum", maximum_); - nBinned_ = toml::find(node, "nBinned"); - nMissed_ = toml::find(node, "nMissed"); - zeroCounter_ = toml::find(node, "nMissed"); - - toMap(node, "averages", [&](const auto &key, const auto &value) { averages_[std::stoi(key)].deserialise(value); }); + nBinned_ = Deserialisable::deser(node.at("nBinned")); + nMissed_ = Deserialisable::deser(node.at("nMissed")); + zeroCounter_ = Deserialisable::deser(node.at("nMissed")); + Deserialisable::map(node, "averages", + [&](const auto &key, const auto &value) { averages_[std::stoi(key)].deserialise(value); }); updateAccumulatedData(); } diff --git a/src/math/integerHistogram1D.h b/src/math/integerHistogram1D.h index 496919ff2f..c65e9d0aa7 100644 --- a/src/math/integerHistogram1D.h +++ b/src/math/integerHistogram1D.h @@ -7,7 +7,7 @@ #include "math/sampledDouble.h" #include -class IntegerHistogram1D : public Serialisable +class IntegerHistogram1D { public: IntegerHistogram1D(); @@ -69,7 +69,7 @@ class IntegerHistogram1D : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/range.cpp b/src/math/range.cpp index 9ce5134ab2..e3b6169d40 100644 --- a/src/math/range.cpp +++ b/src/math/range.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "math/range.h" +#include "base/serialiserLibrary.h" Range::Range(std::optional minimum, std::optional maximum) { set(minimum, maximum); } @@ -57,8 +58,8 @@ void Range::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Range::deserialise(const SerialisedValue &node) { - minimum_ = toml::find(node, "min"); - maximum_ = toml::find(node, "max"); + minimum_ = Deserialisable::deser(node.at("min")); + maximum_ = Deserialisable::deser(node.at("max")); } // Equality diff --git a/src/math/range.h b/src/math/range.h index 65c7f22f4d..2a6c37585d 100644 --- a/src/math/range.h +++ b/src/math/range.h @@ -8,7 +8,7 @@ #include // Range -class Range : public Serialisable +class Range { public: Range(std::optional minimum = std::nullopt, std::optional maximum = std::nullopt); @@ -40,9 +40,9 @@ class Range : public Serialisable // Return whether or not the range has been fully defined bool isDefined() const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); bool operator==(const Range &rhs) const; bool operator!=(const Range &rhs) const; }; diff --git a/src/math/rangedVector3.h b/src/math/rangedVector3.h index 8c0c051a3d..2aeff731d8 100644 --- a/src/math/rangedVector3.h +++ b/src/math/rangedVector3.h @@ -8,7 +8,7 @@ #include // Ranged Vector3 -class RangedVector3 : public Serialisable +class RangedVector3 { public: RangedVector3() = default; @@ -59,7 +59,7 @@ class RangedVector3 : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/sampledData1D.cpp b/src/math/sampledData1D.cpp index 59ac1e3358..040518078c 100644 --- a/src/math/sampledData1D.cpp +++ b/src/math/sampledData1D.cpp @@ -3,6 +3,7 @@ #include "math/sampledData1D.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "math/histogram1D.h" #include "templates/algorithms.h" #include @@ -157,6 +158,6 @@ void SampledData1D::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void SampledData1D::deserialise(const SerialisedValue &node) { - x_ = toml::find>(node, "x"); + x_ = Deserialisable::vector(node.at("x")); values_.deserialise(node.at("values")); } diff --git a/src/math/sampledData1D.h b/src/math/sampledData1D.h index 77e01f40ee..dcffb63d73 100644 --- a/src/math/sampledData1D.h +++ b/src/math/sampledData1D.h @@ -13,7 +13,7 @@ class Data1D; // One-Dimensional Data with Statistics -class SampledData1D : public Data1DBase, public Serialisable +class SampledData1D : public Data1DBase { public: SampledData1D(); @@ -83,7 +83,7 @@ class SampledData1D : public Data1DBase, public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/sampledDouble.cpp b/src/math/sampledDouble.cpp index d14ee198a5..ee5d3127c1 100644 --- a/src/math/sampledDouble.cpp +++ b/src/math/sampledDouble.cpp @@ -2,6 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "math/sampledDouble.h" +#include "base/serialiserLibrary.h" #include SampledDouble::SampledDouble() { clear(); } @@ -149,7 +150,7 @@ void SampledDouble::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void SampledDouble::deserialise(const SerialisedValue &value) { - mean_ = toml::find(value, "mean"); - count_ = toml::find(value, "count"); - m2_ = toml::find(value, "m2"); + mean_ = Deserialisable::deser(value.at("mean")); + count_ = Deserialisable::deser(value.at("count")); + m2_ = Deserialisable::deser(value.at("m2")); }; diff --git a/src/math/sampledDouble.h b/src/math/sampledDouble.h index cd1bfbdd17..2ed559d3c6 100644 --- a/src/math/sampledDouble.h +++ b/src/math/sampledDouble.h @@ -9,7 +9,7 @@ class ProcessPool; // Double value with sampling -class SampledDouble : public Serialisable +class SampledDouble { public: SampledDouble(); @@ -60,7 +60,7 @@ class SampledDouble : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/sampledVector.cpp b/src/math/sampledVector.cpp index 8e3c056970..db971a99e3 100644 --- a/src/math/sampledVector.cpp +++ b/src/math/sampledVector.cpp @@ -3,6 +3,7 @@ #include "math/sampledVector.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "templates/algorithms.h" #include @@ -183,8 +184,8 @@ void SampledVector::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void SampledVector::deserialise(const SerialisedValue &node) { - count_ = toml::find(node, "count"); - mean_ = toml::find>(node, "mean"); - stDev_ = toml::find>(node, "stDev"); - m2_ = toml::find>(node, "m2"); + count_ = Deserialisable::deser(node.at("count")); + mean_ = Deserialisable::vector(node.at("mean")); + stDev_ = Deserialisable::vector(node.at("stDev")); + m2_ = Deserialisable::vector(node.at("m2")); } diff --git a/src/math/sampledVector.h b/src/math/sampledVector.h index de1cd770f0..2a0bb995f3 100644 --- a/src/math/sampledVector.h +++ b/src/math/sampledVector.h @@ -7,7 +7,7 @@ #include // Vector of double values with sampling -class SampledVector : public Serialisable +class SampledVector { public: SampledVector(); @@ -60,7 +60,7 @@ class SampledVector : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/vector3.cpp b/src/math/vector3.cpp index 58bddf0d52..9a2472857b 100644 --- a/src/math/vector3.cpp +++ b/src/math/vector3.cpp @@ -3,6 +3,7 @@ #include "math/vector3.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "math/mathFunc.h" #include #include @@ -506,7 +507,7 @@ void Vector3::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Vector3::deserialise(const SerialisedValue &node) { - x = toml::get(node[0]); - y = toml::get(node[1]); - z = toml::get(node[2]); + x = Deserialisable::deser(node[0]); + y = Deserialisable::deser(node[1]); + z = Deserialisable::deser(node[2]); } diff --git a/src/math/vector3.h b/src/math/vector3.h index 6e842cd4ce..463b7d0ea2 100644 --- a/src/math/vector3.h +++ b/src/math/vector3.h @@ -9,7 +9,7 @@ #include // 3D Real Vector -class Vector3 : public Serialisable +class Vector3 { public: Vector3() = default; @@ -138,7 +138,7 @@ class Vector3 : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/math/vector3i.cpp b/src/math/vector3i.cpp index d026ba53a9..ae4773579c 100644 --- a/src/math/vector3i.cpp +++ b/src/math/vector3i.cpp @@ -3,6 +3,7 @@ #include "math/vector3i.h" #include "base/messenger.h" +#include "base/serialiserLibrary.h" #include "math/mathFunc.h" #include #include @@ -357,7 +358,7 @@ void Vector3i::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Vector3i::deserialise(const SerialisedValue &node) { - x = toml::get(node[0]); - y = toml::get(node[1]); - z = toml::get(node[2]); + x = Deserialisable::deser(node[0]); + y = Deserialisable::deser(node[1]); + z = Deserialisable::deser(node[2]); } diff --git a/src/math/vector3i.h b/src/math/vector3i.h index 90831cbf5f..e7e36bdef6 100644 --- a/src/math/vector3i.h +++ b/src/math/vector3i.h @@ -12,7 +12,7 @@ class NodeValue; class ExpressionVariable; // 3D Real Vector -class Vector3i : public Serialisable +class Vector3i { public: Vector3i() = default; @@ -113,7 +113,7 @@ class Vector3i : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/dissolve.cpp b/src/nodes/dissolve.cpp index 2ded84037b..c8f69f49e2 100644 --- a/src/nodes/dissolve.cpp +++ b/src/nodes/dissolve.cpp @@ -173,13 +173,13 @@ void DissolveGraph::serialise(std::string tag, SerialisedValue &target) const { Graph::serialise(tag, target); auto &result = target[tag]; - Serialisable::fromVector<>(pairPotentialOverrides_, "pairPotentialOverrides", result); + Serialisable::vector<>(pairPotentialOverrides_, "pairPotentialOverrides", result); } // Read values from a serialisable value void DissolveGraph::deserialise(const SerialisedValue &node) { Graph::deserialise(node); - Serialisable::toVector(node, "pairPotentialOverrides", + Deserialisable::vector(node, "pairPotentialOverrides", [this](const auto ppOverrideNode) { addPairPotentialOverride()->deserialise(ppOverrideNode); }); } diff --git a/src/nodes/dissolve.h b/src/nodes/dissolve.h index 7cb6d82658..c602083729 100644 --- a/src/nodes/dissolve.h +++ b/src/nodes/dissolve.h @@ -83,7 +83,7 @@ class DissolveGraph : public Graph */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/edge.cpp b/src/nodes/edge.cpp index 616797bac3..c767573136 100644 --- a/src/nodes/edge.cpp +++ b/src/nodes/edge.cpp @@ -197,10 +197,10 @@ void EdgeDefinition::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void EdgeDefinition::deserialise(const SerialisedValue &node) { - sourceNode = toml::find(node, "sourceNode"); - sourceOutput = toml::find(node, "sourceOutput"); - targetNode = toml::find(node, "targetNode"); - targetInput = toml::find(node, "targetInput"); + sourceNode = Deserialisable::deser(node.at("sourceNode")); + sourceOutput = Deserialisable::deser(node.at("sourceOutput")); + targetNode = Deserialisable::deser(node.at("targetNode")); + targetInput = Deserialisable::deser(node.at("targetInput")); } // Pull the data from the source node to the target, returning a ProcessResult diff --git a/src/nodes/edge.h b/src/nodes/edge.h index 4d69360cf8..dcc4d934d5 100644 --- a/src/nodes/edge.h +++ b/src/nodes/edge.h @@ -12,7 +12,7 @@ class Graph; // Edge Definition -class EdgeDefinition : public Serialisable +class EdgeDefinition { public: EdgeDefinition() = default; @@ -23,13 +23,13 @@ class EdgeDefinition : public Serialisable // Return as a string std::string asString() const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; // Edge -class Edge : public Serialisable +class Edge { friend class LoopEdge; @@ -81,9 +81,9 @@ class Edge : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; // Loop edge diff --git a/src/nodes/epsr.h b/src/nodes/epsr.h index c4ad73ba0e..d67eae5b0d 100644 --- a/src/nodes/epsr.h +++ b/src/nodes/epsr.h @@ -19,7 +19,7 @@ class AtomType; class Configuration; class PartialSet; -class EPSRNamedTargetWeights : public Serialisable +class EPSRNamedTargetWeights { public: EPSRNamedTargetWeights() = default; @@ -39,9 +39,9 @@ class EPSRNamedTargetWeights : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; // EPSR Node diff --git a/src/nodes/epsrHelpers.cpp b/src/nodes/epsrHelpers.cpp index c297ed13c0..4faf9a3e64 100644 --- a/src/nodes/epsrHelpers.cpp +++ b/src/nodes/epsrHelpers.cpp @@ -355,14 +355,14 @@ std::vector> EPSRNamedTargetWeights::value() // Express as a serialisable value void EPSRNamedTargetWeights::serialise(std::string tag, SerialisedValue &target) const { - Serialisable::fromMap(weights_, tag, target); + Serialisable::map(weights_, tag, target); } // Read values from a serialisable value void EPSRNamedTargetWeights::deserialise(const SerialisedValue &node) { weights_.clear(); - return Serialisable::toMap(node, + return Deserialisable::map(node, [&](const auto &key, const auto &value) { std::pair mapping(std::string(key), 1.0); diff --git a/src/nodes/forcefield.h b/src/nodes/forcefield.h index 003bb03cec..c1911b2715 100644 --- a/src/nodes/forcefield.h +++ b/src/nodes/forcefield.h @@ -40,7 +40,7 @@ class ForcefieldNode : public Node */ protected: // Serialise any hidden content - void serialiseInternal(SerialisedValue &target) const override; + void serialiseInternal(SerialisedValue &target) const; // Deserialise any hidden content - void deserialiseInternal(const SerialisedValue &target) override; + void deserialiseInternal(const SerialisedValue &target); }; diff --git a/src/nodes/graph.cpp b/src/nodes/graph.cpp index 0c10f14966..dcd3375bb2 100644 --- a/src/nodes/graph.cpp +++ b/src/nodes/graph.cpp @@ -263,23 +263,23 @@ void Graph::serialise(std::string tag, SerialisedValue &target) const { Node::serialise(tag, target); auto &result = target[tag]; - fromMap(nodes_, "nodes", result, [](const auto key, const auto &value) { return value->shouldSerialise(); }); - fromVector(edges_, "edges", result); + Serialisable::fromMap(nodes_, "nodes", result, [](const auto key, const auto &value) { return value->shouldSerialise(); }); + Serialisable::vector(edges_, "edges", result); } // Read values from a serialisable value void Graph::deserialise(const SerialisedValue &node) { Node::deserialise(node); - toMap(node, "nodes", - [this](const auto name, const auto &value) - { - std::string nodeType = toml::find(value, "type"); - auto child = createNode(nodeType, name); - - child->deserialise(value); - }); - toVector(node, "edges", [this](const auto &value) { addEdge(toml::get(value)); }); + Deserialisable::map(node, "nodes", + [this](const auto name, const auto &value) + { + std::string nodeType = Deserialisable::deser(value.at("type")); + auto child = createNode(nodeType, name); + + child->deserialise(value); + }); + Deserialisable::vector(node, "edges", [this](const auto &value) { addEdge(Deserialisable::deser(value)); }); } /* diff --git a/src/nodes/graph.h b/src/nodes/graph.h index 707bbde768..acbc6846f9 100644 --- a/src/nodes/graph.h +++ b/src/nodes/graph.h @@ -115,7 +115,7 @@ class Graph : public Node */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/inputs.h b/src/nodes/inputs.h index 1f0c2de7a2..393bd0d1d6 100644 --- a/src/nodes/inputs.h +++ b/src/nodes/inputs.h @@ -32,9 +32,9 @@ class InputsNode : public Node */ public: // Is it appropriate to bother serialising this node? - bool shouldSerialise() const override; + bool shouldSerialise() const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/loopBack.h b/src/nodes/loopBack.h index 931f4342c4..37fe5f0f63 100644 --- a/src/nodes/loopBack.h +++ b/src/nodes/loopBack.h @@ -47,9 +47,9 @@ class LoopBacksNode : public Node */ public: // Is it appropriate to bother serialising this node? - bool shouldSerialise() const override; + bool shouldSerialise() const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/node.cpp b/src/nodes/node.cpp index 2ca34a8e88..d9947fa0b2 100644 --- a/src/nodes/node.cpp +++ b/src/nodes/node.cpp @@ -341,7 +341,7 @@ void Node::serialise(std::string tag, SerialisedValue &target) const result["x"] = x; result["y"] = y; - fromMap(options_, "options", result); + Serialisable::map(options_, "options", result); serialiseInternal(result); @@ -351,24 +351,24 @@ void Node::serialise(std::string tag, SerialisedValue &target) const // Read values from a serialisable value void Node::deserialise(const SerialisedValue &node) { - x = toml::find(node, "x"); - y = toml::find(node, "y"); - toMap(node, "inputs", - [this](const auto &k, const auto &v) - { - if (inputs_.contains(k)) - inputs_[k]->deserialise(v); - else - Messenger::exception("Node {} does not contain a parameter {}", name(), k); - }); - toMap(node, "options", - [this](const auto &k, const auto &v) - { - if (options_.contains(k)) - options_[k]->deserialise(v); - else - Messenger::exception("Node {} does not contain an option {}", name(), k); - }); + x = Deserialisable::deser(node.at("x")); + y = Deserialisable::deser(node.at("y")); + Deserialisable::map(node, "inputs", + [this](const auto &k, const auto &v) + { + if (inputs_.contains(k)) + inputs_[k]->deserialise(v); + else + Messenger::exception("Node {} does not contain a parameter {}", name(), k); + }); + Deserialisable::map(node, "options", + [this](const auto &k, const auto &v) + { + if (options_.contains(k)) + options_[k]->deserialise(v); + else + Messenger::exception("Node {} does not contain an option {}", name(), k); + }); deserialiseInternal(node); } diff --git a/src/nodes/node.h b/src/nodes/node.h index 778a9d8b17..77fc6a93ea 100644 --- a/src/nodes/node.h +++ b/src/nodes/node.h @@ -25,7 +25,7 @@ class DissolveGraph; class PairPotential; // Node Base -class Node : public Serialisable +class Node { public: Node() {} @@ -207,7 +207,7 @@ class Node : public Serialisable return param; } // Add serialisable input parameter - template + template std::shared_ptr addSerialisableInput(std::string_view inputName, std::string_view description, T &data) { if (findInput(inputName)) @@ -367,9 +367,9 @@ class Node : public Serialisable serialisables_[std::string(key)] = std::make_shared>(key, data); } // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); // Express persistent data as a serialisable value SerialisedValue serialiseData() const; // Read persistent data from a serialisable value diff --git a/src/nodes/number.h b/src/nodes/number.h index 13bc9ff32c..ef00a362fa 100644 --- a/src/nodes/number.h +++ b/src/nodes/number.h @@ -8,7 +8,7 @@ #include // Node Number -class Number : public Serialisable +class Number { public: using NumberVariant = std::variant; @@ -86,7 +86,7 @@ class Number : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/outputs.h b/src/nodes/outputs.h index eedb726476..a45598e14a 100644 --- a/src/nodes/outputs.h +++ b/src/nodes/outputs.h @@ -37,9 +37,9 @@ class OutputsNode : public Node */ public: // Is it appropriate to bother serialising this node? - bool shouldSerialise() const override; + bool shouldSerialise() const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; + void serialise(std::string tag, SerialisedValue &target) const; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override; + void deserialise(const SerialisedValue &node); }; diff --git a/src/nodes/parameter.h b/src/nodes/parameter.h index 2fb57ca779..609d984ad4 100644 --- a/src/nodes/parameter.h +++ b/src/nodes/parameter.h @@ -6,6 +6,7 @@ #include "base/context.h" #include "base/enumOptions.h" #include "base/serialiser.h" +#include "base/serialiserLibrary.h" #include "math/data1D.h" #include "nodes/number.h" #include "templates/algorithms.h" @@ -38,7 +39,7 @@ struct ParameterLink }; // Base type for all parameter templates to inherit from -class ParameterBase : public Serialisable +class ParameterBase { public: ParameterBase(Node *parent, std::string_view name, std::string_view description, std::type_index storedDataType); @@ -160,9 +161,9 @@ class ParameterBase : public Serialisable */ public: // Express as a serialised value - virtual void serialise(std::string tag, SerialisedValue &target) const override {} + virtual void serialise(std::string tag, SerialisedValue &target) const {} // Read from a serialised value - virtual void deserialise(const SerialisedValue &node) override { return; } + virtual void deserialise(const SerialisedValue &node) { return; } }; namespace ParameterFactory @@ -567,7 +568,7 @@ template class SerialisableParameter : public Parameter class SerialisableParameter : public Parameter) result["data"] = getEnumOptions(Parameter::data_).serialise(Parameter::data_); else if constexpr (std::is_convertible::value) - result["data"] = Parameter::data_; + result["data"] = Serialisable::ser(Parameter::data_); else if constexpr (std::is_convertible::value) - result["data"] = Parameter::data_; + result["data"] = Serialisable::ser(Parameter::data_); else if constexpr (std::is_convertible>::value) { if (Parameter::data_) - result["data"] = *Parameter::data_; + result["data"] = Serialisable::ser(*Parameter::data_); } + else if constexpr (Serialisable::Serialisable) + result["data"] = Serialisable::ser(Parameter::data_); else - result["data"] = Parameter::data_; + throw(std::runtime_error(std::format("Cannot deserialise type {}", typeid(DataClass).name()))); target[tag] = result; }; // Read from a serialised value - void deserialise(const SerialisedValue &node) override + void deserialise(const SerialisedValue &node) { if constexpr (std::is_pointer::value) { @@ -605,27 +608,27 @@ template class SerialisableParameter : public Parameter>::value) { if (node.contains("data")) - Parameter::data_ = toml::find(node, "data"); + Parameter::data_ = Deserialisable::deser(node.at("data")); else Parameter::data_ = {}; } else if constexpr (std::is_convertible>::value) { if (node.contains("data")) - Parameter::data_ = toml::find(node, "data"); + Parameter::data_ = Deserialisable::deser(node.at("data")); else Parameter::data_ = {}; } else if constexpr (std::is_convertible>::value) { if (node.contains("data")) - Parameter::data_ = toml::find(node, "data"); + Parameter::data_ = Deserialisable::deser(node.at("data")); else Parameter::data_ = {}; } + else if constexpr (Deserialisable::Deserialisible) + Parameter::data_ = Deserialisable::deser(node.at("data")); else - { - Parameter::data_ = toml::find(node, "data"); - } + throw(std::runtime_error(std::format("Cannot deserialise type {}", typeid(DataClass).name()))); } }; diff --git a/src/nodes/serialisableData.h b/src/nodes/serialisableData.h index b61b2e3c81..7d44e57315 100644 --- a/src/nodes/serialisableData.h +++ b/src/nodes/serialisableData.h @@ -4,6 +4,7 @@ #pragma once #include "base/serialiser.h" +#include "base/serialiserLibrary.h" #include "templates/algorithms.h" // Base type for serialisable data @@ -41,23 +42,23 @@ template class SerialisableClass : public SerialisableData // Optional Vector of Serialisable SerialisableClass(std::string_view key, DataClass &targetData) requires(is_optional && is_instance_of_v && - std::is_base_of_v) + Serialisable::Serialisable) : SerialisableData(key), data_(targetData), dataSerialiser_( [&]() { - return Serialisable::fromVector(data_.value(), - [&](const auto &item) - { - SerialisedValue outer; - item.serialise("inner", outer); - return outer["inner"]; - }); + return Serialisable::vector(data_.value(), + [&](const auto &item) + { + SerialisedValue outer; + item.serialise("inner", outer); + return outer["inner"]; + }); }), dataDeserialiser_( [&](const SerialisedValue &value) { targetData.emplace(); - Serialisable::toVector(value, [&](const auto &node) { data_->emplace_back().deserialise(node); }); + Deserialisable::vector(value, [&](const auto &node) { data_->emplace_back().deserialise(node); }); }), dataChecker_([&]() { return targetData.has_value() && !targetData.value().empty(); }), dataResolver_( @@ -71,8 +72,8 @@ template class SerialisableClass : public SerialisableData } // Optional Serialisable SerialisableClass(std::string_view key, DataClass &targetData) - requires(is_optional && std::is_base_of_v) - : SerialisableData(key), data_(targetData), dataSerialiser_([&]() { return data_.value().into_toml(); }), + requires(is_optional && Serialisable::Serialisable) + : SerialisableData(key), data_(targetData), dataSerialiser_([&]() { return Serialisable::ser(data_.value()); }), dataDeserialiser_( [&](const SerialisedValue &value) { @@ -90,23 +91,23 @@ template class SerialisableClass : public SerialisableData } // Vector of Serialisable SerialisableClass(std::string_view key, DataClass &targetData) - requires(is_instance_of_v && std::is_base_of_v) + requires(is_instance_of_v && Serialisable::Serialisable) : SerialisableData(key), data_(targetData), dataSerialiser_( [&]() { - return Serialisable::fromVector(data_, - [&](const auto &item) - { - SerialisedValue outer; - item.serialise("inner", outer); - return outer["inner"]; - }); + return Serialisable::vector(data_, + [&](const auto &item) + { + SerialisedValue outer; + item.serialise("inner", outer); + return outer["inner"]; + }); }), dataDeserialiser_( [&](const SerialisedValue &value) { data_.clear(); - Serialisable::toVector(value, [&](const auto &node) { data_.emplace_back().deserialise(node); }); + Deserialisable::vector(value, [&](const auto &node) { data_.emplace_back().deserialise(node); }); }), dataChecker_([&]() { return !targetData.empty(); }), dataResolver_( @@ -118,29 +119,9 @@ template class SerialisableClass : public SerialisableData }) { } - // Trivial Non-Serialisable Value - SerialisableClass(std::string_view key, DataClass &value) - requires(std::is_trivial_v) - : SerialisableData(key), data_(value), dataSerialiser_( - [&]() - { - SerialisedValue value; - value = data_; - return value; - }), - dataDeserialiser_( - [&](const SerialisedValue &value) - { - if constexpr (std::is_floating_point_v) - data_ = value.as_floating(); - else if constexpr (std::is_integral_v) - data_ = value.as_integer(); - }) - { - } // Serialisable SerialisableClass(std::string_view key, DataClass &value) - requires(std::is_base_of_v) + requires(!is_optional && Serialisable::Serialisable) : SerialisableData(key), data_(value), dataResolver_( [&](const std::map &reachableSpecies) { @@ -159,15 +140,10 @@ template class SerialisableClass : public SerialisableData DataClass &data_; // Serialiser for target data using DataSerialiser = std::function; - DataSerialiser dataSerialiser_{[&]() - { - SerialisedValue target; - data_.serialise("inner", target); - return target["inner"]; - }}; + DataSerialiser dataSerialiser_{[&]() { return Serialisable::ser(data_); }}; // Deserialiser for target data using DataDeserialiser = std::function; - DataDeserialiser dataDeserialiser_{[&](const SerialisedValue &value) { data_.deserialise(value); }}; + DataDeserialiser dataDeserialiser_{[&](const SerialisedValue &value) { Deserialisable::deserialiseOnto(data_, value); }}; // Value checker for data, returning whether there is actually data to write using ValueChecker = std::function; ValueChecker dataChecker_{[&]() { return true; }}; @@ -180,11 +156,11 @@ template class SerialisableClass : public SerialisableData */ public: // Return whether there is data to serialise - bool canSerialise() const override { return dataChecker_(); } + bool canSerialise() const { return dataChecker_(); } // Express as a serialised value - SerialisedValue serialise() const override { return dataSerialiser_(); }; + SerialisedValue serialise() const { return dataSerialiser_(); }; // Read from a serialised value - void deserialise(const SerialisedValue &node) override { dataDeserialiser_(node); } + void deserialise(const SerialisedValue &node) { dataDeserialiser_(node); } // Resolve named data void resolve(const std::map &speciesInScope) override { dataResolver_(speciesInScope); }; }; diff --git a/src/nodes/species.h b/src/nodes/species.h index 5c922bed0c..475a8c7e72 100644 --- a/src/nodes/species.h +++ b/src/nodes/species.h @@ -55,7 +55,7 @@ class SpeciesNode : public Node */ private: // Serialise any hidden content - void serialiseInternal(SerialisedValue &target) const override; + void serialiseInternal(SerialisedValue &target) const; // Deserialise any hidden content - void deserialiseInternal(const SerialisedValue &target) override; + void deserialiseInternal(const SerialisedValue &target); }; diff --git a/src/templates/doubleKeyedMap.h b/src/templates/doubleKeyedMap.h index b543408135..bedc1079b8 100644 --- a/src/templates/doubleKeyedMap.h +++ b/src/templates/doubleKeyedMap.h @@ -4,6 +4,7 @@ #pragma once #include "base/serialiser.h" +#include "base/serialiserLibrary.h" #include "base/sysFunc.h" #include "templates/algorithms.h" #include "templates/array2D.h" @@ -17,7 +18,7 @@ * removing the critical dependence of an immutably ordered vector of AtomTypes. */ using DoubleKeyedMapKey = std::pair; -template class DoubleKeyedMap : public Serialisable +template class DoubleKeyedMap { public: DoubleKeyedMap(bool mirrored = false) : mirroredAreEquivalent_(mirrored) {} @@ -164,18 +165,18 @@ template class DoubleKeyedMap : public Serialisable */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override + void serialise(std::string tag, SerialisedValue &target) const { SerialisedValue result; - Serialisable::fromMap(data_, "map", result); + Serialisable::map(data_, "map", result); target[tag] = result; }; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) override + void deserialise(const SerialisedValue &node) { data_.clear(); - for (auto &[mapKey, value] : toml::find(node, "map")) + for (auto &[mapKey, value] : node.at("map").as_table()) { if constexpr (std::is_same_v) data_[mapKey] = value.as_floating(); diff --git a/src/templates/resolvableKeyedVector.h b/src/templates/resolvableKeyedVector.h index 8412ccfe41..e049975a82 100644 --- a/src/templates/resolvableKeyedVector.h +++ b/src/templates/resolvableKeyedVector.h @@ -3,6 +3,7 @@ #pragma once +#include "templates/keyedVector.h" #include "templates/resolvable.h" #include #include diff --git a/tests/nodes/graph.cpp b/tests/nodes/graph.cpp index d160f1d8a4..a6b24edc19 100644 --- a/tests/nodes/graph.cpp +++ b/tests/nodes/graph.cpp @@ -65,14 +65,14 @@ TEST_F(GraphCoreTest, Serialisation) createGraph(); DissolveGraph copy; - auto serialised = root_.into_toml(); + auto serialised = Serialisable::ser(root_); SerialisedValue contents = toml::parse("graph/simple_addition_graph.toml"); UnitTest::compareToml("", serialised, contents); std::cout << serialised << std::endl; copy.deserialise(serialised); - auto repeat = copy.into_toml(); + auto repeat = Serialisable::ser(copy); UnitTest::compareToml("", repeat, contents); };