diff --git a/CMakeLists.txt b/CMakeLists.txt index abccc79fcf..2fe91737d6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -295,9 +295,7 @@ set(BASIC_LINK_LIBS kernels neta analyser - keywords expression - items base math data diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c5d89bfb9..2ad17e6ac7 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,9 +3,7 @@ add_subdirectory(base) add_subdirectory(classes) add_subdirectory(data) add_subdirectory(expression) -add_subdirectory(items) add_subdirectory(kernels) -add_subdirectory(keywords) add_subdirectory(main) add_subdirectory(math) add_subdirectory(neta) diff --git a/src/base/serialiser.h b/src/base/serialiser.h index b5e97b8f06..e77fca1082 100644 --- a/src/base/serialiser.h +++ b/src/base/serialiser.h @@ -3,12 +3,11 @@ #pragma once -#include - #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 @@ -19,43 +18,16 @@ using SerialisedValue = toml::basic_value concept serialisablePointer = requires(T a, std::string tag, SerialisedValue target) { a->serialise(tag, target); }; -// The associated context for type T This type does double duty. -// First, since the struct has not actual members, it is a Unit type -// (a type with only one possible value). This is why the default -// inner type is SerialisableContext - says that we have no -// context and the type has no size. The second duty is acting as a -// type level function. Normally, you would just add an inner type to -// a class (e.g. NodeValue::Context) to perform this function. -// Unfortunately, you can't add an inner type to a primative type -// (e.g. float). By specialising this template, we can create a -// mapping between types and the context that they require. -template struct SerialisableContext -{ - using type = SerialisableContext; -}; - // An interface for classes that can be serialised into an input file -template class Serialisable +class 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, Contexts... context) { return; } - - // When a type has only one context and that context is empty - // (i.e. is a Unit type), then we can create a simple overload - // that skips the need to add the second parameter. This does not - // conflict with the definition above because it only becomes - // instantiated when the Contexts pack is not empty, so the above - // definition of deserialise takes two parameters. We also insist - // that it is only called for empty types to ensure that we do not - // accidentally create a value with its default constructor. - template ::value && ...)>> - void deserialise(const SerialisedValue &node) - { - deserialise(node, {}); - } + virtual void deserialise(const SerialisedValue &node) {} /* Functions that hook into the toml11 library */ // Wrapper for deserialise that toml11 will check for @@ -82,6 +54,14 @@ template class Serialisable 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) @@ -204,14 +184,14 @@ template class Serialisable SerialisedValue result; for (auto &[key, value] : map) if constexpr (serialisablePointer) - value->serialise(std::string(key), result); + value->serialise(std::format("{}", key), result); else if constexpr (std::is_base_of_v) - value.serialise(key, result); + 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::string(key)] = value; + result[std::format("{}", key)] = value; if (!map.empty()) node[name] = result; } diff --git a/src/classes/CMakeLists.txt b/src/classes/CMakeLists.txt index b1da41bfee..10a5ad161f 100644 --- a/src/classes/CMakeLists.txt +++ b/src/classes/CMakeLists.txt @@ -12,7 +12,6 @@ add_library( configuration.cpp configuration_box.cpp configuration_contents.cpp - configuration_io.cpp configuration_sites.cpp configuration_upkeep.cpp configurationAtom.cpp diff --git a/src/classes/atom.h b/src/classes/atom.h index 88f748c1e1..525e14954e 100644 --- a/src/classes/atom.h +++ b/src/classes/atom.h @@ -89,11 +89,11 @@ class AtomBase }; // Atom -template class Atom : public AtomBase, public Serialisable<> +template class Atom : public AtomBase, public Serialisable { public: Atom() = default; - virtual ~Atom() = default; + virtual ~Atom() override = default; /* * Coordinate Manipulation Operators @@ -125,9 +125,9 @@ template class Atom : public AtomBase, public Serialisable< return nullptr; } // Return number of bonds - int nBonds() const { return bonds_.size(); } + int nBonds() const override { return bonds_.size(); } // Return indices of other AtomBases to which this one is connected - std::vector connectedAtoms() const + std::vector connectedAtoms() const override { std::vector connections; for (const auto *bond : bonds_) @@ -140,12 +140,12 @@ template class Atom : public AtomBase, public Serialisable< */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const + 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) + void deserialise(const SerialisedValue &node) override { index_ = toml::find(node, "index"); diff --git a/src/classes/atomType.h b/src/classes/atomType.h index 84a33105ef..c5209c3f1e 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 Serialisable, public std::enable_shared_from_this { public: AtomType(Elements::Element Z = Elements::Unknown); diff --git a/src/classes/bond.h b/src/classes/bond.h index eaa9ab057c..35cb5e809f 100644 --- a/src/classes/bond.h +++ b/src/classes/bond.h @@ -9,7 +9,7 @@ class AtomBase; // Bond -template class Bond : public Serialisable<> +template class Bond : public Serialisable { public: Bond(AtomClass *i = nullptr, AtomClass *j = nullptr) : i_(i), j_(j) {} diff --git a/src/classes/box.h b/src/classes/box.h index 8156541b12..c98c82ad6f 100644 --- a/src/classes/box.h +++ b/src/classes/box.h @@ -16,7 +16,7 @@ class Cell; class Data1D; // Basic Box Definition -class Box : public Serialisable<> +class Box : public Serialisable { public: // Box Type Enum diff --git a/src/classes/braggReflection.cpp b/src/classes/braggReflection.cpp index c97bb29772..7954dbd8b8 100644 --- a/src/classes/braggReflection.cpp +++ b/src/classes/braggReflection.cpp @@ -3,8 +3,6 @@ #include "classes/braggReflection.h" #include "base/lineParser.h" -#include "items/deserialisers.h" -#include "items/serialisers.h" BraggReflectionVector::BraggReflectionVector(const BraggReflectionVector &other) : reflections_(other.reflections_) {} @@ -139,24 +137,6 @@ const Vector3i &BraggReflection::hkl() const { return hkl_; } * Serialisation */ -// Read data through specified parser -bool BraggReflection::deserialise(LineParser &parser) -{ - // Read index, Q centre, and number of contributing K-vectors - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - index_ = parser.argi(0); - q_ = parser.argd(1); - nKVectors_ = parser.argi(2); - hkl_ = parser.arg3i(3); - - // Read intensities array - if (!GenericItemDeserialiser::deserialise>(intensities_, parser)) - return false; - - return true; -} - // Read values from a serialisable value void BraggReflection::deserialise(const SerialisedValue &node) { @@ -177,17 +157,3 @@ void BraggReflection::serialise(std::string tag, SerialisedValue &target) const braggReflection["nKVectors"] = nKVectors_; hkl_.serialise(tag, target); } - -// Write data through specified parser -bool BraggReflection::serialise(LineParser &parser) const -{ - // Write index, Q centre, and number of contributing K-vectors - if (!parser.writeLineF("{} {} {} {} {} {}\n", index_, q_, nKVectors_, hkl_.x, hkl_.y, hkl_.z)) - return false; - - // Write intensities array - if (!GenericItemSerialiser::serialise>(intensities_, parser)) - return false; - - return true; -} diff --git a/src/classes/braggReflection.h b/src/classes/braggReflection.h index d1cb9352f7..5be906bf16 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 Serialisable { public: BraggReflection(); @@ -67,18 +67,14 @@ class BraggReflection : public Serialisable<> * Serialisation */ public: - // Read data through specified parser - bool deserialise(LineParser &parser); // Read values from a serialisable value void deserialise(const SerialisedValue &node) override; - // Write data through specified parser - bool serialise(LineParser &parser) const; // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const; + void serialise(std::string tag, SerialisedValue &target) const override; }; // BraggReflectionVector class -class BraggReflectionVector : public Serialisable<> +class BraggReflectionVector : public Serialisable { public: BraggReflectionVector() = default; @@ -105,7 +101,7 @@ class BraggReflectionVector : public Serialisable<> */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const; + void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value void deserialise(const SerialisedValue &node) override; }; \ No newline at end of file diff --git a/src/classes/configuration.cpp b/src/classes/configuration.cpp index c16e5e8d52..9c933ddce6 100644 --- a/src/classes/configuration.cpp +++ b/src/classes/configuration.cpp @@ -62,7 +62,7 @@ void Configuration::serialise(std::string tag, SerialisedValue &target) const } // Read values from a serialisable value -void Configuration::deserialise(const SerialisedValue &node, const CoreData &data) +void Configuration::deserialise(const SerialisedValue &node) { setTemperature(toml::find_or(node, "temperature", defaultTemperature_)); requestedSizeFactor_ = toml::find_or(node, "sizeFactor", defaultSizeFactor_); diff --git a/src/classes/configuration.h b/src/classes/configuration.h index df0030b4b4..38fc39f518 100644 --- a/src/classes/configuration.h +++ b/src/classes/configuration.h @@ -22,7 +22,7 @@ class ProcessPool; class Species; // Configuration -class Configuration : public Serialisable +class Configuration : public Serialisable { public: Configuration(); @@ -230,5 +230,5 @@ class Configuration : public Serialisable // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &data) override; + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/classes/configuration_io.cpp b/src/classes/configuration_io.cpp deleted file mode 100644 index 83ec8e2e42..0000000000 --- a/src/classes/configuration_io.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "base/lineParser.h" -#include "base/sysFunc.h" -#include "classes/box.h" -#include "classes/configuration.h" -#include "classes/coreData.h" -#include "classes/pairPotential.h" -#include "classes/species.h" -#include - -// Write through specified LineParser -bool Configuration::serialise(LineParser &parser) const -{ - if (!parser.writeLineF("'{}' {} # nMolecules\n", name(), molecules_.size())) - return false; - - // Write unit cell (box) lengths and angles - const auto lengths = box().axisLengths(); - const auto angles = box().axisAngles(); - if (!parser.writeLineF("{:12e} {:12e} {:12e} {} {} {}\n", lengths.x, lengths.y, lengths.z, - appliedSizeFactor_.value_or(defaultSizeFactor_), requestedSizeFactor_.value_or(defaultSizeFactor_), - DissolveSys::btoa(box().type() == Box::BoxType::None))) - return false; - if (!parser.writeLineF("{:12e} {:12e} {:12e}\n", angles.x, angles.y, angles.z)) - return false; - - // Write total number of Molecules - if (!parser.writeLineF("{}\n", molecules_.size())) - return false; - - // Write Molecule types - write sequential Molecules with same type as single line - auto moleculeCount = 0; - const Species *lastType = nullptr; - for (const auto &molecule : molecules_) - { - // If the last Molecule's Species is the same as this one, increment counter and move on - if (lastType == molecule->species()) - { - ++moleculeCount; - continue; - } - - // Species is different between this molecule and the last - write this info, and reset the counter - if (lastType && (!parser.writeLineF("{} '{}'\n", moleculeCount, lastType->name()))) - return false; - moleculeCount = 1; - lastType = molecule->species(); - } - // Write final molecule count / type - if ((moleculeCount > 0) && (!parser.writeLineF("{} '{}'\n", moleculeCount, lastType->name()))) - return false; - - // Write all Atoms - for each write index and coordinates - if (!parser.writeLineF("{} # nAtoms\n", atoms_.size())) - return false; - for (const auto &i : atoms_) - { - if (!parser.writeLineF("{} {} {} {}\n", i.molecule()->arrayIndex(), i.r().x, i.r().y, i.r().z)) - return false; - } - - return true; -} - -// Read from specified LineParser -bool Configuration::deserialise(LineParser &parser, const CoreData &coreData, bool hasPotentials) -{ - // Clear current contents of Configuration - empty(); - - // Read configuration name and nMolecules - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - setName(parser.argsv(0)); - - /* - * Read box definition - * Lengths, along with atomic coordinates, reflect the applied size factor. - * Create box with unscaled lengths - they will be scaled according to the size factor at the end of the routine. - */ - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - if (parser.argd(3) > 1.0) - appliedSizeFactor_ = parser.argd(3); - else - appliedSizeFactor_ = std::nullopt; - requestedSizeFactor_ = parser.argd(4); - auto nonPeriodic = parser.argb(5); - const auto lengths = parser.arg3d(0) / appliedSizeFactor_.value_or(defaultSizeFactor_); - - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - const auto angles = parser.arg3d(0); - - createBoxAndCells(lengths, angles, nonPeriodic); - - // Read total number of Molecules to expect - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - const auto expectedNMols = parser.argi(0); - - // Read Species types for Molecules - auto nMolsRead = 0; - while (nMolsRead < expectedNMols) - { - // Read line containing number of molecules and Species name - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - - auto sp = coreData.findSpecies(DissolveSys::niceName(parser.argsv(1))); - if (!sp) - return Messenger::error("Unrecognised Species '{}' found in Configuration '{}' in restart file.\n", parser.argsv(1), - name()); - - // Set Species pointers for this range of Molecules - auto nMols = parser.argi(0); - for (auto n = 0; n < nMols; ++n) - addMolecule(sp); - - // Increase our counter - nMolsRead += parser.argi(0); - } - - // Read in Atoms - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nAtoms = parser.argi(0); - // Reserve space for the atoms, plus some buffer space - atoms_.reserve(nAtoms + std::min(1000, (nAtoms) >> 2)); - for (auto n = 0; n < nAtoms; ++n) - { - // Each line contains molecule ID and coordinates only - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - - atom(n).setR(parser.arg3d(1)); - } - - // Scale box and cells according to the applied size factor - auto appliedSF = appliedSizeFactor_.value_or(defaultSizeFactor_); - scaleBox({appliedSF, appliedSF, appliedSF}); - - // Update all relationships - updateObjectRelationships(); - - // If this an old-style configuration with no potentials we can end here - if (!hasPotentials) - return true; - - return true; -} diff --git a/src/classes/histogramSet.cpp b/src/classes/histogramSet.cpp index f3a67097fa..b50319d159 100644 --- a/src/classes/histogramSet.cpp +++ b/src/classes/histogramSet.cpp @@ -4,7 +4,6 @@ #include "classes/histogramSet.h" #include "base/lineParser.h" #include "classes/atomType.h" -#include "items/deserialisers.h" #include "math/mathFunc.h" #include "templates/algorithms.h" diff --git a/src/classes/isotopologue.h b/src/classes/isotopologue.h index 0f5fd4febe..706f667628 100644 --- a/src/classes/isotopologue.h +++ b/src/classes/isotopologue.h @@ -20,7 +20,7 @@ class CoreData; /* * Isotopologue Definition */ -class Isotopologue : public Serialisable<> +class Isotopologue : public Serialisable { public: Isotopologue(const Species *parent, std::string name = ""); diff --git a/src/classes/isotopologueSet.cpp b/src/classes/isotopologueSet.cpp index 110e4abcc8..89e20ed7b8 100644 --- a/src/classes/isotopologueSet.cpp +++ b/src/classes/isotopologueSet.cpp @@ -102,7 +102,7 @@ void IsotopologueSet::serialise(std::string tag, SerialisedValue &target) const } // Read values from a serialisable value -void IsotopologueSet::deserialise(const SerialisedValue &node, const CoreData &coreData) +void IsotopologueSet::deserialise(const SerialisedValue &node) { clear(); @@ -113,12 +113,6 @@ void IsotopologueSet::deserialise(const SerialisedValue &node, const CoreData &c toMap(topes, [&](const std::string &isoName, const SerialisedValue &population) { set[isoName] = population.as_floating(); }); }); - - // Need to resolve species - std::map speciesMap; - for (const auto &sp : coreData.species()) - speciesMap[std::string(sp.get()->name())] = sp.get(); - resolve(speciesMap); } // Resolve internal resolvable name references with supplied data diff --git a/src/classes/isotopologueSet.h b/src/classes/isotopologueSet.h index b0040d271e..8f29de028f 100644 --- a/src/classes/isotopologueSet.h +++ b/src/classes/isotopologueSet.h @@ -12,7 +12,7 @@ class Isotopologue; class LineParser; // IsotopologueSet - Isotopologues for one or more Species -class IsotopologueSet : public Serialisable, ResolvableContext +class IsotopologueSet : public Serialisable, ResolvableContext { public: IsotopologueSet() = default; @@ -54,7 +54,7 @@ class IsotopologueSet : public Serialisable, ResolvableContext // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; + void deserialise(const SerialisedValue &node) override; // Resolve internal resolvable name references with supplied data void resolve(const std::map &speciesInScope) override; }; diff --git a/src/classes/neutronWeights.cpp b/src/classes/neutronWeights.cpp index c0951aafc0..9cdfc5309b 100644 --- a/src/classes/neutronWeights.cpp +++ b/src/classes/neutronWeights.cpp @@ -7,7 +7,6 @@ #include "classes/isotopologueSet.h" #include "classes/species.h" #include "data/isotopes.h" -#include "items/deserialisers.h" #include "templates/algorithms.h" NeutronWeights::NeutronWeights(const std::map &speciesPopulations, diff --git a/src/classes/pairPotential.h b/src/classes/pairPotential.h index 42dfdffa4c..28b57e3198 100644 --- a/src/classes/pairPotential.h +++ b/src/classes/pairPotential.h @@ -13,7 +13,7 @@ class AtomType; // PairPotential Definition -class PairPotential : Serialisable<> +class PairPotential : public Serialisable { public: PairPotential(std::string_view nameI = {}, std::string_view nameJ = {}); @@ -222,5 +222,5 @@ class PairPotential : Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/classes/pairPotentialOverride.h b/src/classes/pairPotentialOverride.h index 7b45e49ac4..5041936afd 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 Serialisable { public: // Override Types @@ -58,5 +58,5 @@ class PairPotentialOverride : public Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/classes/partialSet.cpp b/src/classes/partialSet.cpp index 499cadb98c..b24c53a610 100644 --- a/src/classes/partialSet.cpp +++ b/src/classes/partialSet.cpp @@ -7,7 +7,6 @@ #include "classes/box.h" #include "classes/configuration.h" #include "classes/species.h" -#include "items/deserialisers.h" #include "math/interpolator.h" #include "nodes/exportData.h" #include "templates/algorithms.h" @@ -457,129 +456,6 @@ OptionalReferenceWrapper PartialSet::searchData1D(std::string_view * Serialisation */ -int readDataPoint(int argIndex, LineParser &parser, Data1D &data) -{ - data.values().push_back(parser.argd(argIndex++)); - if (data.valuesHaveErrors()) - data.errors().push_back(parser.argd(argIndex++)); - return argIndex; -} - -// Read data through specified LineParser -bool PartialSet::deserialise(LineParser &parser, const CoreData &coreData) -{ - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - fingerprint_ = parser.argsv(0); - triangular_ = parser.hasArg(1) ? parser.argb(1) : true; - - // Read species populations - realSpeciesPopulations_.clear(); - - // Write out species populations first - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nSpecies = parser.argi(0); - for (auto n = 0; n < nSpecies; ++n) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto *sp = coreData.findSpecies(parser.argsv(0)); - if (!sp) - return Messenger::error("Species '{}' not found.\n", parser.argsv(0)); - realSpeciesPopulations_[sp] = parser.argd(1); - } - - // Clear partials - partials_ = DoubleKeyedMap(triangular_); - boundPartials_ = DoubleKeyedMap(triangular_); - unboundPartials_ = DoubleKeyedMap(triangular_); - - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nPartials = parser.argi(0); - - // Read in individual partials - for (auto n = 0; n < nPartials; ++n) - { - // Read key - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto key = parser.args(0); - - if (!partials_.map()[key].deserialise(parser)) - return false; - if (!boundPartials_.map()[key].deserialise(parser)) - return false; - if (!unboundPartials_.map()[key].deserialise(parser)) - return false; - } - - // Read totals - if (!total_.deserialise(parser)) - return false; - if (!boundTotal_.deserialise(parser)) - return false; - if (!unboundTotal_.deserialise(parser)) - return false; - - return true; -} - -std::string writeDataPoint(int i, Data1D data) -{ - if (data.valuesHaveErrors()) - return std::format("{} {}", data.value(i), data.error(i)); - else - return std::format("{}", data.value(i)); -} - -// Write data through specified LineParser -bool PartialSet::serialise(LineParser &parser) const -{ - if (!parser.writeLineF("'{}' {}\n", fingerprint_, triangular_)) - return false; - - // Write out species populations first - if (!parser.writeLineF("{}\n", realSpeciesPopulations_.size())) - return false; - for (auto &[resolvableSpecies, population] : realSpeciesPopulations_) - if (!parser.writeLineF("{} {}\n", resolvableSpecies.name(), population)) - return false; - - // Write number of keys to expect - if (!parser.writeLineF("{}\n", partials_.size())) - return false; - - // Write partials using the full partials as the master key set - for (const auto &[key, partial] : partials_) - { - auto &bound = boundPartials_.map().at(key); - auto &unbound = unboundPartials_.map().at(key); - - // Write key - if (!parser.writeLineF("{}\n", key)) - return false; - - if (!partial.serialise(parser)) - return false; - if (!bound.serialise(parser)) - return false; - if (!unbound.serialise(parser)) - return false; - } - - // Write totals - if (!total_.serialise(parser)) - return false; - if (!boundTotal_.serialise(parser)) - return false; - if (!unboundTotal_.serialise(parser)) - return false; - - return true; -} - // Express as a serialisable value void PartialSet::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/classes/partialSet.h b/src/classes/partialSet.h index 57a881c358..5cac9541d1 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 : public Serialisable, ResolvableContext { public: PartialSet() = default; @@ -114,10 +114,6 @@ class PartialSet : public Serialisable<>, ResolvableContext * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser, const CoreData &coreData); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value diff --git a/src/classes/partialSetAccumulator.cpp b/src/classes/partialSetAccumulator.cpp index 7e4a8269b3..fe4e3f7302 100644 --- a/src/classes/partialSetAccumulator.cpp +++ b/src/classes/partialSetAccumulator.cpp @@ -102,123 +102,3 @@ bool PartialSetAccumulator::save(std::string_view prefix, std::string_view tag, return ExportDataNode::write(total_, std::format("{}-{}-total.{}", prefix, tag, suffix)); } - -/* - * Searchers - */ - -// Return SampledData1D with specified tag, if it exists -OptionalReferenceWrapper PartialSetAccumulator::searchSampledData1D(std::string_view tag) const -{ - auto fullIt = - std::find_if(partials_.begin(), partials_.end(), [tag](const auto &data) { return data.second.tag() == tag; }); - if (fullIt != partials_.end()) - return fullIt->second; - auto boundIt = std::find_if(boundPartials_.begin(), boundPartials_.end(), - [tag](const auto &data) { return data.second.tag() == tag; }); - if (boundIt != boundPartials_.end()) - return boundIt->second; - auto unboundIt = std::find_if(unboundPartials_.begin(), unboundPartials_.end(), - [tag](const auto &data) { return data.second.tag() == tag; }); - if (unboundIt != unboundPartials_.end()) - return unboundIt->second; - if (total_.tag() == tag) - return total_; - return {}; -} - -/* - * Serialisation - */ - -// Read data through specified LineParser -bool PartialSetAccumulator::deserialise(LineParser &parser) -{ - // Read size and number of accumulated data - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - const auto nPartials = parser.argi(0); - nAccumulated_ = parser.argi(1); - auto mirroredEquivalent = parser.argb(2); - - // Clear data - partials_ = DoubleKeyedMap(mirroredEquivalent); - boundPartials_ = DoubleKeyedMap(mirroredEquivalent); - unboundPartials_ = DoubleKeyedMap(mirroredEquivalent); - - if (nAccumulated_ == 0) - return true; - - // Read total function - if (!total_.deserialise(parser)) - return false; - - // Read in individual partials - for (auto n = 0; n < nPartials; ++n) - { - // Read key - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto key = parser.args(0); - - // Read full partial - auto &partial = partials_.map()[key]; - partial.initialise(total_.xAxis()); - if (!partial.serialiseValues(parser)) - return false; - - // Read bound partial - auto &boundPartial = boundPartials_.map()[key]; - boundPartial.initialise(total_.xAxis()); - if (!boundPartial.serialiseValues(parser)) - return false; - - // Read unbound partial - auto &unboundPartial = unboundPartials_.map()[key]; - unboundPartial.initialise(total_.xAxis()); - if (!unboundPartial.serialiseValues(parser)) - return false; - } - - return true; -} - -// Write data through specified LineParser -bool PartialSetAccumulator::serialise(LineParser &parser) const -{ - // Write size information - if (!parser.writeLineF("{} {} {} # nPartials, nAccumulated, mirroredEquivalent\n", partials_.size(), nAccumulated_, - partials_.mirroredAreEquivalent())) - return false; - if (nAccumulated_ == 0) - return true; - - // Write the total function first (abscissa and values) - if (!total_.serialise(parser)) - return false; - - // Write partials - for (auto &[key, fullPartial] : partials_) - { - // Locate the corresponding bound and unbound partials - if (!boundPartials_.map().contains(key)) - return Messenger::error("No bound partial exists in the accumulated partials.\n", key); - if (!unboundPartials_.map().contains(key)) - return Messenger::error("No unbound partial {} exists in the accumulated partials.\n", key); - - auto &partial = partials_.map().at(key); - auto &boundPartial = boundPartials_.map().at(key); - auto &unboundPartial = unboundPartials_.map().at(key); - - if (!parser.writeLineF("{}\n", key)) - return false; - if (!partial.serialiseValues(parser)) - return false; - if (!boundPartial.serialiseValues(parser)) - return false; - if (!unboundPartial.serialiseValues(parser)) - return false; - } - - return true; -} diff --git a/src/classes/partialSetAccumulator.h b/src/classes/partialSetAccumulator.h index a29162cf6f..634906092b 100644 --- a/src/classes/partialSetAccumulator.h +++ b/src/classes/partialSetAccumulator.h @@ -44,20 +44,4 @@ class PartialSetAccumulator const SampledData1D &total() const; // Save all partials and total (with errors) bool save(std::string_view prefix, std::string_view tag, std::string_view suffix, std::string_view abscissaUnits) const; - - /* - * Searchers - */ - public: - // Return SampledData1D with specified tag, if it exists - OptionalReferenceWrapper searchSampledData1D(std::string_view tag) const; - - /* - * Serialisation - */ - public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; }; diff --git a/src/classes/potentialSet.cpp b/src/classes/potentialSet.cpp index 1d36a770cd..d4568b7aa6 100644 --- a/src/classes/potentialSet.cpp +++ b/src/classes/potentialSet.cpp @@ -2,10 +2,7 @@ // Copyright (c) 2026 Team Dissolve and contributors #include "classes/potentialSet.h" -#include "base/lineParser.h" #include "classes/atomType.h" -#include "classes/configuration.h" -#include "items/deserialisers.h" PotentialSet::PotentialSet() { fingerprint_ = "NO_FINGERPRINT"; } diff --git a/src/classes/potentialSet.h b/src/classes/potentialSet.h index 8fd99b02fa..893685d346 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 Serialisable { public: PotentialSet(); diff --git a/src/classes/species.h b/src/classes/species.h index 1c1cf3718f..3f29449173 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 Serialisable { public: Species(std::string name = "Unnamed"); @@ -307,5 +307,5 @@ class Species : public Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/classes/speciesIntra.h b/src/classes/speciesIntra.h index 4ea00eb689..fb1dc66e93 100644 --- a/src/classes/speciesIntra.h +++ b/src/classes/speciesIntra.h @@ -14,7 +14,7 @@ class SpeciesAtom; class Species; // Base class for intramolecular interactions within Species -template class SpeciesIntra : public Serialisable<> +template class SpeciesIntra : public Serialisable { public: explicit SpeciesIntra(Species *parent, typename Functions::Form form) : parent_(parent), interactionPotential_(form) {}; diff --git a/src/classes/speciesSite.h b/src/classes/speciesSite.h index f80a0f0def..fb2526f999 100644 --- a/src/classes/speciesSite.h +++ b/src/classes/speciesSite.h @@ -22,7 +22,7 @@ class Species; class SpeciesAtom; // Species Site Definition -class SpeciesSite : public Serialisable<> +class SpeciesSite : public Serialisable { public: // Site Type diff --git a/src/classes/speciesSites.h b/src/classes/speciesSites.h index 19765564cc..d5fe075ce3 100644 --- a/src/classes/speciesSites.h +++ b/src/classes/speciesSites.h @@ -10,7 +10,7 @@ class SpeciesSite; class Species; // SpeciesSites - Sites from one or more Species -class SpeciesSites : public Serialisable<>, ResolvableContext +class SpeciesSites : public Serialisable, ResolvableContext { public: SpeciesSites() = default; diff --git a/src/classes/structure.h b/src/classes/structure.h index 79f084ec61..0dd41d3c43 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 Serialisable { public: Structure(); @@ -142,5 +142,5 @@ class Structure : public Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/expression/value.h b/src/expression/value.h index ae70babab3..954b168c5f 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 Serialisable { public: ExpressionValue(); diff --git a/src/expression/variable.h b/src/expression/variable.h index bfaa021194..c9e35cad5d 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 Serialisable { public: ExpressionVariable(const ExpressionValue &value = ExpressionValue()); @@ -48,5 +48,5 @@ class ExpressionVariable : public Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/gui/render/renderableData1D.cpp b/src/gui/render/renderableData1D.cpp index ee1a6405a3..2dae22e64f 100644 --- a/src/gui/render/renderableData1D.cpp +++ b/src/gui/render/renderableData1D.cpp @@ -5,7 +5,6 @@ #include "base/lineParser.h" #include "gui/render/renderableGroupManager.h" #include "gui/render/view.h" -#include "items/list.h" #include "math/sampledData1D.h" RenderableData1D::RenderableData1D(const Data1DBase &source) @@ -37,7 +36,8 @@ void RenderableData1D::validateDataSource(const GenericList &sourceList) if (source_) return; - source_ = sourceList.searchBase(tag_); + // TODO DISSOLVE2 + // source_ = sourceList.searchBase(tag_); } // Invalidate the current data source diff --git a/src/gui/render/renderableData2D.cpp b/src/gui/render/renderableData2D.cpp index 5d5d5ad358..d6d053a9e3 100644 --- a/src/gui/render/renderableData2D.cpp +++ b/src/gui/render/renderableData2D.cpp @@ -5,7 +5,6 @@ #include "base/lineParser.h" #include "gui/render/renderableGroupManager.h" #include "gui/render/view.h" -#include "items/list.h" #include "math/data2D.h" #include "templates/array2D.h" @@ -38,7 +37,8 @@ void RenderableData2D::validateDataSource(const GenericList &sourceList) if (source_) return; - source_ = sourceList.search(tag_); + // TODO DISSOLVE2 + // source_ = sourceList.search(tag_); } // Invalidate the current data source diff --git a/src/gui/render/renderableData3D.cpp b/src/gui/render/renderableData3D.cpp index 9562f587a3..58fff0a981 100644 --- a/src/gui/render/renderableData3D.cpp +++ b/src/gui/render/renderableData3D.cpp @@ -5,7 +5,6 @@ #include "base/lineParser.h" #include "gui/render/renderableGroupManager.h" #include "gui/render/view.h" -#include "items/list.h" #include "math/data3D.h" #include "templates/array2D.h" #include "templates/array3D.h" @@ -41,7 +40,8 @@ void RenderableData3D::validateDataSource(const GenericList &sourceList) if (source_) return; - source_ = sourceList.search(tag_); + // TODO DISSOLVE2 + // source_ = sourceList.search(tag_); } // Invalidate the current data source diff --git a/src/items/CMakeLists.txt b/src/items/CMakeLists.txt deleted file mode 100644 index db2b090087..0000000000 --- a/src/items/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_library( - items - deserialisers.cpp - legacy.cpp - list.cpp - producers.cpp - searchers.cpp - serialisers.cpp - deserialisers.h - legacy.h - list.h - producers.h - serialisers.h -) - -target_include_directories(items PRIVATE ${PROJECT_SOURCE_DIR}/src) -target_link_libraries(items PRIVATE base) diff --git a/src/items/deserialisers.cpp b/src/items/deserialisers.cpp deleted file mode 100644 index 6917f0dca3..0000000000 --- a/src/items/deserialisers.cpp +++ /dev/null @@ -1,251 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "items/deserialisers.h" -#include "base/lineParser.h" -#include "classes/braggReflection.h" -#include "classes/partialSet.h" -#include "classes/partialSetAccumulator.h" -#include "classes/potentialSet.h" -#include "items/legacy.h" -#include "math/data1D.h" -#include "math/data2D.h" -#include "math/data3D.h" -#include "math/histogram1D.h" -#include "math/histogram2D.h" -#include "math/histogram3D.h" -#include "math/integerHistogram1D.h" - -GenericItemDeserialiser::GenericItemDeserialiser() -{ - // PODs - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - std::any_cast(a) = parser.argb(0); - return true; - }); - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - std::any_cast(a) = parser.argd(0); - return true; - }); - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - std::any_cast(a) = parser.argi(0); - return true; - }); - - // Standard Classes / Containers - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - // NOTE Can't implicit cast streampos into the arg for readArg(), so assume long long int for now. - long long int pos; - if (!parser.readArg(pos)) - return false; - std::any_cast(a) = pos; - return true; - }); - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - std::any_cast(a) = parser.line(); - return true; - }); - registerDeserialiser>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - v.clear(); - v.resize(parser.argi(0)); - for (auto &n : v) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - n = parser.argd(0); - } - return true; - }); - registerDeserialiser>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - v.clear(); - v.resize(parser.argi(0)); - for (auto &n : v) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - n = parser.arg3d(0); - } - return true; - }); - - // Custom Classes - registerDeserialiser>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nRows = parser.argi(0), nColumns = parser.argi(1); - v.initialise(nRows, nColumns, parser.argb(2)); - for (auto &n : v) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - n = (parser.argsv(0)[0] == 'T' || parser.argsv(0)[0] == 't'); - } - return true; - }); - registerDeserialiser>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nRows = parser.argi(0), nColumns = parser.argi(1); - v.initialise(nRows, nColumns, parser.argb(2)); - for (auto &n : v) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - n = parser.argd(0); - } - return true; - }); - registerDeserialiser>>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast> &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nRows = parser.argi(0), nColumns = parser.argi(1); - v.initialise(nRows, nColumns, parser.argb(2)); - for (auto &data : v) - if (!GenericItemDeserialiser::deserialise>(data, parser, coreData)) - return false; - return true; - }); - registerDeserialiser>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - int nRows = parser.argi(0), nColumns = parser.argi(1); - v.initialise(nRows, nColumns, parser.argb(2)); - for (auto &n : v) - if (!n.deserialise(parser)) - return false; - return true; - }); - registerDeserialiser>( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nX = parser.argi(0), nY = parser.argi(1), nZ = parser.argi(2); - v.initialise(nX, nY, nZ); - for (auto &n : v) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - n = parser.argd(0); - } - return true; - }); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialiseCore); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser(simpleDeserialise); - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - v = parser.arg3i(0); - return true; - }); - registerDeserialiser( - [](std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - v = parser.arg3d(0); - return true; - }); - - // Containers of Custom Classes - registerDeserialiser>(vectorDeserialise); - - // Legacy Classes - registerLegacyDeserialiser(simpleDeserialiseCore); -} - -/* - * Deserialisers - */ - -// Deserialise object of specified type -bool GenericItemDeserialiser::deserialiseObject(std::any &a, LineParser &parser, const CoreData &coreData) const -{ - // Find a suitable deserialiser and call it - auto it = deserialisers_.find(a.type()); - if (it != deserialisers_.end()) - return (it->second)(a, parser, coreData); - - auto legacyIt = legacyDeserialisers_.find(a.type()); - if (legacyIt != legacyDeserialisers_.end()) - return (legacyIt->second)(a, parser, coreData); - - Messenger::exception("Item of type '{}' cannot be deserialised as no suitable deserialiser has been registered.\n", - a.type().name()); -} - -/* - * Instance - */ - -// Return the deserialiser instance -const GenericItemDeserialiser &GenericItemDeserialiser::instance() -{ - static GenericItemDeserialiser instance; - - return instance; -} - -// Deserialise supplied object -bool GenericItemDeserialiser::deserialise(std::any &a, LineParser &parser, const CoreData &coreData) -{ - return instance().deserialiseObject(a, parser, coreData); -} - -// Return whether supplied object is a legacy object -bool GenericItemDeserialiser::isLegacyObject(std::any &object) { return instance().hasLegacyDeserialiser(object); } diff --git a/src/items/deserialisers.h b/src/items/deserialisers.h deleted file mode 100644 index 981e59a19c..0000000000 --- a/src/items/deserialisers.h +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/lineParser.h" -#include "classes/coreData.h" -#include -#include -#include -#include -#include - -// GenericItem Deserialiser -class GenericItemDeserialiser -{ - private: - GenericItemDeserialiser(); - - public: - GenericItemDeserialiser(const GenericItemDeserialiser &) = delete; - GenericItemDeserialiser(GenericItemDeserialiser &&) = delete; - GenericItemDeserialiser &operator=(const GenericItemDeserialiser &) = delete; - GenericItemDeserialiser &operator=(GenericItemDeserialiser &&) = delete; - - /* - * Deserialisers - */ - private: - // Deserialisation function type - using DeserialiseFunction = std::function; - // Deserialisers for all data types - std::unordered_map deserialisers_, legacyDeserialisers_; - - private: - template static bool simpleDeserialise(std::any &a, LineParser &parser, const CoreData &coreData) - { - return std::any_cast(a).deserialise(parser); - } - template static bool simpleDeserialiseCore(std::any &a, LineParser &parser, const CoreData &coreData) - { - return std::any_cast(a).deserialise(parser, coreData); - } - template static bool vectorDeserialise(std::any &a, LineParser &parser, const CoreData &coreData) - { - auto &v = std::any_cast &>(a); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nItems = parser.argi(0); - v.resize(nItems); - for (auto &i : v) - if (!i.deserialise(parser)) - return false; - return true; - } - // Register deserialiser for specific class - template void registerDeserialiser(DeserialiseFunction func) { deserialisers_[typeid(T)] = std::move(func); } - // Register legacy deserialiser for specific class - template void registerLegacyDeserialiser(DeserialiseFunction func) - { - legacyDeserialisers_[typeid(T)] = std::move(func); - } - // Deserialise object of specified type - bool deserialiseObject(std::any &a, LineParser &parser, const CoreData &coreData) const; - // Deserialise templated object - template bool deserialiseObject(T &object, LineParser &parser, const CoreData &coreData) const - { - // Find a suitable deserialiser and call it - auto it = deserialisers_.find(typeid(T)); - if (it == deserialisers_.end()) - Messenger::exception("Item of type '{}' cannot be deserialised as no suitable deserialiser has been registered.\n", - typeid(T).name()); - - auto a = std::make_any(object); - if (!(it->second)(a, parser, coreData)) - return false; - object = std::move(std::any_cast(a)); - - return true; - } - // Return whether the supplied object has a legacy deserialiser - bool hasLegacyDeserialiser(std::any &object) const - { - return legacyDeserialisers_.find(object.type()) != legacyDeserialisers_.end(); - } - - /* - * Instance - */ - private: - // Return the deserialiser instance - static const GenericItemDeserialiser &instance(); - - /* - * Static Functions - */ - public: - // Deserialise templated object - template static bool deserialise(T &object, LineParser &parser) - { - static CoreData dummyCoreData; - return instance().deserialiseObject(object, parser, dummyCoreData); - } - template static bool deserialise(T &object, LineParser &parser, const CoreData &coreData) - { - return instance().deserialiseObject(object, parser, coreData); - } - // Deserialise supplied object - static bool deserialise(std::any &a, LineParser &parser, const CoreData &coreData); - // Return whether supplied object is a legacy object - static bool isLegacyObject(std::any &object); -}; diff --git a/src/items/item.h b/src/items/item.h deleted file mode 100644 index 45a0677778..0000000000 --- a/src/items/item.h +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include - -// Generic Item Definitions -namespace GenericItem -{ -// Item Data Typedef -using Type = std::tuple; -// Item Data Tuple Indices -enum ItemData -{ - AnyObject, - ClassName, - Version, - Flags -}; -// Item Flags -enum ItemFlag -{ - NoFlags = 0, /* No flags */ - InRestartFileFlag = 1, /* The item should be written to the restart file */ - IsReferencePointDataFlag = 2, /* The item was loaded as reference point data */ - ProtectedFlag = 4 /* The item will not be clear()'d unless forced */ -}; -// Retrieval Status -enum class ItemStatus -{ - Existing, - Created -}; -}; // namespace GenericItem diff --git a/src/items/legacy.cpp b/src/items/legacy.cpp deleted file mode 100644 index 4fa86bf98c..0000000000 --- a/src/items/legacy.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "items/legacy.h" - -// AtomTypeList (removed in 0.9.0) -bool LegacyAtomTypeListItem::deserialise(LineParser &parser, const CoreData &coreData) -{ - // First line is contains the number of items we must discard - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - return parser.skipLines(parser.argi(0)) == LineParser::Success; -} diff --git a/src/items/legacy.h b/src/items/legacy.h deleted file mode 100644 index e8324f4700..0000000000 --- a/src/items/legacy.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/lineParser.h" - -// Forward Declarations -class CoreData; - -// Legacy Dummy Classes -// Enable production and deserialisation in order to support legacy file read - -// AtomTypeList (removed in 0.9.0) -class LegacyAtomTypeListItem -{ - public: - // Discard data from specified LineParser - bool deserialise(LineParser &parser, const CoreData &coreData); -}; diff --git a/src/items/list.cpp b/src/items/list.cpp deleted file mode 100644 index 414dd3ae34..0000000000 --- a/src/items/list.cpp +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "items/list.h" -#include "items/deserialisers.h" -#include "items/serialisers.h" -#include "main/version.h" -#include -#include -#include - -// Static Singletons -GenericList::DeserialisableDataVersion GenericList::baseDataVersion_(GenericList::DeserialisableDataVersion::Current); - -// Clear all items (except those that are marked protected) -void GenericList::clear() -{ - for (auto it = items_.begin(); it != items_.end();) - if (!(std::get(it->second) & GenericItem::ProtectedFlag)) - items_.erase(it++); - else - ++it; -} - -// Clear all items, including protected items -void GenericList::clearAll() { items_.clear(); } - -// Return whether the named item is contained in the list -bool GenericList::contains(std::string_view name, std::string_view prefix) const -{ - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - return (it != items_.end()); -} - -// Return item list -const std::map &GenericList::items() const { return items_; } - -// Return the version of the named item from the list -int GenericList::version(std::string_view name, std::string_view prefix) const -{ - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - assert(it != items_.end()); - return std::get(it->second); -} - -// Remove named item -void GenericList::remove(std::string_view name, std::string_view prefix) -{ - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - if (it == items_.end()) - Messenger::exception("GenericList::remove() - No item named '{}' exists.\n", - prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - - items_.erase(it); -} - -// Remove all items with specified prefix -void GenericList::removeWithPrefix(std::string_view prefix) -{ - auto delimitedPrefix = std::format("{}//", prefix); - for (auto it = items_.begin(); it != items_.end();) - if (DissolveSys::startsWith(it->first, delimitedPrefix)) - items_.erase(it++); - else - ++it; -} - -// Rename item -void GenericList::rename(std::string_view oldName, std::string_view oldPrefix, std::string_view newName, - std::string_view newPrefix) -{ - std::string oldVarName = oldPrefix.empty() ? std::string(oldName) : std::format("{}//{}", oldPrefix, oldName); - std::string newVarName = newPrefix.empty() ? std::string(newName) : std::format("{}//{}", newPrefix, newName); - - auto it = items_.find(oldVarName); - if (it == items_.end()) - Messenger::exception("GenericList::rename() - No item named '{}' exists.\n", oldVarName); - - auto handle = items_.extract(oldVarName); - handle.key() = newVarName; - items_.insert(std::move(handle)); -} - -// Rename prefix of items -void GenericList::renamePrefix(std::string_view oldPrefix, std::string_view newPrefix) -{ - if (oldPrefix == newPrefix) - return; - - /* - * Because we are using a std::map there is no easy way to achieve a bulk renaming of keys. Anecdotal evidence of odd - * behaviour indicates that extracting and re-inserting in one loop does not causing segfaults or, at the very least, we - * don't actually rename all the target data. So, here we extract and rename matching items, with the loop restarting after - * every match and running until we get no match. This obviously isn't terribly efficient but the function is sparingly used - * and so the general performance impact will be minimal. - */ - auto delimitedPrefix = std::format("{}//", oldPrefix); - do - { - auto it = std::find_if(items_.begin(), items_.end(), [delimitedPrefix](const auto &item) - { return DissolveSys::startsWith(item.first, delimitedPrefix); }); - if (it == items_.end()) - break; - - auto handle = items_.extract(it); - handle.key() = std::format("{}//{}", newPrefix, DissolveSys::afterString(it->first, "//")); - items_.insert(std::move(handle)); - } while (true); -} - -// Prune all items with '@suffix' -void GenericList::pruneWithSuffix(std::string_view suffix) -{ - for (auto &[key, value] : items_) - if (DissolveSys::endsWith(key, suffix)) - items_.erase(key); -} - -/* - * Serialisation - */ - -// Return EnumOptions for DataVersion -EnumOptions GenericList::deserialisableDataVersions() -{ - return EnumOptions( - "DeserialisableDataVersion", - {{GenericList::DeserialisableDataVersion::Version08X, "v0.8."}, - {GenericList::DeserialisableDataVersion::Current, std::format("v{}", Version::semantic())}}); -} - -// Set current data version being deserialised by detecting it from the supplied string -void GenericList::setBaseDataVersionFromString(std::string_view s) -{ - // Search the supplied string for any of our defined DeserialisableDataVersion enumeration keywords - for (auto n = 0; n < deserialisableDataVersions().nOptions(); ++n) - { - if (s.find(deserialisableDataVersions().keywordByIndex(n)) != std::string::npos) - { - Messenger::print("Detected data version as {}.\n", deserialisableDataVersions().keywordByIndex(n)); - baseDataVersion_ = deserialisableDataVersions().enumerationByIndex(n); - return; - } - } - - Messenger::print("Unable to auto-detect data version - assuming current ({}).\n", Version::semantic()); - baseDataVersion_ = DeserialisableDataVersion::Current; -} - -// Return current data version being deserialised -GenericList::DeserialisableDataVersion GenericList::baseDataVersion() { return baseDataVersion_; } - -// Serialise all objects via the specified LineParser -bool GenericList::serialiseAll(LineParser &parser, std::string_view headerPrefix) const -{ - for (auto &[key, value] : items_) - { - // If it is not flagged to be saved in the restart file, skip it - if (!(std::get(value) & GenericItem::InRestartFileFlag)) - continue; - - if (!parser.writeLineF("{} {} {} {} {}\n", headerPrefix, key, std::get(value), - std::get(value), std::get(value))) - return false; - - // Find a suitable serialiser and call it - auto &data = std::get(value); - if (!GenericItemSerialiser::serialise(data, parser)) - return Messenger::error("Serialisation of item '{}' failed.\n", key); - } - - return true; -} - -// Deserialise an object from the LineParser into our map -bool GenericList::deserialise(LineParser &parser, CoreData &coreData, const std::string &name, const std::string &itemClass, - int dataVersion, int flags) -{ - // Create the item - items_[name] = GenericItem::Type(GenericItemProducer::create(itemClass), itemClass, dataVersion, flags); - auto &data = std::get(items_[name]); - - // Find its deserialiser and call it - if (!GenericItemDeserialiser::deserialise(data, parser, coreData)) - return Messenger::error("Deserialisation of item '{}' failed.\n", name); - - // Check for legacy objects - we don't store them in the items_ map - if (GenericItemDeserialiser::isLegacyObject(data)) - { - Messenger::warn("Legacy data '{}' ({}) will not be captured in written restart files.\n", name, itemClass); - items_.erase(name); - } - - return true; -} diff --git a/src/items/list.h b/src/items/list.h deleted file mode 100644 index de859ce87d..0000000000 --- a/src/items/list.h +++ /dev/null @@ -1,295 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/enumOptions.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" -#include "items/item.h" -#include "items/producers.h" -#include "items/searchers.h" -#include "templates/optionalRef.h" -#include -#include -#include - -// Generic List -class GenericList -{ - public: - GenericList() = default; - ~GenericList() = default; - - /* - * Child Items - */ - private: - // Map of items, where the tuple corresponds to - std::map items_; - - public: - // Clear all items (except those that are marked protected) - void clear(); - // Clear all items, including protected items - void clearAll(); - // Return whether the named item is contained in the list - bool contains(std::string_view name, std::string_view prefix = "") const; - // Return item list - const std::map &items() const; - // Return the version of the named item from the list - int version(std::string_view name, std::string_view prefix = "") const; - // Remove named item - void remove(std::string_view name, std::string_view prefix); - // Remove all items with specified prefix - void removeWithPrefix(std::string_view prefix); - // Rename item - void rename(std::string_view oldName, std::string_view oldPrefix, std::string_view newName, std::string_view newPrefix); - // Rename prefix of items - void renamePrefix(std::string_view oldPrefix, std::string_view newPrefix); - // Prune all items with '@suffix' - void pruneWithSuffix(std::string_view suffix); - - /* - * Item Creation - */ - public: - // Create or retrieve named item as templated type - template T &realise(std::string_view name, std::string_view prefix = "", int flags = GenericItem::NoFlags) - { - return realiseIf(name, prefix, flags).first; - } - // Create or retrieve named item as templated type, also returning whether it was created - template - std::pair realiseIf(std::string_view name, std::string_view prefix = "", - int flags = GenericItem::NoFlags) - { - // Construct full name - std::string varName = prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name); - - auto it = items_.find(varName); - if (it != items_.end()) - { - // Check type before we attempt to cast it - if (std::get(it->second).type() != typeid(T)) - Messenger::exception("GenericList::realise() - Item named '{}' exists, but has a different type " - "to that requested ('{}' vs '{}').\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name), - std::get(it->second).type().name(), typeid(T).name()); - - // Bump version of the item and return it - ++std::get(it->second); - return {std::any_cast(std::get(it->second)), GenericItem::ItemStatus::Existing}; - } - - // Create and return new item - items_.emplace(varName, - GenericItem::Type(GenericItemProducer::create(), GenericItemProducer::className(), 0, flags)); - auto &item = items_[varName]; - return {std::any_cast(std::get(item)), GenericItem::ItemStatus::Created}; - } - - /* - * Item Retrieval - */ - public: - // Return named (const) item as templated type - template const T &value(std::string_view name, std::string_view prefix = "") const - { - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - if (it == items_.end()) - Messenger::exception("GenericList::value() - Item named '{}' does not exist.\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name)); - - // Check type before we attempt to cast it - if (std::get(it->second).type() != typeid(T)) - Messenger::exception( - "GenericList::value() - Item named '{}' exists, but has a different type to that requested ('{}' vs '{}').\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name), - std::get(it->second).type().name(), typeid(T).name()); - - return std::any_cast(std::get(it->second)); - } - // Return copy of named item as templated type, or a default value - template T valueOr(std::string_view name, std::string_view prefix, T valueIfNotFound) const - { - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - if (it == items_.end()) - return valueIfNotFound; - - // Check type before we attempt to cast it - if (std::get(it->second).type() != typeid(T)) - Messenger::exception( - "GenericList::value() - Item named '{}' exists, but has a different type to that requested ('{}' vs '{}').\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name), - std::get(it->second).type().name(), typeid(T).name()); - - return std::any_cast(std::get(it->second)); - } - // Return named (const) item as templated type, if it exists - template OptionalReferenceWrapper valueIf(std::string_view name, std::string_view prefix = "") const - { - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - if (it == items_.end()) - return {}; - - // Check type before we attempt to cast it - if (std::get(it->second).type() != typeid(T)) - Messenger::exception( - "GenericList::valueIf() - Item named '{}' exists, but has a different type to that requested ('{}' vs '{}').\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name), - std::get(it->second).type().name(), typeid(T).name()); - - return std::any_cast(std::get(it->second)); - } - // Retrieve named item as templated type, assuming that it is going to be modified - template T &retrieve(std::string_view name, std::string_view prefix = "") - { - auto it = items_.find(prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name)); - if (it == items_.end()) - Messenger::exception("GenericList::retrieve() - Item named '{}' does not exist.\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name)); - - // Check type before we attempt to cast it - if (std::get(it->second).type() != typeid(T)) - Messenger::exception("GenericList::retrieve() - Item named '{}' exists, but has a different type " - "to that requested ('{}' vs '{}').\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name), - std::get(it->second).type().name(), typeid(T).name()); - - ++std::get(it->second); - return std::any_cast(std::get(it->second)); - } - // Return names of all items of the template type - template std::vector all() const - { - std::vector matches; - for (auto &[key, value] : items_) - if (std::get(value).type() == typeid(T)) - matches.emplace_back(key); - - return matches; - } - - /* - * Serialisation - */ - public: - // Data Versions - enum class DeserialisableDataVersion - { - Version08X, - Current - }; - // Return EnumOptions for DataVersion - static EnumOptions deserialisableDataVersions(); - - private: - // Current data version being deserialised - static DeserialisableDataVersion baseDataVersion_; - - public: - // Set current data version being deserialised by detecting it from the supplied string - static void setBaseDataVersionFromString(std::string_view s); - // Return current data version being deserialised - static DeserialisableDataVersion baseDataVersion(); - // Serialise all objects via the specified LineParser - bool serialiseAll(LineParser &parser, std::string_view headerPrefix) const; - // Deserialise an object from the LineParser into our map - bool deserialise(LineParser &parser, CoreData &coreData, const std::string &name, const std::string &itemClass, - int dataVersion = 0, int flags = 0); - - /* - * Searchers - */ - public: - // Search for an object or child of the specified name - template OptionalReferenceWrapper search(std::string_view name, std::string_view prefix = "") const - { - auto varName = prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name); - auto varNamePath = varName + "//"; - for (auto &[key, value] : items_) - { - // Match name - if (varName == key) - { - // Check type before we attempt to cast it - if (std::get(value).type() != typeid(T)) - Messenger::exception("GenericList::search() - Item named '{}' exists, but has a different " - "type to that requested ('{}' vs '{}').\n", - prefix.empty() ? name : std::format("{}//{}", prefix, name), - std::get(value).type().name(), typeid(T).name()); - - return std::any_cast(std::get(value)); - } - - // Sub-search in the item if its name plus "//" matches the beginning of the var name - if (DissolveSys::startsWith(varName, key + "//")) - { - auto dataName = varName; - dataName.erase(0, key.length() + 2); - auto optRef = GenericItemSearcher::search(std::get(value), dataName); - if (optRef) - return optRef; - } - } - - return {}; - } - // Convert supplied object reference to base-class reference - template const B &convertBase(const T &a, std::string_view varName) const - { - // Perform dynamic_cast to base class (B) and check - OptionalReferenceWrapper base = dynamic_cast(a); - if (!base) - Messenger::exception("GenericList::convertBase() - Item named '{}' exists, but cannot be cast to the" - "requested base type '{}' (item type is '{}').\n", - varName, typeid(B).name(), typeid(T).name()); - return base->get(); - } - // Search for an object or child of the specified name and possible types, casting to the given base class - template - OptionalReferenceWrapper searchBase(std::string_view name, std::string_view prefix = "") const - { - auto varName = prefix.empty() ? std::string(name) : std::format("{}//{}", prefix, name); - auto varNamePath = varName + "//"; - for (auto &[key, value] : items_) - { - // Match name - if (varName == key) - { - auto &object = std::get(value); - OptionalReferenceWrapper optRef; - if (object.type() == typeid(T1)) - optRef = convertBase(std::any_cast(object), varName); - else if (object.type() == typeid(T2)) - optRef = convertBase(std::any_cast(object), varName); - - // If we have no valid result, then throw since the data type is not valid - if (!optRef) - Messenger::exception("GenericList::searchBase() - Item named '{}' exists, but has a different " - "type to those allowed requested ('{}' vs '{}' or '{}').\n", - varName, object.type().name(), typeid(T1).name(), typeid(T2).name()); - return optRef; - } - - // Sub-search in the item if its name plus "//" matches the beginning of the var name - if (DissolveSys::startsWith(varName, key + "//")) - { - auto dataName = varName; - dataName.erase(0, key.length() + 2); - auto &object = std::get(value); - - OptionalReferenceWrapper optRefT1 = GenericItemSearcher::search(object, dataName); - if (optRefT1) - return convertBase(optRefT1->get(), varName); - - OptionalReferenceWrapper optRefT2 = GenericItemSearcher::search(object, dataName); - if (optRefT2) - return convertBase(optRefT2->get(), varName); - } - } - - return {}; - } -}; diff --git a/src/items/producers.cpp b/src/items/producers.cpp deleted file mode 100644 index 7389f23952..0000000000 --- a/src/items/producers.cpp +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "items/producers.h" -#include "classes/braggReflection.h" -#include "classes/kVector.h" -#include "classes/partialSet.h" -#include "classes/partialSetAccumulator.h" -#include "classes/potentialSet.h" -#include "classes/xRayWeights.h" -#include "items/legacy.h" -#include "math/data1D.h" -#include "math/data2D.h" -#include "math/data3D.h" -#include "math/histogram1D.h" -#include "math/histogram2D.h" -#include "math/histogram3D.h" -#include "math/integerHistogram1D.h" -#include - -GenericItemProducer::GenericItemProducer() -{ - // PODs - registerProducer("bool"); - registerProducer("double"); - registerProducer("int"); - - // Standard Classes / Containers - registerProducer("std::string"); - registerProducer("streampos"); - registerProducer>("std::vector"); - registerProducer>("std::vector"); - - // Custom Classes / Containers - registerProducer>("Array2D"); - registerProducer>>("Array2D>"); - registerProducer>("Array2D"); - registerProducer>("Array3D"); - registerProducer("Data1D"); - registerProducer("Data2D"); - registerProducer("Data3D"); - registerProducer>("DoubleKeyedMap"); - registerProducer>("DoubleKeyedMap"); - registerProducer("Histogram1D"); - registerProducer("Histogram2D"); - registerProducer("Histogram3D"); - registerProducer("IntegerHistogram1D"); - registerProducer("PartialSet"); - registerProducer("PartialSetAccumulator"); - registerProducer("PotentialSet"); - registerProducer("SampledData1D"); - registerProducer("SampledDouble"); - registerProducer("SampledVector"); - registerProducer("Vector3i"); - registerProducer("Vector3"); - registerProducer("XRayWeights"); - - // Containers of Custom Classes - registerProducer>("std::vector"); - registerProducer>("std::vector"); - - // Legacy Classes - registerProducer("AtomTypeList"); -} - -/* - * Producers - */ - -// Produce object of specified type -std::any GenericItemProducer::produce(const std::type_info &objectType) const -{ - auto it = producers_.find(objectType); - if (it == producers_.end()) - Messenger::exception( - "A producer has not been registered for type '{}', so a new object of this type cannot be created.\n", - objectType.name()); - - return (it->second)(); -} - -// Produce object of named class -std::any GenericItemProducer::produce(const std::string_view className) const -{ - auto it = - std::find_if(classNames_.begin(), classNames_.end(), [className](auto &item) { return item.second == className; }); - if (it == classNames_.end()) - Messenger::exception( - "A producer has not been registered for class name '{}', so a new object of this type cannot be created.\n", - className); - - auto producer = producers_.find(it->first); - return (producer->second)(); -} - -// Return class name for specified type -std::string GenericItemProducer::className(const std::type_info &objectType) const -{ - auto it = classNames_.find(objectType); - if (it == classNames_.end()) - Messenger::exception("Class name has not been registered for type '{}'.\n", objectType.name()); - - return it->second; -} - -/* - * Instance - */ - -// Return the producer instance -const GenericItemProducer &GenericItemProducer::instance() -{ - static GenericItemProducer instance; - - return instance; -} - -/* - * Static Functions - */ - -// Create new item of the named class type -std::any GenericItemProducer::create(std::string_view className) { return instance().produce(className); } diff --git a/src/items/producers.h b/src/items/producers.h deleted file mode 100644 index 2d667f9967..0000000000 --- a/src/items/producers.h +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include -#include -#include -#include -#include - -// GenericItem Producer -class GenericItemProducer -{ - private: - GenericItemProducer(); - - public: - GenericItemProducer(const GenericItemProducer &) = delete; - GenericItemProducer(GenericItemProducer &&) = delete; - GenericItemProducer &operator=(const GenericItemProducer &) = delete; - GenericItemProducer &operator=(GenericItemProducer &&) = delete; - - /* - * Producers - */ - private: - // Producer function type - using ProducerFunction = std::function; - // Producers for all data types - std::unordered_map classNames_; - std::unordered_map producers_; - - private: - // Register producer for specific class - template void registerProducer(std::string className) - { - producers_[typeid(T)] = []() { return T(); }; - classNames_[typeid(T)] = std::move(className); - } - // Produce object of specified type - std::any produce(const std::type_info &objectType) const; - // Produce object of named class - std::any produce(const std::string_view className) const; - // Return class name for specified type - std::string className(const std::type_info &objectType) const; - - /* - * Instance - */ - private: - // Return the producer instance - static const GenericItemProducer &instance(); - - /* - * Static Functions - */ - public: - // Create new item via template - template static std::any create() { return instance().produce(typeid(T)); } - // Create new item of the named class type - static std::any create(std::string_view className); - // Return registered class name for template type - template static std::string className() { return instance().className(typeid(T)); } -}; diff --git a/src/items/searchers.cpp b/src/items/searchers.cpp deleted file mode 100644 index 08a4efbb1d..0000000000 --- a/src/items/searchers.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "classes/partialSet.h" -#include "classes/partialSetAccumulator.h" -#include "items/list.h" -#include "math/data1D.h" -#include "math/data2D.h" -#include "math/data3D.h" -#include "math/sampledData1D.h" -#include "math/sampledDouble.h" - -/* - * Data1D - */ - -template <> GenericItemSearcher::GenericItemSearcher() -{ - // Custom Classes - registerSearcher>( - [](const std::any &a, std::string_view dataName) - { - auto &array = std::any_cast &>(a); - auto it = std::find_if(array.begin(), array.end(), [dataName](const auto &data) { return dataName == data.tag(); }); - return it == array.end() ? OptionalReferenceWrapper() : OptionalReferenceWrapper(*it); - }); - registerSearcher>( - [](const std::any &a, std::string_view dataName) - { - auto &map = std::any_cast &>(a); - auto it = - std::find_if(map.begin(), map.end(), [dataName](const auto &pair) { return dataName == pair.second.tag(); }); - return it == map.end() ? OptionalReferenceWrapper() - : OptionalReferenceWrapper(it->second); - }); - registerSearcher( - [](const std::any &a, std::string_view dataName) - { - auto &ps = std::any_cast(a); - return ps.searchData1D(dataName); - }); -} - -/* - * Data2D - */ - -template <> GenericItemSearcher::GenericItemSearcher() {} - -/* - * Data3D - */ - -template <> GenericItemSearcher::GenericItemSearcher() {} - -/* - * SampledData1D - */ - -template <> GenericItemSearcher::GenericItemSearcher() -{ - // Custom Classes - registerSearcher>( - [](const std::any &a, std::string_view dataName) - { - auto &array = std::any_cast &>(a); - auto it = std::find_if(array.begin(), array.end(), [dataName](const auto &data) { return dataName == data.tag(); }); - return it == array.end() ? OptionalReferenceWrapper() - : OptionalReferenceWrapper(*it); - }); - registerSearcher( - [](const std::any &a, std::string_view dataName) - { - auto &psa = std::any_cast(a); - return psa.searchSampledData1D(dataName); - }); -} - -/* - * SampledDouble - */ - -template <> GenericItemSearcher::GenericItemSearcher() {} - -/* - * SampledVector - */ - -template <> GenericItemSearcher::GenericItemSearcher() {} diff --git a/src/items/searchers.h b/src/items/searchers.h deleted file mode 100644 index d39f547315..0000000000 --- a/src/items/searchers.h +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "classes/partialSet.h" -#include "items/item.h" -#include "math/data1D.h" -#include "templates/optionalRef.h" -#include -#include -#include -#include - -// GenericItem Searcher -template class GenericItemSearcher -{ - private: - GenericItemSearcher(); - - public: - GenericItemSearcher(const GenericItemSearcher &) = delete; - GenericItemSearcher(GenericItemSearcher &&) = delete; - GenericItemSearcher &operator=(const GenericItemSearcher &) = delete; - GenericItemSearcher &operator=(GenericItemSearcher &&) = delete; - - /* - * Searchers - */ - private: - // Searcher function type - using SearcherFunction = std::function(const std::any &a, std::string_view dataName)>; - // Searchers for data types - std::unordered_map searchers_; - - private: - // Register searcher for specific class - template void registerSearcher(SearcherFunction func) { searchers_[typeid(T)] = std::move(func); }; - // Search for data of templated type - OptionalReferenceWrapper searchObject(const std::any &a, std::string_view dataName) const - { - // Find a suitable searcher and call it - auto it = searchers_.find(a.type()); - if (it == searchers_.end()) - return {}; - - return (it->second)(a, dataName); - } - - /* - * Instance - */ - private: - // Return the searcher instance - static const GenericItemSearcher &instance() - { - static GenericItemSearcher instance; - - return instance; - } - - /* - * Static Functions - */ - public: - // Search for data item of templated type in supplied object - static OptionalReferenceWrapper search(const std::any &a, std::string_view dataName) - { - return instance().searchObject(a, dataName); - } -}; diff --git a/src/items/serialisers.cpp b/src/items/serialisers.cpp deleted file mode 100644 index 994b2dcd04..0000000000 --- a/src/items/serialisers.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "items/serialisers.h" -#include "base/lineParser.h" -#include "classes/braggReflection.h" -#include "classes/kVector.h" -#include "classes/partialSet.h" -#include "classes/partialSetAccumulator.h" -#include "classes/potentialSet.h" -#include "math/data1D.h" -#include "math/data2D.h" -#include "math/data3D.h" -#include "math/histogram1D.h" -#include "math/histogram2D.h" -#include "math/histogram3D.h" -#include "math/integerHistogram1D.h" - -GenericItemSerialiser::GenericItemSerialiser() -{ - // PODs - registerSerialiser([](const std::any &a, LineParser &parser) - { return parser.writeLineF("{}\n", DissolveSys::btoa(std::any_cast(a))); }); - registerSerialiser([](const std::any &a, LineParser &parser) - { return parser.writeLineF("{}\n", std::any_cast(a)); }); - registerSerialiser([](const std::any &a, LineParser &parser) - { return parser.writeLineF("{}\n", std::any_cast(a)); }); - - // Standard Classes / Containers - registerSerialiser([](const std::any &a, LineParser &parser) - { return parser.writeLineF("{}\n", std::any_cast(a)); }); - registerSerialiser([](const std::any &a, LineParser &parser) - { return parser.writeLineF("{}\n", (std::size_t)(std::any_cast(a))); }); - registerSerialiser>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{}\n", v.size())) - return false; - for (auto &n : v) - if (!parser.writeLineF("{}\n", n)) - return false; - return true; - }); - registerSerialiser>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{}\n", v.size())) - return false; - for (auto &n : v) - if (!parser.writeLineF("{} {} {}\n", n.x, n.y, n.z)) - return false; - return true; - }); - - // Custom Classes / Containers - registerSerialiser>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{} {} {}\n", v.nRows(), v.nColumns(), DissolveSys::btoa(v.halved()))) - return false; - for (auto &n : v) - if (!parser.writeLineF("{}\n", n ? 'T' : 'F')) - return false; - return true; - }); - registerSerialiser>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{} {} {}\n", v.nRows(), v.nColumns(), DissolveSys::btoa(v.halved()))) - return false; - for (auto &n : v) - if (!parser.writeLineF("{}\n", n)) - return false; - return true; - }); - registerSerialiser>>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast> &>(a); - if (!parser.writeLineF("{} {} {}\n", v.nRows(), v.nColumns(), DissolveSys::btoa(v.halved()))) - return false; - for (auto &data : v) - if (!GenericItemSerialiser::serialise>(data, parser)) - return false; - return true; - }); - registerSerialiser>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{} {} {}\n", v.nRows(), v.nColumns(), DissolveSys::btoa(v.halved()))) - return false; - for (auto &n : v) - if (!n.serialise(parser)) - return false; - return true; - }); - registerSerialiser>( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{} {} {}\n", v.nX(), v.nY(), v.nZ())) - return false; - for (auto &n : v) - if (!parser.writeLineF("{}\n", n)) - return false; - return true; - }); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser(simpleSerialise); - registerSerialiser( - [](const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast(a); - return parser.writeLineF("{} {} {}\n", v.x, v.y, v.z); - }); - - // Containers of Custom Classes - registerSerialiser>(vectorSerialise); -} - -/* - * Instance - */ - -// Return the serialiser instance -const GenericItemSerialiser &GenericItemSerialiser::instance() -{ - static GenericItemSerialiser instance; - - return instance; -} - -/* - * Serialisers - */ - -// Serialise object of specified type -bool GenericItemSerialiser::serialiseObject(const std::any &a, LineParser &parser) const -{ - // Find a suitable serialiser and call it - auto it = serialisers_.find(a.type()); - if (it == serialisers_.end()) - Messenger::exception("Item of type '{}' cannot be serialised as no suitable serialiser has been registered.\n", - a.type().name()); - - return (it->second)(a, parser); -} - -/* - * Static Functions - */ - -// Serialise supplied object -bool GenericItemSerialiser::serialise(const std::any &a, LineParser &parser) { return instance().serialiseObject(a, parser); } diff --git a/src/items/serialisers.h b/src/items/serialisers.h deleted file mode 100644 index 6bcc7c19df..0000000000 --- a/src/items/serialisers.h +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/lineParser.h" -#include "classes/coreData.h" -#include -#include -#include - -// GenericItem Serialiser -class GenericItemSerialiser -{ - private: - GenericItemSerialiser(); - - public: - GenericItemSerialiser(const GenericItemSerialiser &) = delete; - GenericItemSerialiser(GenericItemSerialiser &&) = delete; - GenericItemSerialiser &operator=(const GenericItemSerialiser &) = delete; - GenericItemSerialiser &operator=(GenericItemSerialiser &&) = delete; - - /* - * Serialisers - */ - private: - // Serialisation function type - using SerialiseFunction = std::function; - // Serialisers for all data types - std::unordered_map serialisers_; - - private: - template static bool simpleSerialise(const std::any &a, LineParser &parser) - { - return std::any_cast(a).serialise(parser); - } - template static bool vectorSerialise(const std::any &a, LineParser &parser) - { - const auto &v = std::any_cast &>(a); - if (!parser.writeLineF("{} # size\n", v.size())) - return false; - for (const auto &i : v) - if (!i.serialise(parser)) - return false; - return true; - } - // Register serialiser for specific class - template void registerSerialiser(SerialiseFunction func) { serialisers_[typeid(T)] = std::move(func); } - // Serialise object of specified type - bool serialiseObject(const std::any &a, LineParser &parser) const; - // Serialise templated object - template bool serialiseObject(const T &object, LineParser &parser) const - { - // Find a suitable serialiser and call it - auto it = serialisers_.find(typeid(T)); - if (it == serialisers_.end()) - Messenger::exception("Item of type '{}' cannot be serialised as no suitable serialiser has been registered.\n", - typeid(T).name()); - - return (it->second)(object, parser); - } - - /* - * Instance - */ - private: - // Return the serialiser instance - static const GenericItemSerialiser &instance(); - - /* - * Static Functions - */ - public: - // Serialise templated object - template static bool serialise(const T &object, LineParser &parser) - { - return instance().serialiseObject(object, parser); - } - // Serialise supplied object - static bool serialise(const std::any &a, LineParser &parser); -}; diff --git a/src/keywords/CMakeLists.txt b/src/keywords/CMakeLists.txt deleted file mode 100644 index 099e7d1326..0000000000 --- a/src/keywords/CMakeLists.txt +++ /dev/null @@ -1,55 +0,0 @@ -add_library( - keywords - base.cpp - bool.cpp - configuration.cpp - configurationVector.cpp - double.cpp - elementVector.cpp - expression.cpp - function1D.cpp - integer.cpp - isotopologueSet.cpp - optionalDouble.cpp - optionalInt.cpp - organiser.cpp - range.cpp - rangeVector.cpp - species.cpp - speciesSite.cpp - speciesSiteVector.cpp - speciesVector.cpp - stdString.cpp - store.cpp - vec3Double.cpp - vec3Integer.cpp - base.h - bool.h - configuration.h - configurationVector.h - double.h - elementVector.h - enumOptions.h - expression.h - function1D.h - integer.h - interactionPotential.h - isotopologueSet.h - optionalDouble.h - optionalInt.h - organiser.h - range.h - species.h - speciesSite.h - speciesSiteVector.h - speciesVector.h - stdString.h - store.h - rangeVector.h - vec3Double.h - vec3Integer.h - vec3Labels.h -) - -target_include_directories(keywords PRIVATE ${PROJECT_SOURCE_DIR}/src) -target_link_libraries(keywords PRIVATE base) diff --git a/src/keywords/base.cpp b/src/keywords/base.cpp deleted file mode 100644 index c52a0c8188..0000000000 --- a/src/keywords/base.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/base.h" -#include "base/messenger.h" - -KeywordBase::KeywordBase(const std::type_index typeIndex) : typeIndex_(typeIndex) {} - -/* - * Keyword Description - */ - -// Set base keyword information -void KeywordBase::setBaseInfo(std::string_view name, std::string_view description) -{ - name_ = name; - description_ = description; -} - -// Return typeindex for the keyword -const std::type_index KeywordBase::typeIndex() const { return typeIndex_; } - -// Return keyword name -std::string_view KeywordBase::name() const { return name_; } - -// Return keyword description -std::string_view KeywordBase::description() const { return description_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int KeywordBase::minArguments() const { return 1; } - -// Return maximum number of arguments accepted -std::optional KeywordBase::maxArguments() const { return 1; } - -// Check number of arguments provided to keyword -bool KeywordBase::validNArgs(int nArgsProvided) const -{ - if (nArgsProvided < minArguments()) - return Messenger::error("Not enough arguments given to keyword '{}'.\n", name()); - if (maxArguments() && (nArgsProvided > maxArguments().value())) - return Messenger::error("Too many arguments given to keyword '{}'.\n", name()); - - return true; -} - -/* - * GUI Signalling - */ - -// Set signals to be emitted (via Qt) when editing this keyword in the GUI -void KeywordBase::setEditSignals(Flags editSignals) { signals_ += editSignals; } - -// Return signals to be emitted (via Qt) when editing this keyword in the GUI -Flags KeywordBase::editSignals() const { return signals_; } - -/* - * Object Management - */ - -// Prune any references to the supplied AtomType in the contained data -void KeywordBase::removeReferencesTo(std::shared_ptr at) -{ - // Default action - ignore -} - -// Prune any references to the supplied Configuration in the contained data -void KeywordBase::removeReferencesTo(Configuration *cfg) -{ - // Default action - ignore -} - -// Prune any references to the supplied Isotopologue in the contained data -void KeywordBase::removeReferencesTo(Isotopologue *iso) -{ - // Default action - ignore -} - -// Prune any references to the supplied Module in the contained data -void KeywordBase::removeReferencesTo(Module *module) -{ - // Default action - ignore -} - -// Prune any references to the supplied Species in the contained data -void KeywordBase::removeReferencesTo(Species *sp) -{ - // Default action - ignore -} - -// Prune any references to the supplied SpeciesSite in the contained data -void KeywordBase::removeReferencesTo(SpeciesSite *spSite) -{ - // Default action - ignore -} diff --git a/src/keywords/base.h b/src/keywords/base.h deleted file mode 100644 index 6673dd1435..0000000000 --- a/src/keywords/base.h +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/serialiser.h" -#include "templates/flags.h" -#include -#include -#include -#include -#include -#include - -// Forward Declarations -class AtomType; -class Configuration; -class CoreData; -class Isotopologue; -class LineParser; -class Module; -class GeneratorNode; -class Species; -class SpeciesSite; - -// Keyword Base Class -class KeywordBase : public Serialisable -{ - public: - KeywordBase(const std::type_index typeIndex); - virtual ~KeywordBase() = default; - - /* - * Keyword Description - */ - private: - // Type index of derived class - const std::type_index typeIndex_; - // Keyword name - std::string name_; - // Description of keyword, if any - std::string description_; - - public: - // Set base keyword information - void setBaseInfo(std::string_view name, std::string_view description); - // Return typeindex for the keyword - const std::type_index typeIndex() const; - // Set option mask - void setOptionMask(int optionMask); - // Return keyword name - std::string_view name() const; - // Return keyword description - std::string_view description() const; - - /* - * Arguments - */ - public: - // Has not changed from initial value - virtual bool isDefault() const { return false; } - // Return minimum number of arguments accepted - virtual int minArguments() const; - // Return maximum number of arguments accepted - virtual std::optional maxArguments() const; - // Check number of arguments provided to keyword - bool validNArgs(int nArgsProvided) const; - // Deserialise from supplied LineParser, starting at given argument offset - virtual bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) = 0; - // Serialise data to specified LineParser - virtual bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix = "") const = 0; - // Express as a serialisable value - virtual void serialise(std::string tag, SerialisedValue &target) const override = 0; - // Read values from a serialisable value - virtual void deserialise(const SerialisedValue &node, const CoreData &coreData) override {}; - - /* - * Keyword Types - */ - public: - // Keyword Types - enum class KeywordType - { - Standard, /* Standard keyword */ - Restartable, /* Standard keyword, captured in restart file */ - Target, /* Target keyword */ - Deprecated /* Deprecated keyword (not captured in restart file) */ - }; - - /* - * Parse Result - */ - public: - // Keyword Parse Result - enum class ParseResult - { - Unrecognised, - Deprecated, - Failed, - Success - }; - - /* - * GUI Signalling - */ - public: - // Keyword Signals - enum KeywordSignal - { - RecreateRenderables, - ReloadExternalData, - ClearModuleData, - RunSetUp - }; - - private: - // Signals to be emitted (via Qt) when editing this keyword in the GUI - Flags signals_; - - public: - // Set signals to be emitted (via Qt) when editing this keyword in the GUI - void setEditSignals(Flags editSignals); - // Return signals to be emitted (via Qt) when editing this keyword in the GUI - Flags editSignals() const; - - public: - // Prune any references to the supplied AtomType in the contained data - virtual void removeReferencesTo(std::shared_ptr at); - // Prune any references to the supplied Configuration in the contained data - virtual void removeReferencesTo(Configuration *cfg); - // Prune any references to the supplied Isotopologue in the contained data - virtual void removeReferencesTo(Isotopologue *iso); - // Prune any references to the supplied Module in the contained data - virtual void removeReferencesTo(Module *module); - // Prune any references to the supplied Species in the contained data - virtual void removeReferencesTo(Species *sp); - // Prune any references to the supplied SpeciesSite in the contained data - virtual void removeReferencesTo(SpeciesSite *spSite); -}; diff --git a/src/keywords/bool.cpp b/src/keywords/bool.cpp deleted file mode 100644 index 75aba6a5d7..0000000000 --- a/src/keywords/bool.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/bool.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" - -BoolKeyword::BoolKeyword(bool &data) : KeywordBase(typeid(this)), data_(data), default_(data) {} - -/* - * Data - */ - -// Has not changed from initial value -bool BoolKeyword::isDefault() const { return data_ == default_; } - -// Set data -bool BoolKeyword::setData(bool value) -{ - data_ = value; - set_ = true; - - return true; -} - -// Return data -const bool &BoolKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool BoolKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg)) - { - data_ = parser.argb(startArg); - set_ = true; - - return true; - } - return false; -} - -// Serialise data to specified LineParser -bool BoolKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!set_) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, DissolveSys::btoa(data_)); -} - -// Express as a serialisable value -void BoolKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void BoolKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_ = node.as_boolean(); } diff --git a/src/keywords/bool.h b/src/keywords/bool.h deleted file mode 100644 index 3b84faa3f4..0000000000 --- a/src/keywords/bool.h +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Keyword managing Bool data -class BoolKeyword : public KeywordBase -{ - public: - explicit BoolKeyword(bool &data); - ~BoolKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - bool &data_; - // Initial value - const bool default_; - // Whether the data has been set - bool set_{false}; - - public: - // Has not changed from initial value - bool isDefault() const override; - // Set data - bool setData(bool value); - // Return data - const bool &data() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/configuration.cpp b/src/keywords/configuration.cpp deleted file mode 100644 index 49a30b127a..0000000000 --- a/src/keywords/configuration.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/configuration.h" -#include "base/lineParser.h" -#include "classes/configuration.h" -#include "classes/coreData.h" - -ConfigurationKeyword::ConfigurationKeyword(Configuration *&data) : KeywordBase(typeid(this)), data_(data) {} - -/* - * Data - */ - -// Return reference to data -Configuration *&ConfigurationKeyword::data() { return data_; } -Configuration *&ConfigurationKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool ConfigurationKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Find target Configuration (first argument) - data_ = coreData.findConfiguration(parser.argsv(startArg)); - if (!data_) - return Messenger::error("Error setting Configuration - no Configuration named '{}' exists.\n", parser.argsv(startArg)); - - return true; -} - -// Serialise data to specified LineParser -bool ConfigurationKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (data_ && !parser.writeLineF("{}{} '{}'\n", prefix, keywordName, data_->name())) - return false; - - return true; -} - -/* - * Object Management - */ - -// Prune any references to the supplied Configuration in the contained data -void ConfigurationKeyword::removeReferencesTo(Configuration *cfg) -{ - if (data_ == cfg) - data_ = nullptr; -} - -// Express as a serialisable value -void ConfigurationKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - // isDefault is checked before serialisation of keywords - // so we have checked for the null pointer - assert(data_); - target[tag] = data_->name(); -} - -// Read values from a serialisable value -void ConfigurationKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - data_ = coreData.findConfiguration(std::string_view(std::string(node.as_string()))); -} diff --git a/src/keywords/configuration.h b/src/keywords/configuration.h deleted file mode 100644 index 2d83850fb3..0000000000 --- a/src/keywords/configuration.h +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class Configuration; - -// Keyword with Configuration Data -class ConfigurationKeyword : public KeywordBase -{ - public: - explicit ConfigurationKeyword(Configuration *&data); - ~ConfigurationKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - Configuration *&data_; - - public: - // Return reference to data - Configuration *&data(); - Configuration *&data() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Configuration in the contained data - void removeReferencesTo(Configuration *cfg) override; -}; diff --git a/src/keywords/configurationVector.cpp b/src/keywords/configurationVector.cpp deleted file mode 100644 index a391976534..0000000000 --- a/src/keywords/configurationVector.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/configurationVector.h" -#include "base/lineParser.h" -#include "classes/configuration.h" -#include "classes/coreData.h" -#include "templates/algorithms.h" - -ConfigurationVectorKeyword::ConfigurationVectorKeyword(std::vector &data) - : KeywordBase(typeid(this)), data_(data) -{ -} - -/* - * Data - */ - -// Return reference to data vector -std::vector &ConfigurationVectorKeyword::data() { return data_; } -const std::vector &ConfigurationVectorKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Return maximum number of arguments accepted -std::optional ConfigurationVectorKeyword::maxArguments() const { return std::nullopt; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool ConfigurationVectorKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Each argument is the name of a Configuration - for (auto n = startArg; n < parser.nArgs(); ++n) - { - auto *cfg = coreData.findConfiguration(parser.argsv(n)); - if (!cfg) - return Messenger::error("Error defining Configuration targets - no Configuration named '{}' exists.\n", - parser.argsv(n)); - - // Check that the configuration isn't already present - if (std::find(data_.begin(), data_.end(), cfg) != data_.end()) - return Messenger::error("Configuration '{}' has already been referenced.\n", cfg->name()); - - data_.push_back(cfg); - } - - return true; -} - -// Serialise data to specified LineParser -bool ConfigurationVectorKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (data_.empty()) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, - joinStrings(data_, " ", [](const auto *cfg) { return std::format("'{}'", cfg->name()); })); -} - -/* - * Object Management - */ - -// Prune any references to the supplied Configuration in the contained data -void ConfigurationVectorKeyword::removeReferencesTo(Configuration *cfg) -{ - data_.erase(std::remove(data_.begin(), data_.end(), cfg), data_.end()); -} - -// Express as a serialisable value -void ConfigurationVectorKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = fromVector(data_, [](const auto &cfg) { return std::string(cfg->name()); }); -} - -// Read values from a serialisable value -void ConfigurationVectorKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - toVector(node, - [&coreData, this](const auto &name) - { - auto *cfg = coreData.findConfiguration(std::string_view(std::string(name.as_string()))); - if (!cfg) - throw toml::type_error( - std::format("Error defining Configuration targets - no Configuration named '{}' exists.\n", - std::string(name.as_string())), - name.location()); - - // Check that the configuration isn't already present - if (std::find(data_.begin(), data_.end(), cfg) != data_.end()) - throw toml::type_error(std::format("Configuration '{}' has already been referenced.\n", cfg->name()), - name.location()); - - data_.push_back(cfg); - }); -} - -// Has not changed from initial value -bool ConfigurationVectorKeyword::isDefault() const { return data_.empty(); } diff --git a/src/keywords/configurationVector.h b/src/keywords/configurationVector.h deleted file mode 100644 index f492f521b2..0000000000 --- a/src/keywords/configurationVector.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class Configuration; - -// Keyword managing vector of Configurations -class ConfigurationVectorKeyword : public KeywordBase -{ - public: - explicit ConfigurationVectorKeyword(std::vector &data); - ~ConfigurationVectorKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data vector - std::vector &data_; - - public: - // Return reference to data vector - std::vector &data(); - const std::vector &data() const; - - /* - * Arguments - */ - public: - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Configuration in the contained data - void removeReferencesTo(Configuration *cfg) override; - - public: - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/double.cpp b/src/keywords/double.cpp deleted file mode 100644 index de9ac5559d..0000000000 --- a/src/keywords/double.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/double.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" - -DoubleKeyword::DoubleKeyword(double &data, std::optional minValue, std::optional maxValue) - : KeywordBase(typeid(this)), data_(data), default_(data), minimumLimit_(minValue), maximumLimit_(maxValue) -{ -} - -/* - * Data - */ - -// Set data -bool DoubleKeyword::setData(double value) -{ - if ((minimumLimit_ && value < minimumLimit_.value()) || (maximumLimit_ && value > maximumLimit_)) - return false; - - data_ = value; - set_ = true; - - return true; -} - -// Return data -double DoubleKeyword::data() const { return data_; } - -// Return minimum limit -std::optional DoubleKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional DoubleKeyword::maximumLimit() const { return maximumLimit_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool DoubleKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg)) - { - auto x = parser.argd(startArg); - if (!setData(x)) - { - if (minimumLimit_ && maximumLimit_) - Messenger::error("Value {} is out of range for keyword. Valid range is {} <= n <= {}.\n", x, - minimumLimit_.value(), maximumLimit_.value()); - else if (minimumLimit_) - Messenger::error("Value {} is out of range for keyword. Valid range is {} <= n.\n", x, minimumLimit_.value()); - else - Messenger::error("Value {} is out of range for keyword. Valid range is n <= {}.\n", x, maximumLimit_.value()); - - return false; - } - - return true; - } - - return false; -} - -// Serialise data to specified LineParser -bool DoubleKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!set_) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, data_); -} - -// Express as a serialisable value -void DoubleKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void DoubleKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_ = toml::get(node); } - -// Has not changed from initial value -bool DoubleKeyword::isDefault() const { return data_ == default_; } diff --git a/src/keywords/double.h b/src/keywords/double.h deleted file mode 100644 index 320bbf7945..0000000000 --- a/src/keywords/double.h +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include - -// Keyword managing Double data -class DoubleKeyword : public KeywordBase -{ - public: - explicit DoubleKeyword(double &data, std::optional minValue = std::nullopt, - std::optional maxValue = std::nullopt); - ~DoubleKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - double &data_; - // Initial value - const double default_; - // Optional limits to apply - std::optional minimumLimit_, maximumLimit_; - // Whether the data has been set - bool set_{false}; - - public: - // Set data - bool setData(double value); - // Return data - double data() const; - // Return minimum limit - std::optional minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Has not changed from initial value - bool isDefault() const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/elementVector.cpp b/src/keywords/elementVector.cpp deleted file mode 100644 index e86931ed12..0000000000 --- a/src/keywords/elementVector.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/elementVector.h" -#include "base/lineParser.h" -#include "data/elements.h" -#include "templates/algorithms.h" - -ElementVectorKeyword::ElementVectorKeyword(std::vector &data) : KeywordBase(typeid(this)), data_(data) {} - -/* - * Data - */ - -// Return reference to data -std::vector &ElementVectorKeyword::data() { return data_; } -const std::vector &ElementVectorKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Return maximum number of arguments accepted -std::optional ElementVectorKeyword::maxArguments() const { return std::nullopt; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool ElementVectorKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Loop over arguments which are Element names - for (auto n = startArg; n < parser.nArgs(); ++n) - { - // Do we recognise the Element? - auto el = Elements::element(parser.argsv(n)); - if (el == Elements::Unknown) - return Messenger::error("Unrecognised Element '{}' given to keyword '{}'.\n", parser.argsv(n), name()); - - // If the Element is already present, complain - if (std::find(data_.begin(), data_.end(), el) != data_.end()) - return Messenger::error("Element '{}' specified twice in keyword '{}'.\n", parser.argsv(n), name()); - - // All OK - add it to our vector - data_.push_back(el); - } - - return true; -} - -// Serialise data to specified LineParser -bool ElementVectorKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (data_.empty()) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, - joinStrings(data_, " ", [](const auto &el) { return Elements::symbol(el); })); -} - -// Express as a serialisable value -void ElementVectorKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - throw std::runtime_error("Cannot serialise ElementVectorKeyword"); -} diff --git a/src/keywords/elementVector.h b/src/keywords/elementVector.h deleted file mode 100644 index d4c4dff116..0000000000 --- a/src/keywords/elementVector.h +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "data/elements.h" -#include "keywords/base.h" - -// Keyword managing Element vector data -class ElementVectorKeyword : public KeywordBase -{ - public: - explicit ElementVectorKeyword(std::vector &data); - ~ElementVectorKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - std::vector &data_; - - public: - // Return reference to data - std::vector &data(); - const std::vector &data() const; - - /* - * Arguments - */ - public: - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; -}; diff --git a/src/keywords/enumOptions.h b/src/keywords/enumOptions.h deleted file mode 100644 index 9c70ee0150..0000000000 --- a/src/keywords/enumOptions.h +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/enumOptions.h" -#include "base/lineParser.h" -#include "keywords/base.h" - -// EnumOptionsKeyword base class -class EnumOptionsBaseKeyword : public KeywordBase -{ - public: - explicit EnumOptionsBaseKeyword(EnumOptionsBase &baseOptions) : KeywordBase(typeid(this)), baseOptions_(baseOptions) {} - - /* - * Source Options - */ - private: - // Source EnumBaseOptions - EnumOptionsBase &baseOptions_; - - public: - // Return EnumBaseOptions - const EnumOptionsBase &baseOptions() const { return baseOptions_; } - - /* - * Set - */ - public: - // Return data as integer index - virtual int enumerationByIndex() const = 0; - // Set new option index, informing KeywordBase - virtual void setEnumerationByIndex(int optionIndex) = 0; -}; - -// Keyword based on EnumOptions -template class EnumOptionsKeyword : public EnumOptionsBaseKeyword -{ - public: - explicit EnumOptionsKeyword(E &data, EnumOptions optionData) - : EnumOptionsBaseKeyword(optionData_), data_(data), default_(data), optionData_(optionData) - { - // Set our array of valid values - for (auto n = 0; n < optionData_.nOptions(); ++n) - validKeywords_.emplace_back(std::string(optionData_.keywordByIndex(n))); - } - ~EnumOptionsKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - E &data_; - // Initial value - const E default_; - // Related EnumOptions data - EnumOptions optionData_; - // List of valid keyword values - std::vector validKeywords_; - - public: - // Return reference to data - E &data() { return data_; } - const E &data() const { return data_; } - // Validate supplied value - bool isValid(std::string_view value) { return optionData_.isValid(value); } - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override - { - if (parser.hasArg(startArg)) - { - // Check validity of the supplied keyword... - if (!optionData_.isValid(parser.argsv(startArg))) - return optionData_.errorAndPrintValid(parser.argsv(startArg)); - - data_ = optionData_.enumeration(parser.argsv(startArg)); - - return true; - } - - return false; - } - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override - { - return parser.writeLineF("{}{} {}\n", prefix, keywordName, optionData_.keyword(data_)); - } - - /* - * Set (implementing pure virtual from EnumOptionsBaseKeyword) - */ - public: - // Return data as integer index - int enumerationByIndex() const override - { - for (auto n = 0; n < optionData_.nOptions(); ++n) - if (optionData_.enumerationByIndex(n) == data_) - return n; - throw(std::runtime_error("Couldn't retrieve index for enumeration as it doesn't exist.\n")); - }; - // Set new option index - void setEnumerationByIndex(int optionIndex) override { data_ = optionData_.enumerationByIndex(optionIndex); } - - // Has not changed from initial value - bool isDefault() const override { return data_ == default_; } - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override { target[tag] = optionData_.keyword(data_); } - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override { data_ = optionData_.deserialise(node); } -}; diff --git a/src/keywords/expression.cpp b/src/keywords/expression.cpp deleted file mode 100644 index 8c16dae7d1..0000000000 --- a/src/keywords/expression.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/expression.h" -#include "base/lineParser.h" -#include "expression/expression.h" - -ExpressionKeyword::ExpressionKeyword(Expression &data) - : KeywordBase(typeid(this)), data_(data), default_(data.expressionString()) -{ -} - -/* - * Data - */ - -// Return reference to data -const Expression &ExpressionKeyword::data() const { return data_; } - -// Set data -bool ExpressionKeyword::setData(std::string_view expressionText) { return data_.create(expressionText); } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool ExpressionKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - return setData(parser.argsv(startArg)); -} - -// Serialise data to specified LineParser -bool ExpressionKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!parser.writeLineF("{}{} '{}'\n", prefix, keywordName, data_.expressionString())) - return false; - - return true; -} - -// Express as a serialisable value -void ExpressionKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_.expressionString(); } - -// Read values from a serialisable value -void ExpressionKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - setData(std::string_view(std::string(node.as_string()))); -} - -// Has not changed from initial value -bool ExpressionKeyword::isDefault() const { return data_.expressionString() == default_; } diff --git a/src/keywords/expression.h b/src/keywords/expression.h deleted file mode 100644 index b24d66b731..0000000000 --- a/src/keywords/expression.h +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class Expression; -class ExpressionVariable; - -// Keyword managing Expression -class ExpressionKeyword : public KeywordBase -{ - public: - ExpressionKeyword(Expression &data); - ~ExpressionKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - Expression &data_; - // Initial Value - const std::string default_; - - public: - // Return reference to data - const Expression &data() const; - // Set data - bool setData(std::string_view expressionText); - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Has not changed from initial value - bool isDefault() const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/function1D.cpp b/src/keywords/function1D.cpp deleted file mode 100644 index 73fd13df82..0000000000 --- a/src/keywords/function1D.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/function1D.h" -#include "base/lineParser.h" -#include "templates/algorithms.h" - -Function1DKeyword::Function1DKeyword(Function1DWrapper &data, - const Flags &functionProperties) - : KeywordBase(typeid(this)), data_(data), functionProperties_(functionProperties) -{ -} - -/* - * Data - */ - -// Return reference to data -const Function1DWrapper &Function1DKeyword::data() const { return data_; } - -// Set data -bool Function1DKeyword::setData(const Function1DWrapper &data) -{ - return data_.setFormAndParameters(data.form(), data.parameters()); -} - -// Return requested function properties -const Flags &Function1DKeyword::functionProperties() const { return functionProperties_; } - -/* - * Arguments - */ - -// Return maximum number of arguments accepted -std::optional Function1DKeyword::maxArguments() const { return std::nullopt; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool Function1DKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Check function name - if (!Functions1D::forms().isValid(parser.argsv(startArg))) - return Functions1D::forms().errorAndPrintValid(parser.argsv(startArg)); - auto func = Functions1D::forms().enumeration(parser.argsv(startArg)); - - // Check properties - if (!Functions1D::validFunction1DProperties(func, functionProperties_)) - return Messenger::error( - "1D function type {} can't be set in keyword '{}' as it does not have the correct properties.\n", - Functions1D::forms().keyword(func), name()); - - // Get parameters if they were given - auto params = parser.hasArg(startArg + 1) ? parser.argvd(startArg + 1) : std::vector(); - - return data_.setFormAndParameters(func, params); -} - -// Serialise data to specified LineParser -bool Function1DKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - return parser.writeLineF("{}{} '{}' {}\n", prefix, keywordName, Functions1D::forms().keyword(data_.form()), - joinStrings(data_.parameters(), " ")); -} - -// Express as a serialisable value -void Function1DKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = {{"type", Functions1D::forms().serialise(data_.form())}, {"parameters", data_.parameters()}}; -} - -// Read values from a serialisable value -void Function1DKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - data_.setFormAndParameters(Functions1D::forms().deserialise(node.at("type")), - toml::find>(node, "parameters")); -} diff --git a/src/keywords/function1D.h b/src/keywords/function1D.h deleted file mode 100644 index f10d7cd591..0000000000 --- a/src/keywords/function1D.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "math/function1D.h" - -// Keyword managing Function1D data -class Function1DKeyword : public KeywordBase -{ - public: - Function1DKeyword(Function1DWrapper &data, const Flags &properties = {}); - ~Function1DKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - Function1DWrapper &data_; - // Requested function properties - Flags functionProperties_; - - public: - // Return reference to data - const Function1DWrapper &data() const; - // Set data - bool setData(const Function1DWrapper &data); - // Return requested function properties - const Flags &functionProperties() const; - - /* - * Arguments - */ - public: - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/integer.cpp b/src/keywords/integer.cpp deleted file mode 100644 index d3bac41589..0000000000 --- a/src/keywords/integer.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/integer.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" - -IntegerKeyword::IntegerKeyword(int &data, std::optional minValue, std::optional maxValue) - : KeywordBase(typeid(this)), data_(data), default_(data), minimumLimit_(minValue), maximumLimit_(maxValue) -{ -} - -/* - * Data - */ - -// Set data -bool IntegerKeyword::setData(int value) -{ - if ((minimumLimit_ && value < minimumLimit_.value()) || (maximumLimit_ && value > maximumLimit_)) - return false; - - data_ = value; - set_ = true; - - return true; -} - -// Return data -int IntegerKeyword::data() const { return data_; } - -// Return minimum limit -std::optional IntegerKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional IntegerKeyword::maximumLimit() const { return maximumLimit_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool IntegerKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg)) - { - auto x = parser.argi(startArg); - if (!setData(x)) - { - if (minimumLimit_ && maximumLimit_) - Messenger::error("Value {} is out of range for keyword. Valid range is {} <= n <= {}.\n", x, - minimumLimit_.value(), maximumLimit_.value()); - else if (minimumLimit_) - Messenger::error("Value {} is out of range for keyword. Valid range is {} <= n.\n", x, minimumLimit_.value()); - else - Messenger::error("Value {} is out of range for keyword. Valid range is n <= {}.\n", x, maximumLimit_.value()); - - return false; - } - - return true; - } - - return false; -} - -// Serialise data to specified LineParser -bool IntegerKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!set_) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, data_); -} - -// Express as a serialisable value -void IntegerKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void IntegerKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_ = node.as_integer(); } - -// Has not changed from initial value -bool IntegerKeyword::isDefault() const { return data_ == default_; } diff --git a/src/keywords/integer.h b/src/keywords/integer.h deleted file mode 100644 index 7248a06bff..0000000000 --- a/src/keywords/integer.h +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include - -// Keyword managing Integer data -class IntegerKeyword : public KeywordBase -{ - public: - explicit IntegerKeyword(int &data, std::optional minValue = std::nullopt, std::optional maxValue = std::nullopt); - ~IntegerKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - int &data_; - // Initial value - const int default_; - // Optional limits to apply - std::optional minimumLimit_, maximumLimit_; - // Whether the data has been set - bool set_{false}; - - public: - // Set data - bool setData(int value); - // Return data - int data() const; - // Return minimum limit - std::optional minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/interactionPotential.h b/src/keywords/interactionPotential.h deleted file mode 100644 index da5d081f16..0000000000 --- a/src/keywords/interactionPotential.h +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "base/enumOptions.h" -#include "base/lineParser.h" -#include "classes/interactionPotential.h" -#include "keywords/base.h" - -// InteractionPotentialKeyword base class -class InteractionPotentialBaseKeyword : public KeywordBase -{ - public: - InteractionPotentialBaseKeyword(EnumOptionsBase &formOptions) : KeywordBase(typeid(this)), formOptions_(formOptions) {} - - /* - * Source Form Options - */ - private: - // Source EnumBaseOptions for functional form - EnumOptionsBase &formOptions_; - - protected: - public: - // Return EnumBaseOptions for functional form - const EnumOptionsBase &formOptions() const { return formOptions_; } - - /* - * Set / Get - */ - public: - // Return form as integer index - virtual int formByIndex() const = 0; - // Set new form index - virtual void setFormByIndex(int formIndex) = 0; - // Return parameters as string - virtual std::string parametersAsString() const = 0; - // Set parameters from supplied string - virtual bool setParameters(std::string parameters) = 0; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override - { - throw std::runtime_error("Cannot serialise InteractionPotentialBaseKeyword"); - } -}; - -// Keyword based on InteractionPotential -template class InteractionPotentialKeyword : public InteractionPotentialBaseKeyword -{ - public: - explicit InteractionPotentialKeyword(InteractionPotential &data) - : InteractionPotentialBaseKeyword(optionData_), data_(data), optionData_(Functions::forms()), - formOptionsType_(typeid(Functions)) - { - } - ~InteractionPotentialKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - InteractionPotential &data_; - // Related form enum data - EnumOptions optionData_; - const std::type_index formOptionsType_; - - public: - // Return reference to data - InteractionPotential &data() { return data_; } - const InteractionPotential &data() const { return data_; } - - const std::type_index formOptionsType() const { return formOptionsType_; } - - /* - * Arguments - */ - public: - // Return maximum number of arguments accepted - std::optional maxArguments() const override { return {}; } - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override - { - if (!parser.hasArg(startArg)) - return Messenger::error("Functional form of interaction must be provided.\n"); - - // Check the functional form specified - if (!Functions::forms().isValid(parser.argsv(startArg))) - return Messenger::error("Functional form of interaction ({}) not recognised.\n", parser.argsv(startArg)); - data_.setForm(Functions::forms().enumeration(parser.argsv(startArg))); - - // Check number of args provided - if (!Functions::forms().validNArgs(data_.form(), parser.nArgs() - startArg - 1)) - return Messenger::error("Invalid number of parameters given for functional form '{}'.\n", - Functions::forms().keyword(data_.form())); - - // Set parameters - if (!data_.parseParameters(parser, startArg + 1)) - return Messenger::error("Failed to set parameters for functional form '{}'.\n", - Functions::forms().keyword(data_.form())); - - return true; - } - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override - { - return parser.writeLineF("{}{} {} {}\n", prefix, keywordName, Functions::forms().keyword(data_.form()), - data_.parametersAsString()); - } - - /* - * Set (implementing pure virtual from InteractionPotentialBaseKeyword) - */ - public: - // Return form as integer index - int formByIndex() const override - { - for (auto n = 0; n < Functions::forms().nOptions(); ++n) - if (Functions::forms().enumerationByIndex(n) == data_.form()) - return n; - throw(std::runtime_error("Couldn't retrieve index for enumeration as it doesn't exist.\n")); - }; - // Set new form index - void setFormByIndex(int formIndex) override { data_.setForm(Functions::forms().enumerationByIndex(formIndex)); } - // Return parameters as string - std::string parametersAsString() const override { return data_.parametersAsString(); }; - // Set parameters from supplied string - bool setParameters(std::string parameters) override - { - // Stash current parameters, just in case we fail to set from the new string - auto currentParameters = data_.parametersAsString(); - - if (data_.parseParameters(parameters)) - return true; - - data_.parseParameters(currentParameters); - return false; - } -}; diff --git a/src/keywords/isotopologueSet.cpp b/src/keywords/isotopologueSet.cpp deleted file mode 100644 index 699ebd3e8d..0000000000 --- a/src/keywords/isotopologueSet.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/isotopologueSet.h" -#include "base/lineParser.h" -#include "classes/coreData.h" -#include "classes/species.h" - -IsotopologueSetKeyword::IsotopologueSetKeyword(IsotopologueSet &data) : KeywordBase(typeid(this)), data_(data) {} - -/* - * Data - */ - -// Return reference to data -IsotopologueSet &IsotopologueSetKeyword::data() { return data_; } -const IsotopologueSet &IsotopologueSetKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int IsotopologueSetKeyword::minArguments() const { return 3; } - -// Return maximum number of arguments accepted -std::optional IsotopologueSetKeyword::maxArguments() const { return 3; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool IsotopologueSetKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Find specified Species (first argument) - Species *sp = coreData.findSpecies(DissolveSys::niceName(parser.argsv(startArg))); - if (!sp) - return Messenger::error("Error defining Isotopologue reference - no Species named '{}' exists.\n", - DissolveSys::niceName(parser.argsv(startArg))); - - // Finally, locate isotopologue definition for species (second argument) - const Isotopologue *iso = sp->findIsotopologue(parser.argsv(startArg + 1)); - if (!iso) - return Messenger::error("Error defining Isotopologue reference - no Isotopologue named '{}' exists for Species '{}'.\n", - parser.argsv(startArg + 1), sp->name()); - - // Add the isotopologue to the set - data_.add(iso, parser.argd(startArg + 2)); - - // Resolve against the current set of species - std::map speciesMap; - for (const auto &sp : coreData.species()) - speciesMap[std::string(sp.get()->name())] = sp.get(); - data_.resolve(speciesMap); - - return true; -} - -// Serialise data to specified LineParser -bool IsotopologueSetKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - for (auto &[species, isotopologues] : data_.isotopologues()) - for (const auto &[iso, weight] : isotopologues) - { - if (!parser.writeLineF("{}{} '{}' '{}' {}\n", prefix, keywordName, species.name(), iso.raw()->name(), weight)) - return false; - } - - return true; -} - -/* - * Data Management - */ - -// Prune any references to the supplied Species in the contained data -void IsotopologueSetKeyword::removeReferencesTo(Species *sp) { data_.remove(sp); } - -// Prune any references to the supplied Isotopologue in the contained data -void IsotopologueSetKeyword::removeReferencesTo(Isotopologue *iso) { data_.remove(iso); } - -// Express as a serialisable value -void IsotopologueSetKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void IsotopologueSetKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - data_.deserialise(node, coreData); -} - -// Has not changed from initial value -bool IsotopologueSetKeyword::isDefault() const { return false; } diff --git a/src/keywords/isotopologueSet.h b/src/keywords/isotopologueSet.h deleted file mode 100644 index 2a90960f48..0000000000 --- a/src/keywords/isotopologueSet.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "classes/isotopologueSet.h" -#include "keywords/base.h" - -// Keyword managing IsotopologueSet data -class IsotopologueSetKeyword : public KeywordBase -{ - public: - explicit IsotopologueSetKeyword(IsotopologueSet &data); - ~IsotopologueSetKeyword() override = default; - // Has not changed from initial value - bool isDefault() const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - - /* - * Data - */ - private: - // Reference to data - IsotopologueSet &data_; - - public: - // Return reference to data - IsotopologueSet &data(); - const IsotopologueSet &data() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Species in the contained data - void removeReferencesTo(Species *sp) override; - // Prune any references to the supplied Isotopologue in the contained data - void removeReferencesTo(Isotopologue *iso) override; -}; diff --git a/src/keywords/optionalDouble.cpp b/src/keywords/optionalDouble.cpp deleted file mode 100644 index 398a3c14c5..0000000000 --- a/src/keywords/optionalDouble.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/optionalDouble.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" -#include "keywords/base.h" - -OptionalDoubleKeyword::OptionalDoubleKeyword(std::optional &data, double minValue, std::optional maxValue, - double valueDelta, std::string_view textWhenNull) - : KeywordBase(typeid(this)), data_(data), minimumLimit_{minValue}, maximumLimit_{maxValue}, valueDelta_(valueDelta), - textWhenNull_{textWhenNull} -{ -} - -/* - * Data - */ - -// Set data -bool OptionalDoubleKeyword::setData(std::optional value) -{ - // Check limits if a value was supplied - if (value) - { - if (maximumLimit_ && value.value() > maximumLimit_) - return false; - else if (value.value() <= minimumLimit_) - value = std::nullopt; - } - - data_ = value; - set_ = true; - - return true; -} - -// Return data -std::optional OptionalDoubleKeyword::data() const { return data_; } - -// Return minimum limit -double OptionalDoubleKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional OptionalDoubleKeyword::maximumLimit() const { return maximumLimit_; } - -// Return step size for widget -double OptionalDoubleKeyword::valueDelta() const { return valueDelta_; } - -// Return text to display in widget when value is null -std::string OptionalDoubleKeyword::textWhenNull() const { return textWhenNull_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool OptionalDoubleKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - try - { - if (!parser.hasArg(startArg)) - return false; - - auto x = parser.argd(startArg); - if (!setData(x)) - { - if (maximumLimit_) - return Messenger::error("Value {} is out of range for keyword '{}'. Valid range is {} <= n.\n", x, name(), - maximumLimit_.value()); - } - } - catch (...) - { - // Check explicitly for null text - if (DissolveSys::sameString(parser.argsv(startArg), textWhenNull_)) - setData(std::nullopt); - else - return Messenger::error("Input {} is invalid for keyword '{}'.\n", parser.argsv(startArg), name()); - } - return true; -} - -// Serialise data to specified LineParser -bool OptionalDoubleKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!set_) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, data_.value_or(minimumLimit_)); -} - -// Express as a serialisable value -void OptionalDoubleKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = data_.value_or(minimumLimit_); -} - -// Read values from a serialisable value -void OptionalDoubleKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - setData(toml::get(node)); -} - -// Has not changed from initial value -bool OptionalDoubleKeyword::isDefault() const { return !set_ || !data_; } diff --git a/src/keywords/optionalDouble.h b/src/keywords/optionalDouble.h deleted file mode 100644 index a3406665cb..0000000000 --- a/src/keywords/optionalDouble.h +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include - -// Keyword managing optional Double data -class OptionalDoubleKeyword : public KeywordBase -{ - public: - explicit OptionalDoubleKeyword(std::optional &data, double minValue, std::optional maxValue, - double valueDelta, std::string_view textWhenNull); - ~OptionalDoubleKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - std::optional &data_; - // Minimum limit, at or below which equates to nullopt - double minimumLimit_; - // Optional maximum limit to apply - std::optional maximumLimit_; - // Step size for widget - double valueDelta_; - // Text to display in widget when null - std::string textWhenNull_; - // Whether the data has been set - bool set_{false}; - - public: - // Set data - bool setData(std::optional value); - // Return data - std::optional data() const; - // Return minimum limit - double minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - // Return step size for widget - double valueDelta() const; - // Return text to display in widget when value is null - std::string textWhenNull() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/optionalInt.cpp b/src/keywords/optionalInt.cpp deleted file mode 100644 index aef8266c5c..0000000000 --- a/src/keywords/optionalInt.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/optionalInt.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" -#include "keywords/base.h" - -OptionalIntegerKeyword::OptionalIntegerKeyword(std::optional &data, int minValue, std::optional maxValue, - int valueDelta, std::string_view textWhenNull) - : KeywordBase(typeid(this)), data_(data), minimumLimit_{minValue}, maximumLimit_{maxValue}, valueDelta_(valueDelta), - textWhenNull_{textWhenNull} -{ -} - -/* - * Data - */ - -// Set data -bool OptionalIntegerKeyword::setData(std::optional value) -{ - // Check limits if a value was supplied - if (value) - { - if (maximumLimit_ && value.value() > maximumLimit_) - return false; - else if (value.value() <= minimumLimit_) - value = std::nullopt; - } - - data_ = value; - set_ = true; - - return true; -} - -// Return data -std::optional OptionalIntegerKeyword::data() const { return data_; } - -// Return minimum limit -int OptionalIntegerKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional OptionalIntegerKeyword::maximumLimit() const { return maximumLimit_; } - -// Return step size for widget -int OptionalIntegerKeyword::valueDelta() const { return valueDelta_; } - -// Return text to display in widget when value is null -std::string OptionalIntegerKeyword::textWhenNull() const { return textWhenNull_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool OptionalIntegerKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - try - { - if (!parser.hasArg(startArg)) - return false; - - auto x = parser.argi(startArg); - if (!setData(x)) - { - if (maximumLimit_) - return Messenger::error("Value {} is out of range for keyword '{}'. Valid range is {} <= n.\n", x, name(), - maximumLimit_.value()); - } - } - catch (...) - { - // Check explicitly for null text - if (DissolveSys::sameString(parser.argsv(startArg), textWhenNull_)) - setData(std::nullopt); - else - return Messenger::error("Input {} is invalid for keyword '{}'.\n", parser.argsv(startArg), name()); - } - return true; -} - -// Serialise data to specified LineParser -bool OptionalIntegerKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!set_) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, data_.value_or(minimumLimit_)); -} - -// Express as a serialisable value -void OptionalIntegerKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = data_.value_or(minimumLimit_); -} - -// Read values from a serialisable value -void OptionalIntegerKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - setData(toml::get(node)); -} diff --git a/src/keywords/optionalInt.h b/src/keywords/optionalInt.h deleted file mode 100644 index 02f838536d..0000000000 --- a/src/keywords/optionalInt.h +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include - -// Keyword managing optional int data -class OptionalIntegerKeyword : public KeywordBase -{ - public: - explicit OptionalIntegerKeyword(std::optional &data, int minValue, std::optional maxValue, int valueDelta, - std::string_view textWhenNull); - ~OptionalIntegerKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - std::optional &data_; - // Minimum limit, at or below which equates to nullopt - int minimumLimit_; - // Optional maximum limit to apply - std::optional maximumLimit_; - // Step size for widget - int valueDelta_; - // Text to display in widget when null - std::string textWhenNull_; - // Whether the data has been set - bool set_{false}; - - public: - // Set data - bool setData(std::optional value); - // Return data - std::optional data() const; - // Return minimum limit - int minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - // Return step size for widget - int valueDelta() const; - // Return text to display in widget when value is null - std::string textWhenNull() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/organiser.cpp b/src/keywords/organiser.cpp deleted file mode 100644 index a0e4a2a274..0000000000 --- a/src/keywords/organiser.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/organiser.h" -#include - -/* - * Keyword Store Group - */ - -KeywordStoreGroup::KeywordStoreGroup(std::string_view name, std::optional groupDescription) : name_(name) -{ - if (groupDescription) - description_ = *groupDescription; -} - -// Add keyword to group -void KeywordStoreGroup::addKeyword(KeywordBase *keyword, KeywordBase::KeywordType type) -{ - keywords_.emplace_back(keyword, type); -} - -// Return the group name -std::string_view KeywordStoreGroup::name() const { return name_; } - -// Return the group description -std::string_view KeywordStoreGroup::description() const { return description_; } - -// Return the keywords vector -const std::vector &KeywordStoreGroup::keywords() const { return keywords_; } - -// Find named keyword -std::optional KeywordStoreGroup::find(std::string_view name) const -{ - auto keywordIt = - std::find_if(keywords_.begin(), keywords_.end(), [name](const auto &kd) { return kd.first->name() == name; }); - if (keywordIt != keywords_.end()) - return *keywordIt; - - return {}; -} - -/* - * Keyword Store Section - */ - -KeywordStoreSection::KeywordStoreSection(std::string_view name) : name_(name) { groups_.emplace_back("_NO_HEADER"); } - -// Return section name -std::string_view KeywordStoreSection::name() const { return name_; } - -// Get named group if it exists -OptionalReferenceWrapper KeywordStoreSection::getGroup(std::string_view groupName, - std::optional groupDescription, - bool createIfRequired) -{ - auto groupIt = std::find_if(groups_.begin(), groups_.end(), [groupName](auto &group) { return group.name() == groupName; }); - if (groupIt != groups_.end()) - return *groupIt; - - if (createIfRequired) - return groups_.emplace_back(groupName, groupDescription); - - return {}; -} - -// Return vector if defined groups -const std::vector &KeywordStoreSection::groups() const { return groups_; } - -// Return number of keywords defined over all groups -int KeywordStoreSection::nKeywords() const -{ - return std::accumulate(groups_.begin(), groups_.end(), 0, - [](const auto acc, const auto &group) { return acc + group.keywords().size(); }); -} - -// Find named keyword -std::optional KeywordStoreSection::find(std::string_view name) const -{ - for (const auto &group : groups_) - { - auto optK = group.find(name); - if (optK) - return *optK; - } - - return {}; -} diff --git a/src/keywords/organiser.h b/src/keywords/organiser.h deleted file mode 100644 index 3992128c65..0000000000 --- a/src/keywords/organiser.h +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "keywords/enumOptions.h" -#include "math/function1D.h" -#include "math/range.h" -#include "templates/optionalRef.h" -#include -#include -#include - -// Keywords are organised into sections and groups for the purposes of display in the GUI, where: -// - The section represents a top-level button the UI (e.g. "Options", "Export", "Advanced") which has -// associated with it one or more keywords organised into one or more named groups. -// - Groups represent logical ordering of keywords together within a section, e.g. step sizes or targets - -// Type Definition for Basic Keyword Entry -using KeywordStoreEntry = std::pair; - -// Keyword Store Group -class KeywordStoreGroup -{ - public: - KeywordStoreGroup(std::string_view groupName, std::optional groupDescription = {}); - - private: - // Group name and description - std::string name_, description_; - // Contained keywords - std::vector keywords_; - - public: - // Add keyword to group - void addKeyword(KeywordBase *keyword, KeywordBase::KeywordType type); - // Return the group name - std::string_view name() const; - // Return the group description - std::string_view description() const; - // Return the keywords vector - const std::vector &keywords() const; - - /* - * Find - */ - public: - // Find named keyword - std::optional find(std::string_view name) const; - // Find all keywords of specified type - template std::vector allOfType() const - { - std::vector result; - for (auto &&[k, kType] : keywords_) - if (k->typeIndex() == typeid(K *)) - result.push_back(dynamic_cast(k)); - return result; - } -}; - -// Keyword Store Section -class KeywordStoreSection -{ - public: - KeywordStoreSection(std::string_view name); - - private: - // Section name - std::string name_; - // Vector of defined keyword groups - std::vector groups_; - - public: - // Return section name - std::string_view name() const; - // Get named group if it exists - OptionalReferenceWrapper - getGroup(std::string_view groupName, std::optional groupDescription = {}, bool createIfRequired = false); - // Return vector of defined groups - const std::vector &groups() const; - // Return number of keywords defined over all groups - int nKeywords() const; - - /* - * Find - */ - public: - // Find named keyword - std::optional find(std::string_view name) const; - // Find all keywords of specified type - template std::vector allOfType() const - { - std::vector result; - for (auto &group : groups_) - { - auto subResult = group.allOfType(); - result.insert(result.end(), subResult.begin(), subResult.end()); - } - return result; - } -}; diff --git a/src/keywords/range.cpp b/src/keywords/range.cpp deleted file mode 100644 index 6072632064..0000000000 --- a/src/keywords/range.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/range.h" -#include "base/lineParser.h" - -RangeKeyword::RangeKeyword(Range &data, Vec3Labels::LabelType labelType) - : KeywordBase(typeid(this)), data_(data), default_(data), labelType_(labelType) -{ -} - -RangeKeyword::RangeKeyword(Range &data, std::optional minimumLimit, std::optional maximumLimit, - Vec3Labels::LabelType labelType) - : KeywordBase(typeid(this)), data_(data), minimumLimit_(minimumLimit), maximumLimit_(maximumLimit), labelType_(labelType) -{ -} - -/* - * Data - */ - -// Set data -bool RangeKeyword::setData(double rangeMin, double rangeMax) -{ - if ((minimumLimit_ && rangeMin < minimumLimit_.value()) || (maximumLimit_ && rangeMax > maximumLimit_.value())) - return false; - - data_.set(rangeMin, rangeMax); - - return true; -} -bool RangeKeyword::setData(const Range &range) { return setData(range.minimum(), range.maximum()); } - -// Set range minimum -bool RangeKeyword::setMinimum(double rangeMin) -{ - if ((minimumLimit_ && rangeMin < minimumLimit_.value()) || (maximumLimit_ && rangeMin > maximumLimit_) || - rangeMin > data_.maximum()) - return false; - - data_.setMinimum(rangeMin); - - return true; -} - -// Set range maximum -bool RangeKeyword::setMaximum(double rangeMax) -{ - if ((minimumLimit_ && rangeMax < minimumLimit_.value()) || (maximumLimit_ && rangeMax > maximumLimit_) || - rangeMax < data_.minimum()) - return false; - - data_.setMaximum(rangeMax); - - return true; -} - -// Return reference to data -const Range &RangeKeyword::data() const { return data_; } - -// Return minimum limit -std::optional RangeKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional RangeKeyword::maximumLimit() const { return maximumLimit_; } - -// Label type to display in GUI -Vec3Labels::LabelType RangeKeyword::labelType() const { return labelType_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int RangeKeyword::minArguments() const { return 2; } - -// Return maximum number of arguments accepted -std::optional RangeKeyword::maxArguments() const { return 2; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool RangeKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg + 1)) - { - auto rangeMin = parser.argd(startArg); - auto rangeMax = parser.argd(startArg + 1); - if (!setData(rangeMin, rangeMax)) - { - if (minimumLimit_ && maximumLimit_) - Messenger::error("Range {} - {} is invalid for keyword. Range limits are {} - {}.\n", rangeMin, rangeMax, - minimumLimit_.value(), maximumLimit_.value()); - else if (minimumLimit_) - Messenger::error("Range {} - {} is invalid for keyword. Range minimum limit is {}.\n", rangeMin, rangeMax, - minimumLimit_.value()); - else - Messenger::error("Range {} - {} is invalid for keyword. Range maximum limit is {}.\n", rangeMin, rangeMax, - maximumLimit_.value()); - - return false; - } - - return true; - } - - return false; -} - -// Serialise data to specified LineParser -bool RangeKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - return parser.writeLineF("{}{} {:12.6e} {:12.6e}\n", prefix, keywordName, data_.minimum(), data_.maximum()); -} - -// Express as a serialisable value -void RangeKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void RangeKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_.deserialise(node); } - -// Has not changed from initial value -bool RangeKeyword::isDefault() const { return data_ == default_; } diff --git a/src/keywords/range.h b/src/keywords/range.h deleted file mode 100644 index 6c544239bd..0000000000 --- a/src/keywords/range.h +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "keywords/vec3Labels.h" -#include "math/range.h" - -// Keyword managing Range data -class RangeKeyword : public KeywordBase -{ - public: - RangeKeyword(Range &data, Vec3Labels::LabelType labelType = Vec3Labels::NoLabels); - RangeKeyword(Range &data, std::optional minimumLimit, std::optional maximumLimit, - Vec3Labels::LabelType labelType = Vec3Labels::NoLabels); - ~RangeKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - Range &data_; - // Optional limits to apply - std::optional minimumLimit_, maximumLimit_; - // Initial Value - const Range default_; - // Label type to display in GUI - Vec3Labels::LabelType labelType_; - - public: - // Set data - bool setData(double rangeMin, double rangeMax); - bool setData(const Range &range); - // Set range minimum - bool setMinimum(double rangeMin); - // Set range maximum - bool setMaximum(double rangeMax); - // Return reference to data - const Range &data() const; - // Return minimum limit - std::optional minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - // Label type to display in GUI - Vec3Labels::LabelType labelType() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/rangeVector.cpp b/src/keywords/rangeVector.cpp deleted file mode 100644 index 996f0bff01..0000000000 --- a/src/keywords/rangeVector.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/rangeVector.h" -#include "base/lineParser.h" -#include "classes/coreData.h" - -RangeVectorKeyword::RangeVectorKeyword(std::vector &data) : KeywordBase(typeid(this)), data_(data) {} - -/* - * Data - */ - -// Return the data vector -std::vector &RangeVectorKeyword::data() { return data_; } -const std::vector &RangeVectorKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int RangeVectorKeyword::minArguments() const { return 2; } - -// Return maximum number of arguments accepted -std::optional RangeVectorKeyword::maxArguments() const { return 2; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool RangeVectorKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Check to see if value pair are numbers - if (DissolveSys::isNumber(parser.argsv(startArg)) && DissolveSys::isNumber(parser.argsv(startArg + 1))) - { - data_.emplace_back(parser.argd(startArg), parser.argd(startArg + 1)); - } - else - { - return Messenger::error( - "Value '{}' given to keyword '{}' doesn't appear to be numerical.\n", - DissolveSys::isNumber(parser.argsv(startArg)) ? parser.argsv(startArg + 1) : parser.argsv(startArg), name()); - } - - return true; -} - -// Serialise data to specified LineParser -bool RangeVectorKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - for (auto &range : data_) - { - // Serialising, skipping undefined ranges - if (range.isDefined() && !parser.writeLineF("{}{} {} {}\n", prefix, keywordName, range.minimum(), range.maximum())) - { - return false; - } - } - - return true; -} - -/* - * Object Management - */ - -// Express as a serialisable value -void RangeVectorKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = fromVector(data_, [](const auto &item) -> SerialisedValue { return item.into_toml(); }); -} - -// Read values from a serialisable value -void RangeVectorKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - toVector(node, [this](const auto &item) - { data_.emplace_back(toml::find(item, "min"), toml::find(item, "max")); }); -} - -// Has not changed from initial value -bool RangeVectorKeyword::isDefault() const { return data_.empty(); } diff --git a/src/keywords/rangeVector.h b/src/keywords/rangeVector.h deleted file mode 100644 index 0d12601889..0000000000 --- a/src/keywords/rangeVector.h +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "math/range.h" - -// Module Vector Keyword -class RangeVectorKeyword : public KeywordBase -{ - public: - RangeVectorKeyword(std::vector &data); - ~RangeVectorKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data vector - std::vector &data_; - - public: - // Return the data vector - std::vector &data(); - const std::vector &data() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/species.cpp b/src/keywords/species.cpp deleted file mode 100644 index f534146e7e..0000000000 --- a/src/keywords/species.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/species.h" -#include "base/lineParser.h" -#include "classes/coreData.h" -#include "classes/species.h" - -SpeciesKeyword::SpeciesKeyword(const Species *&data) : KeywordBase(typeid(this)), data_(data) {} - -/* - * Data - */ - -// Return reference to data -const Species *&SpeciesKeyword::data() { return data_; } -const Species *&SpeciesKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool SpeciesKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Find target Species (first argument) - data_ = coreData.findSpecies(DissolveSys::niceName(parser.argsv(startArg))); - if (!data_) - return Messenger::error("Error setting Species - no Species named '{}' exists.\n", - DissolveSys::niceName(parser.argsv(startArg))); - - return true; -} - -// Serialise data to specified LineParser -bool SpeciesKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (!data_) - return true; - - return parser.writeLineF("{}{} '{}'\n", prefix, keywordName, data_->name()); -} - -/* - * Object Management - */ - -// Prune any references to the supplied Species in the contained data -void SpeciesKeyword::removeReferencesTo(Species *sp) -{ - if (data_ == sp) - data_ = nullptr; -} - -// Express as a serialisable value -void SpeciesKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_->name(); } - -// Read values from a serialisable value -void SpeciesKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - data_ = coreData.findSpecies(DissolveSys::niceName(std::string(node.as_string()))); -} diff --git a/src/keywords/species.h b/src/keywords/species.h deleted file mode 100644 index c5e36e06db..0000000000 --- a/src/keywords/species.h +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class Species; - -// Keyword managing Species data -class SpeciesKeyword : public KeywordBase -{ - public: - explicit SpeciesKeyword(const Species *&data); - ~SpeciesKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - const Species *&data_; - - public: - // Return reference to data - const Species *&data(); - const Species *&data() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Species in the contained data - void removeReferencesTo(Species *sp) override; -}; diff --git a/src/keywords/speciesSite.cpp b/src/keywords/speciesSite.cpp deleted file mode 100644 index 6ca12a4e0f..0000000000 --- a/src/keywords/speciesSite.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/speciesSite.h" -#include "base/lineParser.h" -#include "classes/coreData.h" -#include "classes/species.h" - -SpeciesSiteKeyword::SpeciesSiteKeyword(const SpeciesSite *&data, bool axesRequired) - : KeywordBase(typeid(this)), data_(data), axesRequired_(axesRequired) -{ -} - -/* - * Data - */ - -// Return reference to data -const SpeciesSite *&SpeciesSiteKeyword::data() { return data_; } -const SpeciesSite *&SpeciesSiteKeyword::data() const { return data_; } - -// Return whether axes are required for the site -bool SpeciesSiteKeyword::axesRequired() const { return axesRequired_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int SpeciesSiteKeyword::minArguments() const { return 2; } - -// Return maximum number of arguments accepted -std::optional SpeciesSiteKeyword::maxArguments() const { return 2; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool SpeciesSiteKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Find target Species (first argument) - Species *sp = coreData.findSpecies(DissolveSys::niceName(parser.argsv(startArg))); - if (!sp) - { - Messenger::error("Error setting SpeciesSite - no Species named '{}' exists.\n", parser.argsv(startArg)); - return false; - } - - // Find specified Site (second argument) in the Species - data_ = sp->findSite(DissolveSys::niceName(parser.argsv(startArg + 1))); - if (!data_) - return Messenger::error("Error setting SpeciesSite - no such site named '{}' exists in Species '{}'.\n", - parser.argsv(startArg + 1), sp->name()); - - if (axesRequired_ && (!data_->hasAxes())) - return Messenger::error( - "Can't select site '{}' for keyword '{}', as the keyword requires axes specifications to be present.\n", - data_->name(), name()); - - return true; -} - -// Serialise data to specified LineParser -bool SpeciesSiteKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (data_) - { - if (!parser.writeLineF("{}{} '{}' '{}'\n", prefix, keywordName, data_->parent()->name(), data_->name())) - return false; - } - - return true; -} - -/* - * Object Management - */ - -// Prune any references to the supplied Species in the contained data -void SpeciesSiteKeyword::removeReferencesTo(Species *sp) -{ - if (data_ && (data_->parent() == sp)) - data_ = nullptr; -} - -// Prune any references to the supplied Site in the contained data -void SpeciesSiteKeyword::removeReferencesTo(SpeciesSite *spSite) -{ - if (data_ == spSite) - data_ = nullptr; -} - -// Express as a serialisable value -void SpeciesSiteKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = {{"species", data_->parent()->name()}, {"site", data_->name()}}; -} - -// Read values from a serialisable value -void SpeciesSiteKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - KeywordBase::deserialise(node, coreData); - std::string species = toml::find(node, "species"); - std::string site = toml::find(node, "site"); - // Find target Species (first argument) - Species *sp = coreData.findSpecies(species); - if (!sp) - { - throw toml::type_error(std::format("Error setting SpeciesSite - no Species named '{}' exists.\n", species), - node.location()); - } - - // Find specified Site (second argument) in the Species - data_ = sp->findSite(site); - if (!data_) - throw toml::type_error( - std::format("Error setting SpeciesSite - no such site named '{}' exists in Species '{}'.\n", site, sp->name()), - node.location()); - - if (axesRequired_ && (!data_->hasAxes())) - throw toml::type_error( - std::format("Can't select site '{}' for keyword '{}', as the keyword requires axes specifications to be present.\n", - data_->name(), name()), - node.location()); -} diff --git a/src/keywords/speciesSite.h b/src/keywords/speciesSite.h deleted file mode 100644 index b25cae9e64..0000000000 --- a/src/keywords/speciesSite.h +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class SpeciesSite; - -// Keyword managing Site data -class SpeciesSiteKeyword : public KeywordBase -{ - public: - explicit SpeciesSiteKeyword(const SpeciesSite *&data, bool axesRequired = false); - ~SpeciesSiteKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - const SpeciesSite *&data_; - // Whether supplied sites must have a defined orientation - bool axesRequired_; - - public: - // Return reference to data - const SpeciesSite *&data(); - const SpeciesSite *&data() const; - // Return whether axes are required for the site - bool axesRequired() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Species in the contained data - void removeReferencesTo(Species *sp) override; - // Prune any references to the supplied SpeciesSite in the contained data - void removeReferencesTo(SpeciesSite *spSite) override; -}; diff --git a/src/keywords/speciesSiteVector.cpp b/src/keywords/speciesSiteVector.cpp deleted file mode 100644 index 6794414119..0000000000 --- a/src/keywords/speciesSiteVector.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/speciesSiteVector.h" -#include "base/lineParser.h" -#include "classes/configuration.h" -#include "classes/coreData.h" -#include "classes/species.h" - -SpeciesSiteVectorKeyword::SpeciesSiteVectorKeyword(std::vector &data, bool axesRequired) - : KeywordBase(typeid(this)), data_(data), axesRequired_(axesRequired) -{ -} - -/* - * Specification - */ - -// Return reference to data vector -std::vector &SpeciesSiteVectorKeyword::data() { return data_; } -const std::vector &SpeciesSiteVectorKeyword::data() const { return data_; } - -// Return whether axes are required for the site -bool SpeciesSiteVectorKeyword::axesRequired() const { return axesRequired_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int SpeciesSiteVectorKeyword::minArguments() const { return 2; } - -// Return maximum number of arguments accepted -std::optional SpeciesSiteVectorKeyword::maxArguments() const { return std::nullopt; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool SpeciesSiteVectorKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Loop over arguments - for (int n = startArg; n < parser.nArgs() - 1; n += 2) - { - // Find target Species (first argument) - Species *sp = coreData.findSpecies(DissolveSys::niceName(parser.argsv(n))); - if (!sp) - return Messenger::error("Error adding SpeciesSite - no Species named '{}' exists.\n", - DissolveSys::niceName(parser.argsv(n))); - - // Find specified Site (second argument) in the Species - auto speciesSite = sp->findSite(DissolveSys::niceName(parser.argsv(n + 1))); - if (!speciesSite) - return Messenger::error("Error setting SpeciesSite - no such site named '{}' exists in Species '{}'.\n", - parser.argsv(n + 1), sp->name()); - if (axesRequired_ && (!speciesSite->hasAxes())) - return Messenger::error("Can't add site '{}' to keyword '{}', as the keyword requires axes " - "specifications for all sites.\n", - speciesSite->name(), name()); - - // Add site to the vector - data_.push_back(speciesSite); - } - - return true; -} - -// Serialise data to specified LineParser -bool SpeciesSiteVectorKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - // If there are no sites in the vector, no need to write anything - if (data_.empty()) - return true; - - std::string sites; - for (auto *site : data_) - sites += std::format(" '{}' '{}'", site->parent()->name(), site->name()); - - if (!parser.writeLineF("{}{}{}\n", prefix, keywordName, sites)) - return false; - - return true; -} - -/* - * Object Management - */ - -// Prune any references to the supplied Species in the contained data -void SpeciesSiteVectorKeyword::removeReferencesTo(Species *sp) -{ - data_.erase(std::remove_if(data_.begin(), data_.end(), [sp](const auto *site) { return site->parent() == sp; }), - data_.end()); -} - -// Prune any references to the supplied SpeciesSite in the contained data -void SpeciesSiteVectorKeyword::removeReferencesTo(SpeciesSite *spSite) -{ - data_.erase(std::remove(data_.begin(), data_.end(), spSite), data_.end()); -} - -// Express as a serialisable value -void SpeciesSiteVectorKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = fromVector(data_, [](const auto item) -> SerialisedValue - { return {{"site", item->name()}, {"species", item->parent()->name()}}; }); -} - -// Read values from a serialisable value -void SpeciesSiteVectorKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - toVector(node, - [this, &coreData](const auto &item) - { - auto species = coreData.findSpecies(toml::find(item, "species")); - if (species) - { - auto site = species->findSite(toml::find(item, "site")); - if (site) - data_.push_back(site); - else - throw toml::type_error(std::format("Cannot find Site {}", toml::find(item, "site")), - item.location()); - } - else - toml::type_error(std::format("Cannot find Species {}", toml::find(item, "species")), - item.location()); - }); -} - -// Has not changed from initial value -bool SpeciesSiteVectorKeyword::isDefault() const { return data_.empty(); } diff --git a/src/keywords/speciesSiteVector.h b/src/keywords/speciesSiteVector.h deleted file mode 100644 index 7590490ee0..0000000000 --- a/src/keywords/speciesSiteVector.h +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class SpeciesSite; - -// Keyword managing vector of SpeciesSites -class SpeciesSiteVectorKeyword : public KeywordBase -{ - public: - SpeciesSiteVectorKeyword(std::vector &data, bool axesRequired = false); - ~SpeciesSiteVectorKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data vector - std::vector &data_; - // Whether supplied sites must have a defined orientation - bool axesRequired_; - - public: - // Return reference to data vector - std::vector &data(); - const std::vector &data() const; - // Return whether axes are required for the site - bool axesRequired() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Species in the contained data - void removeReferencesTo(Species *sp) override; - // Prune any references to the supplied SpeciesSite in the contained data - void removeReferencesTo(SpeciesSite *spSite) override; - - public: - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/speciesVector.cpp b/src/keywords/speciesVector.cpp deleted file mode 100644 index f8e8b7e421..0000000000 --- a/src/keywords/speciesVector.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/speciesVector.h" -#include "base/lineParser.h" -#include "classes/coreData.h" -#include "classes/species.h" -#include "templates/algorithms.h" - -SpeciesVectorKeyword::SpeciesVectorKeyword(std::vector &data) : KeywordBase(typeid(this)), data_(data) {} - -/* - * Data - */ - -// Return reference to data vector -std::vector &SpeciesVectorKeyword::data() { return data_; } -const std::vector &SpeciesVectorKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Return maximum number of arguments accepted -std::optional SpeciesVectorKeyword::maxArguments() const { return 99; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool SpeciesVectorKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - // Each argument is the name of a Species - for (auto n = startArg; n < parser.nArgs(); ++n) - { - const auto *sp = coreData.findSpecies(DissolveSys::niceName(parser.argsv(n))); - if (!sp) - return Messenger::error("Error reading keyword '{}' - no Species named '{}' exists.\n", name(), - DissolveSys::niceName(parser.argsv(n))); - - data_.push_back(sp); - } - - return true; -} - -// Serialise data to specified LineParser -bool SpeciesVectorKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - if (data_.empty()) - return true; - - return parser.writeLineF("{}{} {}\n", prefix, keywordName, - joinStrings(data_, " ", [](const auto *sp) { return sp->name(); })); -} - -/* - * Object Management - */ - -// Prune any references to the supplied Species in the contained data -void SpeciesVectorKeyword::removeReferencesTo(Species *sp) -{ - data_.erase(std::remove(data_.begin(), data_.end(), sp), data_.end()); -} - -// Express as a serialisable value -void SpeciesVectorKeyword::serialise(std::string tag, SerialisedValue &target) const -{ - target[tag] = fromVector(data_, [](const auto *item) { return item->name(); }); -} - -// Read values from a serialisable value -void SpeciesVectorKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) -{ - toVector(node, - [&coreData, this](const auto &item) - { - auto title = toml::get(item); - auto *species = coreData.findSpecies(title); - if (!species) - throw toml::type_error(std::format("No Species named '{}' exists.\n", title), item.location()); - - data_.push_back(species); - }); -} - -// Has not changed from initial value -bool SpeciesVectorKeyword::isDefault() const { return data_.empty(); } diff --git a/src/keywords/speciesVector.h b/src/keywords/speciesVector.h deleted file mode 100644 index f74b387e0b..0000000000 --- a/src/keywords/speciesVector.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Forward Declarations -class Species; - -// Keyword managing vector of Species -class SpeciesVectorKeyword : public KeywordBase -{ - public: - SpeciesVectorKeyword(std::vector &data); - ~SpeciesVectorKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data vector - std::vector &data_; - - public: - // Return reference to data vector - std::vector &data(); - const std::vector &data() const; - - /* - * Arguments - */ - public: - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - - /* - * Object Management - */ - protected: - // Prune any references to the supplied Species in the contained data - void removeReferencesTo(Species *sp) override; - - public: - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; -}; diff --git a/src/keywords/stdString.cpp b/src/keywords/stdString.cpp deleted file mode 100644 index 3417c3fad2..0000000000 --- a/src/keywords/stdString.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/stdString.h" -#include "base/lineParser.h" -#include "base/sysFunc.h" - -StringKeyword::StringKeyword(std::string &data) : KeywordBase(typeid(this)), data_(data), default_(data) {} - -/* - * Data - */ - -// Return reference to data -std::string &StringKeyword::data() { return data_; } -const std::string &StringKeyword::data() const { return data_; } - -/* - * Arguments - */ - -// Deserialise from supplied LineParser, starting at given argument offset -bool StringKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg)) - { - data_ = parser.argsv(startArg); - - return true; - } - - return false; -} - -// Serialise data to specified LineParser -bool StringKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - return parser.writeLineF("{}{} '{}'\n", prefix, keywordName, data_); -} - -// Express as a serialisable value -void StringKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void StringKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_ = node.as_string(); } - -// Has not changed from initial value -bool StringKeyword::isDefault() const { return data_ == default_; } diff --git a/src/keywords/stdString.h b/src/keywords/stdString.h deleted file mode 100644 index 1a394ecffb..0000000000 --- a/src/keywords/stdString.h +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" - -// Keyword managing std::string data -class StringKeyword : public KeywordBase -{ - public: - explicit StringKeyword(std::string &data); - ~StringKeyword() override = default; - - /* - * Data - */ - private: - // Reference to data - std::string &data_; - // Initial data - const std::string default_; - - public: - // Return reference to data - std::string &data(); - const std::string &data() const; - - /* - * Arguments - */ - public: - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; - // Has not changed from initial value - bool isDefault() const override; -}; diff --git a/src/keywords/store.cpp b/src/keywords/store.cpp deleted file mode 100644 index d70ce00461..0000000000 --- a/src/keywords/store.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/store.h" -#include "base/lineParser.h" -#include "keywords/bool.h" -#include "keywords/configuration.h" -#include "keywords/configurationVector.h" -#include "keywords/double.h" -#include "keywords/function1D.h" -#include "keywords/integer.h" -#include "keywords/range.h" -#include "keywords/species.h" -#include "keywords/speciesSiteVector.h" -#include "keywords/stdString.h" -#include "keywords/vec3Double.h" -#include "keywords/vec3Integer.h" - -/* - * Keyword Data - */ - -// Add keyword to current section / group -void KeywordStore::addKeywordToCurrentGroup(KeywordBase *keyword, KeywordBase::KeywordType type) -{ - if (!currentGroup_) - setOrganisation("_DEFAULT_SECTION", "_NO_HEADER"); - - currentGroup_->get().addKeyword(keyword, type); -} - -// Return named group, if it exists -OptionalReferenceWrapper KeywordStore::getGroup(std::string_view sectionName, std::string_view groupName, - std::optional groupDescription, - bool createIfRequired) -{ - // Get the specified section - auto sectionIt = std::find_if(sections_.begin(), sections_.end(), - [sectionName](const auto §ion) { return section.name() == sectionName; }); - if (sectionIt == sections_.end()) - { - if (createIfRequired) - { - auto &newSection = sections_.emplace_back(sectionName); - return newSection.getGroup(groupName, groupDescription, true); - } - else - return {}; - } - - return sectionIt->getGroup(groupName, groupDescription, createIfRequired); -} - -// Set current group and section organisation -void KeywordStore::setOrganisation(std::string_view sectionName, std::optional groupName, - std::optional groupDescription) -{ - currentGroup_ = getGroup(sectionName, groupName ? *groupName : "_NO_HEADER", groupDescription, true); -} - -// Find named keyword -std::optional KeywordStore::find(std::string_view name) -{ - for (const auto §ion : sections_) - { - auto optKeyword = section.find(name); - if (optKeyword) - return optKeyword; - } - - return {}; -} -std::optional KeywordStore::find(std::string_view name) const -{ - for (const auto §ion : sections_) - { - auto optKeyword = section.find(name); - if (optKeyword) - return optKeyword; - } - - return {}; -} - -// Return "Target" group keywords -std::vector KeywordStore::targetKeywords() -{ - // Return the keywords in the Options / Target section / group, if it exists - auto optGroup = getGroup("Options", "Targets"); - if (!optGroup) - return {}; - - // Flatten the keywords in this group into a plain vector of pointers - auto &group = optGroup->get(); - std::vector targets; - std::transform(group.keywords().begin(), group.keywords().end(), std::back_inserter(targets), - [](const auto &kd) { return kd.first; }); - return targets; -} - -// Return defined keyword sections -const std::vector &KeywordStore::sections() const { return sections_; } - -// Return number of visible keywords defined over all sections -int KeywordStore::nVisibleKeywords() const -{ - return std::accumulate(sections_.begin(), sections_.end(), 0, - [](const auto acc, const auto §ion) { return acc + section.nKeywords(); }); -} - -/* - * Read / Write - */ - -// Try to deserialise a single keyword through the specified LineParser -KeywordBase::ParseResult KeywordStore::deserialise(LineParser &parser, const CoreData &coreData, int startArg) -{ - // Do we recognise the first item (the 'keyword')? - auto optKeyword = find(parser.argsv(startArg)); - if (!optKeyword) - return KeywordBase::ParseResult::Unrecognised; - - auto &[keyword, keywordType] = *optKeyword; - auto deprecated = keywordType == KeywordBase::KeywordType::Deprecated; - - // We recognised the keyword - check the number of arguments we have against the min / max for the keyword - if (!keyword->validNArgs(parser.nArgs() - startArg - 1)) - return deprecated ? KeywordBase::ParseResult::Deprecated : KeywordBase::ParseResult::Failed; - - // All OK, so parse the keyword - if (!keyword->deserialise(parser, startArg + 1, coreData)) - { - Messenger::error("Failed to parse arguments for keyword '{}'.\n", keyword->name()); - return deprecated ? KeywordBase::ParseResult::Deprecated : KeywordBase::ParseResult::Failed; - } - - return deprecated ? KeywordBase::ParseResult::Deprecated : KeywordBase::ParseResult::Success; -} - -// Write all keywords to specified LineParser -bool KeywordStore::serialise(LineParser &parser, std::string_view prefix, bool onlyIfSet) const -{ - for (const auto §ion : sections_) - for (const auto &group : section.groups()) - for (const auto &[keyword, keywordType] : group.keywords()) - { - if (keywordType == KeywordBase::KeywordType::Deprecated) - continue; - if (!keyword->serialise(parser, keyword->name(), prefix)) - return false; - } - - return true; -} - -//// Local template for handling boilerplate of casting the keyword -template K *getKeyword(std::string_view name, std::optional optKeyword) -{ - if (!optKeyword) - Messenger::exception("Keyword '{}' cannot be retrieved as it doesn't exist.\n", name); - K *keyword = dynamic_cast(optKeyword->first); - if (!keyword) - Messenger::exception("Keyword '{}' is not of type '{}'.\n", name, typeid(K).name()); - return keyword; -} - -bool KeywordStore::set(std::string_view name, const bool value) -{ - getKeyword(name, find(name))->setData(value); - return true; -} -bool KeywordStore::set(std::string_view name, const double value) -{ - return getKeyword(name, find(name))->setData(value); -} -bool KeywordStore::set(std::string_view name, const int value) -{ - return getKeyword(name, find(name))->setData(value); -} -bool KeywordStore::set(std::string_view name, const std::vector value) -{ - getKeyword(name, find(name))->data() = value; - return true; -} -bool KeywordStore::set(std::string_view name, Configuration *value) -{ - getKeyword(name, find(name))->data() = value; - return true; -} -bool KeywordStore::set(std::string_view name, const std::vector value) -{ - getKeyword(name, find(name))->data() = value; - return true; -} -bool KeywordStore::set(std::string_view name, const Species *value) -{ - getKeyword(name, find(name))->data() = value; - return true; -} -bool KeywordStore::set(std::string_view name, const std::string value) -{ - getKeyword(name, find(name))->data() = value; - return true; -} -bool KeywordStore::set(std::string_view name, const Function1DWrapper value) -{ - return getKeyword(name, find(name))->setData(value); -} -bool KeywordStore::set(std::string_view name, const Vector3i value) -{ - return getKeyword(name, find(name))->setData(value); -} -bool KeywordStore::set(std::string_view name, const Vector3 value) -{ - return getKeyword(name, find(name))->setData(value); -} -bool KeywordStore::set(std::string_view name, const Range value) -{ - return getKeyword(name, find(name))->setData(value); -} - -// Retrieve a Configuration by keyword name -Configuration *KeywordStore::getConfiguration(std::string_view name) const -{ - return getKeyword(name, find(name))->data(); -} - -// Retrieve a Species by keyword name -const Species *KeywordStore::getSpecies(std::string_view name) const -{ - return getKeyword(name, find(name))->data(); -} - -// Retrieve a vector of Configurations by keyword name -std::vector KeywordStore::getVectorConfiguration(std::string_view name) const -{ - return getKeyword(name, find(name))->data(); -} - -// Retrieve an Integer by keyword name -int KeywordStore::getInt(std::string_view name) const { return getKeyword(name, find(name))->data(); } - -// Turn first character of keyword label to lower case to match -// convention with the rest of the file format. -std::string toml_format(const std::string_view original) -{ - auto result = std::string(original); - result[0] = tolower(result[0]); - return result; -} - -// Apply the terms in the keyword store to a node -SerialisedValue KeywordStore::serialiseOnto(SerialisedValue node) const -{ - for (const auto §ion : sections_) - for (const auto &group : section.groups()) - for (const auto &[keyword, keywordType] : group.keywords()) - if (!keyword->isDefault()) - { - SerialisedValue outer; - keyword->serialise("inner", outer); - auto &value = outer["inner"]; - if (keywordType != KeywordBase::KeywordType::Deprecated && !value.is_uninitialized()) - node[toml_format(keyword->name())] = value; - } - return node; -} - -// Pull keywords from entries in table -void KeywordStore::deserialiseFrom(const SerialisedValue &node, const CoreData &coreData) -{ - for (const auto §ion : sections_) - for (const auto &group : section.groups()) - for (const auto &[keyword, keywordType] : group.keywords()) - if (node.contains(toml_format(keyword->name()))) - keyword->deserialise(node.at(toml_format(keyword->name())), coreData); -} diff --git a/src/keywords/store.h b/src/keywords/store.h deleted file mode 100644 index cc20d71fa6..0000000000 --- a/src/keywords/store.h +++ /dev/null @@ -1,292 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "keywords/enumOptions.h" -#include "keywords/organiser.h" -#include "math/function1D.h" -#include "math/range.h" -#include "templates/optionalRef.h" -#include -#include -#include - -class SelectGeneratorNode; -class RegionGeneratorNodeBase; -class SQModule; -class RDFModule; -class Configuration; - -// Keyword Store -class KeywordStore -{ - public: - KeywordStore() = default; - ~KeywordStore() - { - // Remove keywords in this store from the global reference - // This is now a bit of a clumsy function since we do a separate remove/erase for each group. - // This will be tidied up as part of #1637 (Remove Static Singletons) - for (const auto §ion : sections_) - for (const auto &group : section.groups()) - { - auto it = - std::remove_if(allKeywords_.begin(), allKeywords_.end(), - [&](const auto *k) - { - return std::find_if(group.keywords().begin(), group.keywords().end(), [k](const auto &kd) - { return k == kd.first; }) != group.keywords().end(); - }); - allKeywords_.erase(it, allKeywords_.end()); - } - } - - /* - * Keyword Data - */ - private: - // Defined keyword sections - std::vector sections_; - // Current section accepting keywords - OptionalReferenceWrapper currentGroup_; - - private: - // Create keyword - template - KeywordBase *createKeyword(std::string_view name, std::string_view description, Args &&...args) - { - // Check for keyword of this name already - if (find(name)) - Messenger::exception("Keyword named '{}' already exists, and can't be added again.", name); - - // Create new keyword using the supplied arguments - K *k = new K(std::forward(args)...); - k->setBaseInfo(name, description); - - // Add the new keyword to the global reference vector - allKeywords_.push_back(k); - - return k; - } - // Add keyword to current section / group - void addKeywordToCurrentGroup(KeywordBase *keyword, KeywordBase::KeywordType type); - // Return named group, if it exists, optionally creating it if it doesn't - OptionalReferenceWrapper getGroup(std::string_view sectionName, std::string_view groupName, - std::optional groupDescription = {}, - bool createIfRequired = false); - - public: - // Set current group and section organisation - void setOrganisation(std::string_view sectionName, std::optional groupName = {}, - std::optional groupDescription = {}); - // Add target keyword - template - KeywordBase *addTarget(std::string_view name, std::string_view description, Args &&...args) - { - auto *k = createKeyword(name, description, args...); - - auto optTargetsGroup = getGroup("Options", "Targets", {}, true); - - optTargetsGroup->get().addKeyword(k, KeywordBase::KeywordType::Target); - - return k; - } - // Add hidden keyword (no group) - template - KeywordBase *addHidden(std::string_view name, std::string_view description, Args &&...args) - { - auto *k = createKeyword(name, description, args...); - - auto optHiddenGroup = getGroup("Options", "_HIDDEN", {}, true); - - optHiddenGroup->get().addKeyword(k, KeywordBase::KeywordType::Target); - - return k; - } - // Add keyword, displaying in current section/group - template KeywordBase *add(std::string_view name, std::string_view description, Args &&...args) - { - auto *k = createKeyword(name, description, args...); - - addKeywordToCurrentGroup(k, KeywordBase::KeywordType::Standard); - - return k; - } - // Add keyword (displaying in current section/group) and capture in restart file - template - KeywordBase *addRestartable(std::string_view name, std::string_view description, Args &&...args) - { - auto *k = createKeyword(name, description, args...); - - addKeywordToCurrentGroup(k, KeywordBase::KeywordType::Restartable); - - return k; - } - // Add deprecated keyword - template - KeywordBase *addDeprecated(std::string_view name, std::string_view description, Args &&...args) - { - auto *k = createKeyword(name, description, args...); - - auto optHiddenGroup = getGroup("Options", "_HIDDEN", {}, true); - - optHiddenGroup->get().addKeyword(k, KeywordBase::KeywordType::Deprecated); - - return k; - } - // Find named keyword - std::optional find(std::string_view name); - std::optional find(std::string_view name) const; - // Find all keywords of specified type - template std::vector allOfType() - { - std::vector result; - for (auto §ion : sections_) - { - auto subResult = section.allOfType(); - result.insert(result.end(), subResult.begin(), subResult.end()); - } - return result; - } - // Return all target keywords - std::vector targetKeywords(); - // Return defined keyword sections - const std::vector §ions() const; - // Return number of visible keywords defined over all sections - int nVisibleKeywords() const; - - /* - * Set / Get - */ - public: - // Set specified keyword with supplied data - bool set(std::string_view name, const bool value); - bool set(std::string_view name, const double value); - bool set(std::string_view name, const int value); - bool set(std::string_view name, const std::string value); - bool set(std::string_view name, const Function1DWrapper value); - bool set(std::string_view name, const Vector3 value); - bool set(std::string_view name, const Vector3i value); - bool set(std::string_view name, const Range value); - bool set(std::string_view name, const std::vector value); - bool set(std::string_view name, const std::shared_ptr value); - bool set(std::string_view name, const std::shared_ptr value); - bool set(std::string_view name, const std::vector value); - bool set(std::string_view name, const Module *value); - bool set(std::string_view name, Configuration *value); - bool set(std::string_view name, const std::vector value); - bool set(std::string_view name, const Species *value); - // Set specified enumerated keyword - template void setEnumeration(std::string_view name, E data) - { - auto optKeyword = find(name); - if (!optKeyword) - Messenger::exception("Enumerated keyword '{}' cannot be set as no suitable setter has been registered.\n", name); - - auto *k = dynamic_cast *>(optKeyword->first); - if (!k) - Messenger::exception("Couldn't cast keyword '{}' into type '{}'.\n", name, typeid(EnumOptionsKeyword).name()); - - k->data() = data; - } - - /* - * Getters for the Keyword Store. This should eventually be - * replaced with a single get function. The problem is two-fold. - * First, C++ doesn't allow for overloading on return-type, so we - * need a template that takes the return type as a parameter. That - * template can then be specialised to the individual return types, - * with the generic implementation throwing an exception. Now C++11 - * doesn't allow template specialisation within a member function. - * C++14 added support for this, but GCC still does not support this - * as of GCC 12. - */ - - // Retrieve a Configuration by keyword name - Configuration *getConfiguration(std::string_view name) const; - // Retrieve a vector of Configurations by keyword name - std::vector getVectorConfiguration(std::string_view name) const; - // Retrieve a Species by keyword name - const Species *getSpecies(std::string_view name) const; - // Retrieve an Integer by keyword name - int getInt(std::string_view name) const; - // Get specified keyword data, casting as necessary - template std::optional get(std::string_view name) const - { - auto optKeyword = find(name); - if (!optKeyword) - return {}; - - // Cast the keyword - const K *keyword = dynamic_cast(optKeyword->first); - if (!keyword) - Messenger::exception("Couldn't cast keyword '{}' into type '{}'.\n", name, typeid(K).name()); - - return keyword->data(); - } - template std::optional get(std::string_view name) - { - auto optKeyword = find(name); - if (!optKeyword) - return {}; - - // Cast the keyword - K *keyword = dynamic_cast(optKeyword->first); - if (!keyword) - Messenger::exception("Couldn't cast keyword '{}' into type '{}'.\n", name, typeid(K).name()); - - return keyword->data(); - } - // Get specified keyword enumeration, casting as necessary - template std::optional getEnumeration(std::string_view name) const - { - auto optKeyword = find(name); - if (!optKeyword) - return {}; - - // Cast the keyword - const auto *keyword = dynamic_cast *>(optKeyword->first); - if (!keyword) - Messenger::exception("Couldn't cast keyword '{}' into type '{}'.\n", name, typeid(EnumOptionsKeyword).name()); - - return keyword->data(); - } - - /* - * Read / Write - */ - public: - // Try to deserialise a single keyword through the specified LineParser - KeywordBase::ParseResult deserialise(LineParser &parser, const CoreData &coreData, int startArg = 0); - // Write all keywords to specified LineParser - bool serialise(LineParser &parser, std::string_view prefix, bool onlyIfSet = true) const; - // Apply the terms in the keyword store to a node - SerialisedValue serialiseOnto(SerialisedValue node) const; - // Pull keywords from entries in table - void deserialiseFrom(const SerialisedValue &node, const CoreData &coreData); - - /* - * Object Management - */ - private: - // Vector of all keywords in the store - std::vector allKeywords_; - - public: - // Gracefully deal with the specified object no longer being valid - template void objectNoLongerValid(O *object) - { - // Loop over all keyword objects and call their local functions - for (auto *kwd : allKeywords_) - kwd->removeReferencesTo(object); - } - - template void objectNoLongerValid(std::shared_ptr

object) - { - // Loop over all keyword objects and call their local functions - for (auto *kwd : allKeywords_) - kwd->removeReferencesTo(object); - } -}; diff --git a/src/keywords/vec3Double.cpp b/src/keywords/vec3Double.cpp deleted file mode 100644 index ddbbcc0b68..0000000000 --- a/src/keywords/vec3Double.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/vec3Double.h" -#include "base/lineParser.h" - -Vec3DoubleKeyword::Vec3DoubleKeyword(Vector3 &data, Vec3Labels::LabelType labelType) - : KeywordBase(typeid(this)), data_(data), default_(data), labelType_(labelType) -{ -} - -Vec3DoubleKeyword::Vec3DoubleKeyword(Vector3 &data, std::optional minValue, std::optional maxValue, - Vec3Labels::LabelType labelType) - : KeywordBase(typeid(this)), data_(data), minimumLimit_(minValue), maximumLimit_(maxValue), labelType_(labelType) -{ -} - -/* - * Data - */ - -// Set data -bool Vec3DoubleKeyword::setData(Vector3 value) -{ - if (minimumLimit_ && - (value.x < minimumLimit_.value().x || value.y < minimumLimit_.value().y || value.z < minimumLimit_.value().z)) - return false; - if (maximumLimit_ && - (value.x > maximumLimit_.value().x || value.y > maximumLimit_.value().y || value.z > maximumLimit_.value().z)) - return false; - - data_ = value; - - return true; -} - -// Return data -const Vector3 &Vec3DoubleKeyword::data() const { return data_; } - -// Return minimum limit -std::optional Vec3DoubleKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional Vec3DoubleKeyword::maximumLimit() const { return maximumLimit_; } - -/* - * Label Type - */ - -// Label type to display in GUI -Vec3Labels::LabelType Vec3DoubleKeyword::labelType() const { return labelType_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int Vec3DoubleKeyword::minArguments() const { return 3; } - -// Return maximum number of arguments accepted -std::optional Vec3DoubleKeyword::maxArguments() const { return 3; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool Vec3DoubleKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg + 2)) - { - auto v = parser.arg3d(startArg); - if (!setData(v)) - { - if (minimumLimit_ && maximumLimit_) - Messenger::error("Value [{:12.6e},{:12.6e},{:12.6e}] is out of range. Valid range is " - "[{:12.6e},{:12.6e},{:12.6e}] <= [x,y,z] " - "<= [{:12.6e},{:12.6e},{:12.6e}].\n", - v.x, v.y, v.z, minimumLimit_.value().x, minimumLimit_.value().y, minimumLimit_.value().z, - maximumLimit_.value().x, maximumLimit_.value().y, maximumLimit_.value().z); - else if (minimumLimit_) - Messenger::error("Value [{:12.6e},{:12.6e},{:12.6e}] is out of range. Valid range is " - "[{:12.6e},{:12.6e},{:12.6e}] <= [x,y,z].\n", - v.x, v.y, v.z, minimumLimit_.value().x, minimumLimit_.value().y, minimumLimit_.value().z); - else - Messenger::error("Value [{:12.6e},{:12.6e},{:12.6e}] is out of range. Valid range is [x,y,z] " - "<= [{:12.6e},{:12.6e},{:12.6e}].\n", - v.x, v.y, v.z, maximumLimit_.value().x, maximumLimit_.value().y, maximumLimit_.value().z); - - return false; - } - - return true; - } - return false; -} - -// Serialise data to specified LineParser -bool Vec3DoubleKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - return parser.writeLineF("{}{} {:12.6e} {:12.6e} {:12.6e}\n", prefix, keywordName, data_.x, data_.y, data_.z); -} - -// Has not changed from initial value -bool Vec3DoubleKeyword::isDefault() const { return data_ == default_; } - -// Express as a serialisable value -void Vec3DoubleKeyword::serialise(std::string tag, SerialisedValue &target) const { data_.serialise(tag, target); } - -// Read values from a serialisable value -void Vec3DoubleKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_.deserialise(node); } diff --git a/src/keywords/vec3Double.h b/src/keywords/vec3Double.h deleted file mode 100644 index 6c6f207c37..0000000000 --- a/src/keywords/vec3Double.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "keywords/vec3Labels.h" -#include "math/vector3.h" -#include - -// Keyword managing Vector3 -class Vec3DoubleKeyword : public KeywordBase -{ - public: - explicit Vec3DoubleKeyword(Vector3 &data, Vec3Labels::LabelType labelType = Vec3Labels::NoLabels); - explicit Vec3DoubleKeyword(Vector3 &data, std::optional minValue = std::nullopt, - std::optional maxValue = std::nullopt, - Vec3Labels::LabelType labelType = Vec3Labels::NoLabels); - - ~Vec3DoubleKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - Vector3 &data_; - // Initial Value - const Vector3 default_; - // Optional limits to apply - std::optional minimumLimit_, maximumLimit_; - - public: - // Has not changed from initial value - bool isDefault() const override; - // Set data - bool setData(Vector3 value); - // Return data - const Vector3 &data() const; - // Return minimum limit - std::optional minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - - /* - * Label Type - */ - private: - // Label type to display in GUI - Vec3Labels::LabelType labelType_; - - public: - // Label type to display in GUI - Vec3Labels::LabelType labelType() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/vec3Integer.cpp b/src/keywords/vec3Integer.cpp deleted file mode 100644 index 1777b723e7..0000000000 --- a/src/keywords/vec3Integer.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/vec3Integer.h" -#include "base/lineParser.h" - -Vec3IntegerKeyword::Vec3IntegerKeyword(Vector3i &data, std::optional minValue, std::optional maxValue, - Vec3Labels::LabelType labelType) - : KeywordBase(typeid(this)), data_(data), default_(data), minimumLimit_(minValue), maximumLimit_(maxValue), - labelType_(labelType) -{ -} - -/* - * Data - */ - -// Set data -bool Vec3IntegerKeyword::setData(Vector3i value) -{ - if (minimumLimit_ && - (value.x < minimumLimit_.value().x || value.y < minimumLimit_.value().y || value.z < minimumLimit_.value().z)) - return false; - if (maximumLimit_ && - (value.x > maximumLimit_.value().x || value.y > maximumLimit_.value().y || value.z > maximumLimit_.value().z)) - return false; - - data_ = value; - - return true; -} - -// Return data -const Vector3i &Vec3IntegerKeyword::data() const { return data_; } - -// Return minimum limit -std::optional Vec3IntegerKeyword::minimumLimit() const { return minimumLimit_; } - -// Return maximum limit -std::optional Vec3IntegerKeyword::maximumLimit() const { return maximumLimit_; } - -/* - * Label Type - */ - -// Label type to display in GUI -Vec3Labels::LabelType Vec3IntegerKeyword::labelType() const { return labelType_; } - -/* - * Arguments - */ - -// Return minimum number of arguments accepted -int Vec3IntegerKeyword::minArguments() const { return 3; } - -// Return maximum number of arguments accepted -std::optional Vec3IntegerKeyword::maxArguments() const { return 3; } - -// Deserialise from supplied LineParser, starting at given argument offset -bool Vec3IntegerKeyword::deserialise(LineParser &parser, int startArg, const CoreData &coreData) -{ - if (parser.hasArg(startArg + 2)) - { - auto v = parser.arg3i(startArg); - if (!setData(v)) - { - if (minimumLimit_ && maximumLimit_) - Messenger::error("Value [{},{},{}] is out of range. Valid range is " - "[{},{},{}] <= [x,y,z] " - "<= [{},{},{}].\n", - v.x, v.y, v.z, minimumLimit_.value().x, minimumLimit_.value().y, minimumLimit_.value().z, - maximumLimit_.value().x, maximumLimit_.value().y, maximumLimit_.value().z); - else if (minimumLimit_) - Messenger::error("Value [{},{},{}] is out of range. Valid range is " - "[{},{},{}] <= [x,y,z].\n", - v.x, v.y, v.z, minimumLimit_.value().x, minimumLimit_.value().y, minimumLimit_.value().z); - else - Messenger::error("Value [{},{},{}] is out of range. Valid range is [x,y,z] " - "<= [{},{},{}].\n", - v.x, v.y, v.z, maximumLimit_.value().x, maximumLimit_.value().y, maximumLimit_.value().z); - - return false; - } - - return true; - } - return false; -} - -// Serialise data to specified LineParser -bool Vec3IntegerKeyword::serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const -{ - return parser.writeLineF("{}{} {} {} {}\n", prefix, keywordName, data_.x, data_.y, data_.z); -} - -// Express as a serialisable value -void Vec3IntegerKeyword::serialise(std::string tag, SerialisedValue &target) const { target[tag] = data_; } - -// Read values from a serialisable value -void Vec3IntegerKeyword::deserialise(const SerialisedValue &node, const CoreData &coreData) { data_.deserialise(node); } - -// Has not changed from initial value -bool Vec3IntegerKeyword::isDefault() const { return data_ == default_; } diff --git a/src/keywords/vec3Integer.h b/src/keywords/vec3Integer.h deleted file mode 100644 index 767f7e6b2d..0000000000 --- a/src/keywords/vec3Integer.h +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -#include "keywords/base.h" -#include "keywords/vec3Labels.h" -#include "math/vector3i.h" -#include - -// Keyword managing Vector3i -class Vec3IntegerKeyword : public KeywordBase -{ - public: - explicit Vec3IntegerKeyword(Vector3i &data, std::optional minValue = std::nullopt, - std::optional maxValue = std::nullopt, - Vec3Labels::LabelType labelType = Vec3Labels::NoLabels); - ~Vec3IntegerKeyword() override = default; - - /* - * Data - */ - private: - // Reference to target data - Vector3i &data_; - // Initial Value - const Vector3i default_; - // Optional limits to apply - std::optional minimumLimit_, maximumLimit_; - - public: - // Has not changed from initial value - bool isDefault() const override; - // Set data - bool setData(Vector3i value); - // Return data - const Vector3i &data() const; - // Return minimum limit - std::optional minimumLimit() const; - // Return maximum limit - std::optional maximumLimit() const; - - /* - * Label Type - */ - private: - // Label type to display in GUI - Vec3Labels::LabelType labelType_; - - public: - // Label type to display in GUI - Vec3Labels::LabelType labelType() const; - - /* - * Arguments - */ - public: - // Return minimum number of arguments accepted - int minArguments() const override; - // Return maximum number of arguments accepted - std::optional maxArguments() const override; - // Deserialise from supplied LineParser, starting at given argument offset - bool deserialise(LineParser &parser, int startArg, const CoreData &coreData) override; - // Serialise data to specified LineParser - bool serialise(LineParser &parser, std::string_view keywordName, std::string_view prefix) const override; - // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const override; - // Read values from a serialisable value - void deserialise(const SerialisedValue &node, const CoreData &coreData) override; -}; diff --git a/src/keywords/vec3Labels.h b/src/keywords/vec3Labels.h deleted file mode 100644 index 9ea1c23db0..0000000000 --- a/src/keywords/vec3Labels.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#pragma once - -// Labels for Vec3 Keyword -class Vec3Labels -{ - public: - // Label Types - enum LabelType - { - NoLabels, - ABCLabels, - AlphaBetaGammaLabels, - HKLLabels, - MinMaxDeltaLabels, - MinMaxBinwidthlabels, - XYZLabels - }; -}; diff --git a/src/main/dissolve.cpp b/src/main/dissolve.cpp index 552de0e9fd..adb594d74c 100644 --- a/src/main/dissolve.cpp +++ b/src/main/dissolve.cpp @@ -45,7 +45,6 @@ void Dissolve::clear() // Simulation Messenger::printVerbose("Clearing Simulation...\n"); - processingModuleData_.clearAll(); iteration_ = 0; nIterationsPerformed_ = 0; @@ -57,10 +56,3 @@ void Dissolve::clear() restartFilename_.clear(); saveRestartTimes_.clear(); } - -/* - * Processing Module Data - */ - -// Return data associated with processing Modules -GenericList &Dissolve::processingModuleData() { return processingModuleData_; } diff --git a/src/main/dissolve.h b/src/main/dissolve.h index e2f83d5bec..bdcd6e3399 100644 --- a/src/main/dissolve.h +++ b/src/main/dissolve.h @@ -9,7 +9,6 @@ #include "classes/coreData.h" #include "classes/pairPotential.h" #include "classes/potentialMap.h" -#include "items/list.h" #include "math/sampledDouble.h" // Forward Declarations @@ -21,7 +20,7 @@ class Isotopologue; class Molecule; // Dissolve Main Class -class Dissolve : public Serialisable<> +class Dissolve : public Serialisable { public: Dissolve(CoreData &coreData); @@ -78,19 +77,6 @@ class Dissolve : public Serialisable<> PotentialMap &potentialMap(); // Update all pair potentials bool updatePairPotentials(std::optional useCombinationRulesHint = {}); - // Clear additional potentials - void clearAdditionalPotentials(); - - /* - * Processing Module Data - */ - private: - // Data associated with processing Modules - GenericList processingModuleData_; - - public: - // Return data associated with main processing Modules - GenericList &processingModuleData(); /* * Graph node diff --git a/src/main/io.cpp b/src/main/io.cpp index 29a92c8afa..71372c5a70 100644 --- a/src/main/io.cpp +++ b/src/main/io.cpp @@ -109,7 +109,7 @@ void Dissolve::deserialise(const SerialisedValue &originalNode) { auto *cfg = coreData_.addConfiguration(); cfg->setName(name); - cfg->deserialise(data, coreData_); + cfg->deserialise(data); }); } diff --git a/src/main/pairPotentials.cpp b/src/main/pairPotentials.cpp index 0dc13e344c..09e6c7b024 100644 --- a/src/main/pairPotentials.cpp +++ b/src/main/pairPotentials.cpp @@ -131,30 +131,17 @@ bool Dissolve::updatePairPotentials(std::optional useCombinationRulesHint) // REMOVED for Dissolve2 // Fourth step - set any additional potential - for (auto &&[at1, at2, pp] : pairPotentials_) - { - // Check processing module data for a named additional potential - auto addPotName = std::format("Potential_{}-{}_Additional", at1->name(), at2->name()); - if (processingModuleData_.contains(addPotName, "Dissolve")) - pp->setAdditionalPotential(processingModuleData_.retrieve(addPotName, "Dissolve")); - } + // TODO DISSOLVE2 + // for (auto &&[at1, at2, pp] : pairPotentials_) + // { + // // Check processing module data for a named additional potential + // auto addPotName = std::format("Potential_{}-{}_Additional", at1->name(), at2->name()); + // if (processingModuleData_.contains(addPotName, "Dissolve")) + // pp->setAdditionalPotential(processingModuleData_.retrieve(addPotName, "Dissolve")); + // } // Reinitialise the potential map // DSABLED FOR DISSOLVE2 // return potentialMap_.initialise(coreData_.atomTypes(), pairPotentials_); return true; } - -// Clear additional potentials -void Dissolve::clearAdditionalPotentials() -{ - for (auto &&[at1, at2, pp] : pairPotentials_) - { - pp->resetAdditionalPotential(); - - // Clear entry in processing module data if it exists - auto itemName = std::format("Potential_{}-{}_Additional", at1->name(), at2->name()); - if (processingModuleData_.contains(itemName, "Dissolve")) - processingModuleData_.remove(itemName, "Dissolve"); - } -} diff --git a/src/math/data1D.cpp b/src/math/data1D.cpp index 2d9d57779b..adf8dbd191 100644 --- a/src/math/data1D.cpp +++ b/src/math/data1D.cpp @@ -416,63 +416,6 @@ void Data1D::operator/=(const double factor) * Serialisation */ -// Read data through specified LineParser -bool Data1D::deserialise(LineParser &parser) -{ - clear(); - - // Read name - if (parser.readNextLine(LineParser::KeepBlanks) != LineParser::Success) - return false; - tag_ = parser.line(); - - // Read number of points and whether errors are present - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nPoints = parser.argi(0); - auto errors = parser.argb(1); - initialise(nPoints, errors); - - // Read data points - for (auto n = 0; n < nPoints; ++n) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - x_[n] = parser.argd(0); - values_[n] = parser.argd(1); - if (hasError_) - errors_[n] = parser.argd(2); - } - - return true; -} - -// Write data through specified LineParser -bool Data1D::serialise(LineParser &parser) const -{ - // Write tag - if (!parser.writeLineF("{}\n", tag_)) - return false; - - // Write axis size and errors flag - if (!parser.writeLineF("{} {}\n", x_.size(), DissolveSys::btoa(hasError_))) - return false; - - // Write values / errors - if (hasError_) - { - for (auto &&[x, value, error] : zip(x_, values_, errors_)) - if (!parser.writeLineF("{} {} {}\n", x, value, error)) - return false; - } - else - for (auto &&[x, value] : zip(x_, values_)) - if (!parser.writeLineF("{} {}\n", x, value)) - return false; - - return true; -} - // Express as a serialisable value void Data1D::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/math/data1D.h b/src/math/data1D.h index 9473013082..4aaea592fb 100644 --- a/src/math/data1D.h +++ b/src/math/data1D.h @@ -10,7 +10,7 @@ #include // One-Dimensional Data -class Data1D : public Data1DBase, public Serialisable<> +class Data1D : public Data1DBase, public Serialisable { public: Data1D(); @@ -114,10 +114,6 @@ class Data1D : public Data1DBase, public Serialisable<> * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value diff --git a/src/math/data2D.cpp b/src/math/data2D.cpp index 5cb0a49ebd..d6be8d0c44 100644 --- a/src/math/data2D.cpp +++ b/src/math/data2D.cpp @@ -320,106 +320,6 @@ void Data2D::operator/=(const double factor) * Serialisation */ -// Read data through specified LineParser -bool Data2D::deserialise(LineParser &parser) -{ - clear(); - - // Read object tag - if (parser.readNextLine(LineParser::KeepBlanks) != LineParser::Success) - return false; - tag_ = parser.line(); - - // Read axis sizes and initialise arrays - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto xSize = parser.argi(0); - auto ySize = parser.argi(1); - auto errors = parser.argb(2); - initialise(xSize, ySize, errors); - - // Read x axis - for (auto &x : x_) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - x = parser.argd(0); - } - - // Read y axis - for (auto &y : y_) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - y = parser.argd(0); - } - - // Read errors / valuse - if (hasError_) - { - for (auto index : ArrayIndex2D(values_)) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - values_[index] = parser.argd(0); - errors_[index] = parser.argd(1); - } - } - else - { - for (auto index : ArrayIndex2D(values_)) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - values_[index] = parser.argd(0); - } - } - - return true; -} - -// Write data through specified LineParser -bool Data2D::serialise(LineParser &parser) const -{ - // Write object tag - if (!parser.writeLineF("{}\n", tag_)) - return false; - - // Write axis sizes and errors flag - if (!parser.writeLineF("{} {} {}\n", x_.size(), y_.size(), DissolveSys::btoa(hasError_))) - return false; - - // Write x axis array - for (auto x : x_) - if (!parser.writeLineF("{:e}\n", x)) - return false; - - // Write y axis array - for (auto y : y_) - if (!parser.writeLineF("{:e}\n", y)) - return false; - - // Write values / errors - if (hasError_) - { - for (auto index : ArrayIndex2D(values_)) - { - if (!parser.writeLineF("{:e} {:e}\n", values_[index], errors_[index])) - return false; - } - } - else - { - for (auto index : ArrayIndex2D(values_)) - { - if (!parser.writeLineF("{:e} {:e}\n", values_[index], errors_[index])) - return false; - } - } - - return true; -} - // Express as a serialisable value void Data2D::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/math/data2D.h b/src/math/data2D.h index b075141d50..12a157df9f 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 Serialisable { public: Data2D(); @@ -108,10 +108,6 @@ class Data2D : public Data2DBase, public Serialisable<> * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value diff --git a/src/math/data3D.cpp b/src/math/data3D.cpp index 4c3f84a376..b10f0d6d61 100644 --- a/src/math/data3D.cpp +++ b/src/math/data3D.cpp @@ -329,114 +329,29 @@ void Data3D::operator/=(const double factor) * Serialisation */ -// Read data through specified LineParser -bool Data3D::deserialise(LineParser &parser) +// Express as a serialisable value +void Data3D::serialise(std::string tag, SerialisedValue &target) const { - clear(); - - // Read object name - if (parser.readNextLine(LineParser::KeepBlanks) != LineParser::Success) - return false; - tag_ = parser.line(); - - // Read axis sizes and initialise arrays - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto xSize = parser.argi(0); - auto ySize = parser.argi(1); - auto zSize = parser.argi(2); - auto errors = parser.argb(3); - initialise(xSize, ySize, zSize, errors); - - // Read x axis - for (auto &x : x_) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - x = parser.argd(0); - } - - // Read y axis - for (auto &y : y_) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - y = parser.argd(0); - } - - // Read z axis - for (auto &z : z_) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - z = parser.argd(0); - } - - // Read errors / valuse + target[tag] = {{"tag", tag_}, {"x", x_}, {"y", y_}, {"z", z_}, {"values", values_.linearArray()}}; if (hasError_) - { - for (auto index : ArrayIndex3D(values_)) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - values_[index] = parser.argd(0); - errors_[index] = parser.argd(1); - } - } - else - { - for (auto &value : values_) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - value = parser.argd(0); - } - } - - return true; + target[tag]["errors"] = errors_.linearArray(); } -// Write data through specified LineParser -bool Data3D::serialise(LineParser &parser) const +// Read values from a serialisable value +void Data3D::deserialise(const SerialisedValue &node) { - // Write tag - if (!parser.writeLineF("{}\n", tag_)) - return false; - - // Write axis sizes and errors flag - if (!parser.writeLineF("{} {} {} {}\n", x_.size(), y_.size(), z_.size(), DissolveSys::btoa(hasError_))) - return false; - - // Write x axis array - for (auto x : x_) - if (!parser.writeLineF("{:e}\n", x)) - return false; - - // Write y axis array - for (auto y : y_) - if (!parser.writeLineF("{:e}\n", y)) - return false; - - // Write z axis array - for (auto z : z_) - if (!parser.writeLineF("{:e}\n", z)) - return false; - - // Write values / errors - if (hasError_) - { - for (auto index : ArrayIndex3D(values_)) - { - if (!parser.writeLineF("{:e} {:e}\n", values_[index], errors_[index])) - return false; - } - } - else - { - for (const auto &value : values_) - if (!parser.writeLineF("{:e}\n", value)) - return false; - } - - return true; + tag_ = toml::find(node, "tag"); + x_ = toml::find>(node, "x"); + y_ = toml::find>(node, "y"); + z_ = toml::find>(node, "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); + }); } diff --git a/src/math/data3D.h b/src/math/data3D.h index f9bb4c98b1..729efc8252 100644 --- a/src/math/data3D.h +++ b/src/math/data3D.h @@ -11,7 +11,7 @@ class Histogram3D; // One-Dimensional Data -class Data3D : public Data3DBase +class Data3D : public Data3DBase, public Serialisable { public: Data3D(); @@ -118,8 +118,8 @@ class Data3D : public Data3DBase * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; + // Express as a serialisable value + void serialise(std::string tag, SerialisedValue &target) const override; + // Read values from a serialisable value + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/function1D.h b/src/math/function1D.h index 646a9a193b..b198a25043 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 Serialisable { public: Function1DWrapper(Functions1D::Form form = Functions1D::Form::None, const std::vector ¶ms = {}); diff --git a/src/math/histogram1D.cpp b/src/math/histogram1D.cpp index c137dee1cf..3ab2d225f8 100644 --- a/src/math/histogram1D.cpp +++ b/src/math/histogram1D.cpp @@ -212,41 +212,6 @@ Histogram1D Histogram1D::operator+(const Histogram1D &other) const * Serialisation */ -// Read data through specified LineParser -bool Histogram1D::deserialise(LineParser &parser) -{ - clear(); - - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - initialise(parser.argd(0), parser.argd(1), parser.argd(2)); - - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - nBinned_ = parser.argli(0); - nMissed_ = parser.argli(1); - - for (auto n = 0; n < nBins_; ++n) - if (!averages_[n].deserialise(parser)) - return false; - - return true; -} - -// Write data through specified LineParser -bool Histogram1D::serialise(LineParser &parser) const -{ - if (!parser.writeLineF("{} {} {}\n", minimum_, maximum_, binWidth_)) - return false; - if (!parser.writeLineF("{} {}\n", nBinned_, nMissed_)) - return false; - for (auto n = 0; n < nBins_; ++n) - if (!averages_.at(n).serialise(parser)) - return false; - - return true; -} - // Express as a serialisable value void Histogram1D::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/math/histogram1D.h b/src/math/histogram1D.h index a8a06ecce6..29d0387fd9 100644 --- a/src/math/histogram1D.h +++ b/src/math/histogram1D.h @@ -7,7 +7,7 @@ #include "math/sampledDouble.h" // One-Dimensional Histogram -class Histogram1D : public Serialisable<> +class Histogram1D : public Serialisable { public: Histogram1D(); @@ -90,12 +90,8 @@ class Histogram1D : public Serialisable<> * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/histogram2D.cpp b/src/math/histogram2D.cpp index b29f86ec6d..665f7c21e7 100644 --- a/src/math/histogram2D.cpp +++ b/src/math/histogram2D.cpp @@ -43,6 +43,22 @@ void Histogram2D::clear() * Data */ +// Update accumulated data +void Histogram2D::updateAccumulatedData() +{ + // Set up arrays + accumulatedData_.initialise(bins_.size(), true); + + // Store bin centres and accumulated averages in the object + for (auto n = 0; n < bins_.size(); ++n) + { + accumulatedData_.xAxis(n) = xBinCentres_[n]; + accumulatedData_.yAxis(n) = yBinCentres_[n]; + accumulatedData_.values().linearArray()[n] = averages_[n]; + accumulatedData_.errors().linearArray()[n] = averages_[n].stDev(); + } +} + // Initialise with specified bin range void Histogram2D::initialise(double xMin, double xMax, double xBinWidth, double yMin, double yMax, double yBinWidth) { @@ -204,43 +220,27 @@ void Histogram2D::operator=(const Histogram2D &source) * Serialisation */ -// Read data through specified LineParser -bool Histogram2D::deserialise(LineParser &parser) +// Express as a serialisable value +void Histogram2D::serialise(std::string tag, SerialisedValue &target) const { - clear(); - - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - initialise(parser.argd(0), parser.argd(1), parser.argd(2), parser.argd(3), parser.argd(4), parser.argd(5)); + target[tag] = {{"xMinimum", xMinimum_}, {"xMaximum", xMaximum_}, {"xBinWidth", xBinWidth_}, + {"yMinimum", yMinimum_}, {"yMaximum", yMaximum_}, {"yBinWidth", yBinWidth_}, + {"nBinned", nBinned_}, {"nMissed", nMissed_}, {"averages", averages_.linearArray()}}; +} - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - nBinned_ = parser.argli(0); - nMissed_ = parser.argli(1); +// Read values from a serialisable value +void Histogram2D::deserialise(const SerialisedValue &node) +{ + clear(); - for (auto x = 0; x < nXBins_; ++x) - { - for (auto y = 0; y < nYBins_; ++y) - if (!averages_[{x, y}].deserialise(parser)) - return false; - } + 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")); - return true; -} + nBinned_ = toml::find(node, "nBinned"); + nMissed_ = toml::find(node, "nMissed"); -// Write data through specified LineParser -bool Histogram2D::serialise(LineParser &parser) const -{ - if (!parser.writeLineF("{} {} {} {} {} {}\n", xMinimum_, xMaximum_, xBinWidth_, yMinimum_, yMaximum_, yBinWidth_)) - return false; - if (!parser.writeLineF("{} {}\n", nBinned_, nMissed_)) - return false; - for (auto x = 0; x < nXBins_; ++x) - { - for (auto y = 0; y < nYBins_; ++y) - if (!averages_[{x, y}].serialise(parser)) - return false; - } + averages_.linearArray() = toml::find>(node, "averages"); - return true; -} + updateAccumulatedData(); +} \ No newline at end of file diff --git a/src/math/histogram2D.h b/src/math/histogram2D.h index 81072a8e64..a7f89efd82 100644 --- a/src/math/histogram2D.h +++ b/src/math/histogram2D.h @@ -8,7 +8,7 @@ #include "templates/array2D.h" // Two-Dimensional Histogram -class Histogram2D +class Histogram2D : public Serialisable { public: Histogram2D(); @@ -53,6 +53,10 @@ class Histogram2D // Accumulated data Data2D accumulatedData_; + private: + // Update accumulated data + void updateAccumulatedData(); + public: // Initialise with specified bin range void initialise(double xMinimum, double xMaximum, double xBinWidth, double yMinimum, double yMaximum, double yBinWidth); @@ -101,8 +105,8 @@ class Histogram2D * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; + // Express as a serialisable value + void serialise(std::string tag, SerialisedValue &target) const override; + // Read values from a serialisable value + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/histogram3D.cpp b/src/math/histogram3D.cpp index 713c01b241..9a00b9ce0a 100644 --- a/src/math/histogram3D.cpp +++ b/src/math/histogram3D.cpp @@ -242,39 +242,29 @@ void Histogram3D::operator=(const Histogram3D &source) * Serialisation */ -// Read data through specified LineParser -bool Histogram3D::deserialise(LineParser &parser) +// Express as a serialisable value +void Histogram3D::serialise(std::string tag, SerialisedValue &target) const { - clear(); + 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()}}; +} - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - initialise(parser.argd(0), parser.argd(1), parser.argd(2), parser.argd(3), parser.argd(4), parser.argd(5), parser.argd(6), - parser.argd(7), parser.argd(8)); +// Read values from a serialisable value +void Histogram3D::deserialise(const SerialisedValue &node) +{ + clear(); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - nBinned_ = parser.argli(0); - nMissed_ = parser.argli(1); + 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")); - for (auto &average : averages_) - if (!average.deserialise(parser)) - return false; + nBinned_ = toml::find(node, "nBinned"); + nMissed_ = toml::find(node, "nMissed"); - return true; -} + averages_.linearArray() = toml::find>(node, "averages"); -// Write data through specified LineParser -bool Histogram3D::serialise(LineParser &parser) const -{ - if (!parser.writeLineF("{} {} {} {} {} {} {} {} {}\n", xMinimum_, xMaximum_, xBinWidth_, yMinimum_, yMaximum_, yBinWidth_, - zMinimum_, zMaximum_, zBinWidth_)) - return false; - if (!parser.writeLineF("{} {}\n", nBinned_, nMissed_)) - return false; - for (auto &average : averages_) - if (!average.serialise(parser)) - return false; - - return true; -} + updateAccumulatedData(); +} \ No newline at end of file diff --git a/src/math/histogram3D.h b/src/math/histogram3D.h index 638cff0484..118fe50109 100644 --- a/src/math/histogram3D.h +++ b/src/math/histogram3D.h @@ -7,8 +7,7 @@ #include "math/sampledDouble.h" #include "templates/array3D.h" -// Three-Dimensional Histogram -class Histogram3D +class Histogram3D : public Serialisable { public: Histogram3D(); @@ -128,8 +127,8 @@ class Histogram3D * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; + // Express as a serialisable value + void serialise(std::string tag, SerialisedValue &target) const override; + // Read values from a serialisable value + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/history.h b/src/math/history.h index d557824d7c..b5ceb8b030 100644 --- a/src/math/history.h +++ b/src/math/history.h @@ -11,7 +11,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 Serialisable { public: History(std::function initialiser = {}) : initialiser_(std::move(initialiser)) {} @@ -55,7 +55,7 @@ template class History : public Serialisable<> */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const + void serialise(std::string tag, SerialisedValue &target) const override { return Serialisable::fromVector(history_, tag, target, [&](const auto &itemPtr) { return itemPtr->into_toml(); }); } @@ -75,7 +75,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 : public Serialisable { private: // Stored historical data @@ -110,7 +110,7 @@ template class PODHistory : public Serialisable<> */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const + void serialise(std::string tag, SerialisedValue &target) const override { if (history_.empty()) return; diff --git a/src/math/integerHistogram1D.cpp b/src/math/integerHistogram1D.cpp index 4b4a8d324d..bd10f204c5 100644 --- a/src/math/integerHistogram1D.cpp +++ b/src/math/integerHistogram1D.cpp @@ -153,62 +153,32 @@ const Data1D &IntegerHistogram1D::accumulatedData() const { return accumulatedDa * Serialisation */ -// Read data through specified LineParser -bool IntegerHistogram1D::deserialise(LineParser &parser) +// Express as a serialisable value +void IntegerHistogram1D::serialise(std::string tag, SerialisedValue &target) const { - clear(); - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - std::optional minLim = parser.argb(0) ? std::optional(parser.argi(1)) : std::nullopt; - std::optional maxLim = parser.argb(2) ? std::optional(parser.argi(3)) : std::nullopt; - initialise(minLim, maxLim); - - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - nBinned_ = parser.argli(0); - nMissed_ = parser.argli(1); - - if (!zeroCounter_.deserialise(parser)) - return false; + target[tag] = {{"zeroCounter", zeroCounter_}, {"nBinned", nBinned_}, {"nMissed", nMissed_}}; - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto nBins = parser.argli(0); - for (auto n = 0; n < nBins; ++n) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - auto bin = parser.argi(0); - raw_[bin] = parser.argli(1); - averages_[bin].deserialise(parser); - } + if (minimum_) + target[tag]["minimum"] = *minimum_; + if (maximum_) + target[tag]["maximum"] = *maximum_; - return true; + fromMap(averages_, "averages", target); } -// Write data through specified LineParser -bool IntegerHistogram1D::serialise(LineParser &parser) const +// Read values from a serialisable value +void IntegerHistogram1D::deserialise(const SerialisedValue &node) { - if (!parser.writeLineF("{} {} {} {}\n", DissolveSys::btoa(minimum_.has_value()), minimum_.value_or(0), - DissolveSys::btoa(maximum_.has_value()), maximum_.value_or(0))) - return false; - - if (!parser.writeLineF("{} {}\n", nBinned_, nMissed_)) - return false; + clear(); - if (!zeroCounter_.serialise(parser)) - return false; + getIfPresent(node, "minimum", minimum_); + getIfPresent(node, "maximum", maximum_); - if (!parser.writeLineF("{}\n", averages_.size())) - return false; + nBinned_ = toml::find(node, "nBinned"); + nMissed_ = toml::find(node, "nMissed"); + zeroCounter_ = toml::find(node, "nMissed"); - for (auto &[key, value] : averages_) - { - if (!parser.writeLineF("{} {}\n", key, raw_.at(key))) - return false; - if (!value.serialise(parser)) - return false; - } + toMap(node, "averages", [&](const auto &key, const auto &value) { averages_[std::stoi(key)].deserialise(value); }); - return true; + updateAccumulatedData(); } diff --git a/src/math/integerHistogram1D.h b/src/math/integerHistogram1D.h index bc72d60eaa..496919ff2f 100644 --- a/src/math/integerHistogram1D.h +++ b/src/math/integerHistogram1D.h @@ -3,13 +3,11 @@ #pragma once -#include "keywords/optionalInt.h" #include "math/data1D.h" #include "math/sampledDouble.h" #include -// Pure Integer Histogram -class IntegerHistogram1D +class IntegerHistogram1D : public Serialisable { public: IntegerHistogram1D(); @@ -70,8 +68,8 @@ class IntegerHistogram1D * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; + // Express as a serialisable value + void serialise(std::string tag, SerialisedValue &target) const override; + // Read values from a serialisable value + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/range.h b/src/math/range.h index a081cbe8ea..65c7f22f4d 100644 --- a/src/math/range.h +++ b/src/math/range.h @@ -8,7 +8,7 @@ #include // Range -class Range : public Serialisable<> +class Range : public Serialisable { public: Range(std::optional minimum = std::nullopt, std::optional maximum = std::nullopt); diff --git a/src/math/rangedVector3.h b/src/math/rangedVector3.h index 08d55e6b65..8c0c051a3d 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 Serialisable { public: RangedVector3() = default; diff --git a/src/math/sampledData1D.cpp b/src/math/sampledData1D.cpp index 08585c8db2..fb85d55178 100644 --- a/src/math/sampledData1D.cpp +++ b/src/math/sampledData1D.cpp @@ -148,68 +148,6 @@ void SampledData1D::operator+=(const std::vector &source) * Serialisation */ -// Read data through specified LineParser -bool SampledData1D::deserialise(LineParser &parser) -{ - clear(); - - // Read tag - if (parser.readNextLine(LineParser::KeepBlanks) != LineParser::Success) - return false; - tag_ = parser.line(); - - // Read number of points and sample size - if (parser.getArgsDelim(LineParser::KeepBlanks) != LineParser::Success) - return false; - auto nPoints = parser.argi(0); - auto count = parser.argi(1); - - // Read samples into temporary arrays, then set values_ at the end - x_.reserve(nPoints); - std::vector mean, stDev, m2; - mean.reserve(nPoints); - stDev.reserve(nPoints); - m2.reserve(nPoints); - for (auto n = 0; n < nPoints; ++n) - { - if (parser.getArgsDelim(LineParser::KeepBlanks) != LineParser::Success) - return false; - - x_.push_back(parser.argd(0)); - mean.push_back(parser.argd(1)); - stDev.push_back(parser.argd(2)); - m2.push_back(parser.argd(3)); - } - values_.initialise(count, mean, stDev, m2); - - return true; -} - -// Read value data only through specified LineParser -bool SampledData1D::deserialiseValues(LineParser &parser) { return values_.deserialise(parser); } - -// Write data through specified LineParser -bool SampledData1D::serialise(LineParser &parser) const -{ - // Write tag - if (!parser.writeLine(tag_)) - return false; - - // Write number of points and sample size - if (!parser.writeLineF("{} {} # nData count\n", x_.size(), values_.count())) - return false; - - // Write four-column format : x, mean, stDev, m2 - for (auto &&[x, mean, m2, stDev] : zip(x_, values_.values(), values_.m2(), values_.stDev())) - if (!parser.writeLineF("{} {} {} {}\n", x, mean, m2, stDev)) - return false; - - return true; -} - -// Write value data only through specified LineParser -bool SampledData1D::serialiseValues(LineParser &parser) const { return values_.serialise(parser); } - // Express as a serialisable value void SampledData1D::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/math/sampledData1D.h b/src/math/sampledData1D.h index 1ffd9c730d..77e01f40ee 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 Serialisable { public: SampledData1D(); @@ -82,16 +82,8 @@ class SampledData1D : public Data1DBase, public Serialisable<> * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Read value data only through specified LineParser - bool deserialiseValues(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; - // Write value data only through specified LineParser - bool serialiseValues(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/sampledDouble.cpp b/src/math/sampledDouble.cpp index 08cf1cad55..448f6a9dab 100644 --- a/src/math/sampledDouble.cpp +++ b/src/math/sampledDouble.cpp @@ -141,21 +141,6 @@ void SampledDouble::operator/=(double x) * Serialisation */ -// Read data through specified LineParser -bool SampledDouble::deserialise(LineParser &parser) -{ - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - mean_ = parser.argd(0); - count_ = parser.argi(1); - m2_ = parser.argd(2); - - return true; -} - -// Write data through specified LineParser -bool SampledDouble::serialise(LineParser &parser) const { return parser.writeLineF("{} {} {}\n", mean_, count_, m2_); } - // Express as a serialisable value void SampledDouble::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/math/sampledDouble.h b/src/math/sampledDouble.h index 06fd6f3db3..91c65cc9ab 100644 --- a/src/math/sampledDouble.h +++ b/src/math/sampledDouble.h @@ -11,7 +11,7 @@ class LineParser; class ProcessPool; // Double value with sampling -class SampledDouble : public Serialisable<> +class SampledDouble : public Serialisable { public: SampledDouble(); @@ -61,10 +61,6 @@ class SampledDouble : public Serialisable<> * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value diff --git a/src/math/sampledVector.cpp b/src/math/sampledVector.cpp index 17cf82290a..07ae14ebf9 100644 --- a/src/math/sampledVector.cpp +++ b/src/math/sampledVector.cpp @@ -174,40 +174,6 @@ void SampledVector::operator/=(double x) * Serialisation */ -// Read data through specified LineParser -bool SampledVector::deserialise(LineParser &parser) -{ - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - initialise(parser.argi(0)); - count_ = parser.argi(1); - - for (auto &&[mean, stDev, m2] : zip(mean_, stDev_, m2_)) - { - if (parser.getArgsDelim(LineParser::Defaults) != LineParser::Success) - return false; - - mean = parser.argd(0); - stDev = parser.argd(1); - m2 = parser.argd(2); - } - - return true; -} - -// Write data through specified LineParser -bool SampledVector::serialise(LineParser &parser) const -{ - if (!parser.writeLineF("{} {} # nData count\n", mean_.size(), count_)) - return false; - - for (auto &&[mean, stDev, m2] : zip(mean_, stDev_, m2_)) - if (!parser.writeLineF("{} {} {}\n", mean, stDev, m2)) - return false; - - return true; -} - // Express as a serialisable value void SampledVector::serialise(std::string tag, SerialisedValue &target) const { diff --git a/src/math/sampledVector.h b/src/math/sampledVector.h index 3f3101192a..c10bce4b5e 100644 --- a/src/math/sampledVector.h +++ b/src/math/sampledVector.h @@ -11,7 +11,7 @@ class CoreData; class LineParser; // Vector of double values with sampling -class SampledVector : public Serialisable<> +class SampledVector : public Serialisable { public: SampledVector(); @@ -63,12 +63,8 @@ class SampledVector : public Serialisable<> * Serialisation */ public: - // Read data through specified LineParser - bool deserialise(LineParser &parser); - // Write data through specified LineParser - bool serialise(LineParser &parser) const; // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/vector3.h b/src/math/vector3.h index 377c60b0e2..6e842cd4ce 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 Serialisable { public: Vector3() = default; @@ -140,5 +140,5 @@ class Vector3 : public Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/math/vector3i.h b/src/math/vector3i.h index 524a308e92..90831cbf5f 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 Serialisable { public: Vector3i() = default; @@ -115,5 +115,5 @@ class Vector3i : public Serialisable<> // Express as a serialisable value void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value - void deserialise(const SerialisedValue &node); + void deserialise(const SerialisedValue &node) override; }; diff --git a/src/nodes/edge.h b/src/nodes/edge.h index dcb21ac37d..4d69360cf8 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 Serialisable { public: EdgeDefinition() = default; @@ -29,7 +29,7 @@ class EdgeDefinition : public Serialisable<> }; // Edge -class Edge : public Serialisable<> +class Edge : public Serialisable { friend class LoopEdge; diff --git a/src/nodes/epsr.h b/src/nodes/epsr.h index 8802fb10ee..9ecd07c3b7 100644 --- a/src/nodes/epsr.h +++ b/src/nodes/epsr.h @@ -18,7 +18,7 @@ class AtomType; class PartialSet; -class EPSRNamedTargetWeights : public Serialisable<> +class EPSRNamedTargetWeights : public Serialisable { public: EPSRNamedTargetWeights() = default; @@ -38,7 +38,7 @@ class EPSRNamedTargetWeights : public Serialisable<> */ public: // Express as a serialisable value - void serialise(std::string tag, SerialisedValue &target) const; + void serialise(std::string tag, SerialisedValue &target) const override; // Read values from a serialisable value void deserialise(const SerialisedValue &node) override; }; diff --git a/src/nodes/md.cpp b/src/nodes/md.cpp index 11356fc439..f279265a29 100644 --- a/src/nodes/md.cpp +++ b/src/nodes/md.cpp @@ -217,13 +217,10 @@ NodeConstants::ProcessResult MDNode::process() if (!velocities_) velocities_.emplace(); auto &velocities = velocities_.value(); - auto status = GenericItem::ItemStatus::Created; - if ((status == GenericItem::ItemStatus::Created || randomVelocities_ || - velocities.size() != targetConfiguration_->nAtoms()) && - !intramolecularForcesOnly_) + if ((randomVelocities_ || velocities.size() != targetConfiguration_->nAtoms()) && !intramolecularForcesOnly_) { // Show warning message on array size mismatch - if (status != GenericItem::ItemStatus::Created && velocities.size() != targetConfiguration_->nAtoms()) + if (velocities.size() != targetConfiguration_->nAtoms()) Messenger::warn( "Size of existing velocities array doesn't match the current configuration size - they will be ignored."); diff --git a/src/nodes/node.h b/src/nodes/node.h index 662256b2b9..6708a4d5ad 100644 --- a/src/nodes/node.h +++ b/src/nodes/node.h @@ -24,7 +24,7 @@ class DissolveGraph; class PairPotential; // Node Base -class Node : public Serialisable<> +class Node : public Serialisable { public: Node() {} diff --git a/src/nodes/number.h b/src/nodes/number.h index 2c6e64ba72..13bc9ff32c 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 Serialisable { public: using NumberVariant = std::variant; diff --git a/src/nodes/parameter.h b/src/nodes/parameter.h index 805a118ce3..c50b71b7ea 100644 --- a/src/nodes/parameter.h +++ b/src/nodes/parameter.h @@ -39,7 +39,7 @@ struct ParameterLink }; // Base type for all parameter templates to inherit from -class ParameterBase : public Serialisable<> +class ParameterBase : public Serialisable { public: ParameterBase(Node *parent, std::string_view name, std::string_view description, std::type_index storedDataType); diff --git a/src/nodes/serialisableData.h b/src/nodes/serialisableData.h index 06ee6594ef..b61b2e3c81 100644 --- a/src/nodes/serialisableData.h +++ b/src/nodes/serialisableData.h @@ -41,25 +41,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, typename DataClass::value_type::value_type>) - : SerialisableData(key), data_(targetData), - dataSerialiser_( - [&]() - { - return Serialisable::fromVector(data_.value(), - [&](const auto &item) - { - SerialisedValue outer; - item.serialise("inner", outer); - return outer["inner"]; - }); - }), + std::is_base_of_v) + : SerialisableData(key), data_(targetData), dataSerialiser_( + [&]() + { + return Serialisable::fromVector(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); }); + Serialisable::toVector(value, [&](const auto &node) { data_->emplace_back().deserialise(node); }); }), dataChecker_([&]() { return targetData.has_value() && !targetData.value().empty(); }), dataResolver_( @@ -73,7 +71,7 @@ template class SerialisableClass : public SerialisableData } // Optional Serialisable SerialisableClass(std::string_view key, DataClass &targetData) - requires(is_optional && std::is_base_of_v, typename DataClass::value_type>) + requires(is_optional && std::is_base_of_v) : SerialisableData(key), data_(targetData), dataSerialiser_([&]() { return data_.value().into_toml(); }), dataDeserialiser_( [&](const SerialisedValue &value) @@ -92,24 +90,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, typename DataClass::value_type>) - : SerialisableData(key), data_(targetData), - dataSerialiser_( - [&]() - { - return Serialisable::fromVector(data_, - [&](const auto &item) - { - SerialisedValue outer; - item.serialise("inner", outer); - return outer["inner"]; - }); - }), + requires(is_instance_of_v && std::is_base_of_v) + : SerialisableData(key), data_(targetData), dataSerialiser_( + [&]() + { + return Serialisable::fromVector(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); }); + Serialisable::toVector(value, [&](const auto &node) { data_.emplace_back().deserialise(node); }); }), dataChecker_([&]() { return !targetData.empty(); }), dataResolver_( @@ -143,7 +140,7 @@ template class SerialisableClass : public SerialisableData } // Serialisable SerialisableClass(std::string_view key, DataClass &value) - requires(std::is_base_of_v, DataClass>) + requires(std::is_base_of_v) : SerialisableData(key), data_(value), dataResolver_( [&](const std::map &reachableSpecies) { diff --git a/src/templates/doubleKeyedMap.h b/src/templates/doubleKeyedMap.h index 644cd78fba..b543408135 100644 --- a/src/templates/doubleKeyedMap.h +++ b/src/templates/doubleKeyedMap.h @@ -17,7 +17,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 Serialisable { public: DoubleKeyedMap(bool mirrored = false) : mirroredAreEquivalent_(mirrored) {} @@ -171,7 +171,7 @@ template class DoubleKeyedMap : public Serialisable<> target[tag] = result; }; // Read values from a serialisable value - void deserialise(const SerialisedValue &node) + void deserialise(const SerialisedValue &node) override { data_.clear(); diff --git a/src/templates/keyedVector.h b/src/templates/keyedVector.h index 8dd8c9a8fc..4f8fd37d21 100644 --- a/src/templates/keyedVector.h +++ b/src/templates/keyedVector.h @@ -3,8 +3,10 @@ #pragma once +#include #include #include +#include #include // Keyed Vector diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9a8e5bcf36..18637cc563 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -71,7 +71,6 @@ if(GUI) endif(GUI) add_subdirectory(intramolecular) add_subdirectory(io) -add_subdirectory(keywords) add_subdirectory(generator) add_subdirectory(math) add_subdirectory(nodes) diff --git a/tests/classes/CMakeLists.txt b/tests/classes/CMakeLists.txt index 4981734b73..20663c3e1d 100644 --- a/tests/classes/CMakeLists.txt +++ b/tests/classes/CMakeLists.txt @@ -8,7 +8,6 @@ dissolve_add_test(SRC elements.cpp) dissolve_add_test(SRC empiricalFormula.cpp) dissolve_add_test(SRC enumOptions.cpp) dissolve_add_test(SRC flags.cpp) -dissolve_add_test(SRC genericList.cpp) dissolve_add_test(SRC history.cpp) dissolve_add_test(SRC interactionPotential.cpp) dissolve_add_test(SRC neutronWeights.cpp) diff --git a/tests/classes/genericList.cpp b/tests/classes/genericList.cpp deleted file mode 100644 index 0a5dc633b7..0000000000 --- a/tests/classes/genericList.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "items/list.h" -#include "math/data1D.h" -#include -#include -#include - -namespace UnitTest -{ - -TEST(GenericListTest, GenericList) -{ - GenericList list; - - // POD set / get - const auto d = 1.23456; - list.realise("DOUBLE") = d; - EXPECT_DOUBLE_EQ(d, list.value("DOUBLE")); - EXPECT_DOUBLE_EQ(d, list.retrieve("DOUBLE")); - - // Class set / get - Data1D testData; - for (auto n = 0; n < 100; ++n) - testData.addPoint(n, rand() * 0.1); - list.realise("XY") = testData; - auto xy1 = list.value("XY"); - for (auto &&[a, b] : zip(xy1.values(), testData.values())) - EXPECT_DOUBLE_EQ(a, b); - list.retrieve("XY") += xy1; - auto xy2 = list.value("XY"); - for (auto &&[a, b] : zip(xy2.values(), testData.values())) - EXPECT_DOUBLE_EQ(a, 2.0 * b); - - // Missing item - EXPECT_ANY_THROW(list.value("INT")); - EXPECT_ANY_THROW(list.retrieve("INT")); - - // Bad cast - EXPECT_ANY_THROW(list.value("DOUBLE")); - EXPECT_ANY_THROW(list.retrieve>("DOUBLE")); - - // Bad realise - list.realise("INT") = 99; - EXPECT_ANY_THROW(list.realise("INT") = "99"); -} - -} // namespace UnitTest diff --git a/tests/keywords/CMakeLists.txt b/tests/keywords/CMakeLists.txt deleted file mode 100644 index 9273840044..0000000000 --- a/tests/keywords/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -dissolve_add_test(SRC double.cpp) -dissolve_add_test(SRC integer.cpp) -dissolve_add_test(SRC optionalDouble.cpp) -dissolve_add_test(SRC optionalInteger.cpp) -dissolve_add_test(SRC range.cpp) diff --git a/tests/keywords/double.cpp b/tests/keywords/double.cpp deleted file mode 100644 index de08a478c3..0000000000 --- a/tests/keywords/double.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/double.h" -#include - -namespace UnitTest -{ -TEST(DoubleKeywordTest, Basic) -{ - // Unlimited value - double value_{5.0}; - DoubleKeyword keyword(value_); - - // Check initial value - EXPECT_NEAR(keyword.data(), 5.0, 1.0e-8); - - // Set an actual value - EXPECT_TRUE(keyword.setData(10.0)); - EXPECT_NEAR(value_, 10.0, 1.0e-8); - - // And another - EXPECT_TRUE(keyword.setData(-123.0)); - EXPECT_NEAR(value_, -123.0, 1.0e-8); -} - -TEST(DoubleKeywordTest, Clamped) -{ - // Minimum at 0.0, maximum at 100.0 - double value_{5.0}; - DoubleKeyword keyword(value_, 0.0, 100.0); - - // Set an acceptable value within the limits - EXPECT_TRUE(keyword.setData(40.0)); - EXPECT_NEAR(value_, 40.0, 1.0e-8); - - // Set to the allowed limits - EXPECT_TRUE(keyword.setData(0.0)); - EXPECT_NEAR(value_, 0.0, 1.0e-8); - EXPECT_TRUE(keyword.setData(100.0)); - EXPECT_NEAR(value_, 100.0, 1.0e-8); - - // Try to set outside the allowed limits - value_ = 50.0; - EXPECT_FALSE(keyword.setData(-1.0)); - EXPECT_NEAR(value_, 50.0, 1.0e-8); - EXPECT_FALSE(keyword.setData(101.0)); - EXPECT_NEAR(value_, 50.0, 1.0e-8); -} - -} // namespace UnitTest diff --git a/tests/keywords/integer.cpp b/tests/keywords/integer.cpp deleted file mode 100644 index cff8d9bc4f..0000000000 --- a/tests/keywords/integer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/integer.h" -#include - -namespace UnitTest -{ -TEST(IntegerKeywordTest, Basic) -{ - // Unlimited value - int value_{5}; - IntegerKeyword keyword(value_); - - // Check initial value - EXPECT_EQ(keyword.data(), 5); - - // Set an actual value - EXPECT_TRUE(keyword.setData(10)); - EXPECT_EQ(value_, 10); - - // And another - EXPECT_TRUE(keyword.setData(-123)); - EXPECT_EQ(value_, -123); -} - -TEST(IntegerKeywordTest, Clamped) -{ - // Minimum at 0.0, maximum at 100.0 - int value_{5}; - IntegerKeyword keyword(value_, 0, 100); - - // Set an acceptable value within the limits - EXPECT_TRUE(keyword.setData(40)); - EXPECT_EQ(value_, 40); - - // Set to the allowed limits - EXPECT_TRUE(keyword.setData(0)); - EXPECT_EQ(value_, 0); - EXPECT_TRUE(keyword.setData(100)); - EXPECT_EQ(value_, 100); - - // Try to set outside the allowed limits - value_ = 50.0; - EXPECT_FALSE(keyword.setData(-1)); - EXPECT_EQ(value_, 50); - EXPECT_FALSE(keyword.setData(101)); - EXPECT_EQ(value_, 50); -} - -} // namespace UnitTest diff --git a/tests/keywords/optionalDouble.cpp b/tests/keywords/optionalDouble.cpp deleted file mode 100644 index 0b94703402..0000000000 --- a/tests/keywords/optionalDouble.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/optionalDouble.h" -#include - -namespace UnitTest -{ -TEST(OptionalDoubleTest, Standard) -{ - // Minimum at zero, no maximum - std::optional value_; - OptionalDoubleKeyword keyword(value_, 0.0, std::nullopt, 0.5, "Null Text"); - - // Null value_ to start with - EXPECT_TRUE(!value_); - // Set ot an actual value - EXPECT_TRUE(keyword.setData(1.0)); - EXPECT_TRUE(value_); - EXPECT_NEAR(value_.value(), 1.0, 1.0e-8); - // Set back to the value indicating null - EXPECT_TRUE(keyword.setData(0.0)); - EXPECT_TRUE(!value_); - // Set below the minimum value indicating null - EXPECT_TRUE(keyword.setData(-100.0)); - EXPECT_TRUE(!value_); -} - -TEST(OptionalDoubleTest, Clamped) -{ - // Minimum at 10.0, maximum at 100.0 - std::optional value_; - OptionalDoubleKeyword keyword(value_, 10.0, 100.0, 1.0, "Null Text"); - - // Null value_ to start with - EXPECT_TRUE(!value_); - // Set the value representing null - EXPECT_TRUE(keyword.setData(10.0)); - EXPECT_TRUE(!value_); - // Set ot an actual value - EXPECT_TRUE(keyword.setData(50.0)); - EXPECT_TRUE(value_); - EXPECT_NEAR(value_.value(), 50.0, 1.0e-8); - // Set the maximum value - EXPECT_TRUE(keyword.setData(100.0)); - EXPECT_TRUE(value_); - EXPECT_NEAR(value_.value(), 100.0, 1.0e-8); - // Set above the maximum value (fail) - EXPECT_FALSE(keyword.setData(105.0)); - EXPECT_TRUE(value_); - EXPECT_NEAR(value_.value(), 100.0, 1.0e-8); - // Set below the minimum value indicating null - EXPECT_TRUE(keyword.setData(-100.0)); - EXPECT_TRUE(!value_); -} - -} // namespace UnitTest diff --git a/tests/keywords/optionalInteger.cpp b/tests/keywords/optionalInteger.cpp deleted file mode 100644 index 882a13ba4c..0000000000 --- a/tests/keywords/optionalInteger.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/optionalInt.h" -#include - -namespace UnitTest -{ -TEST(OptionalIntegerTest, Standard) -{ - // Minimum at zero, no maximum - std::optional value_; - OptionalIntegerKeyword keyword(value_, 0, std::nullopt, 1, "Null Text"); - - // Null value_ to start with - EXPECT_TRUE(!value_); - // Set an actual value - EXPECT_TRUE(keyword.setData(1)); - EXPECT_TRUE(value_); - EXPECT_EQ(value_.value(), 1); - // Set back to the value indicating null - EXPECT_TRUE(keyword.setData(0)); - EXPECT_TRUE(!value_); - // Set below the minimum value indicating null - EXPECT_TRUE(keyword.setData(-100)); - EXPECT_TRUE(!value_); -} - -TEST(OptionalIntegerTest, Clamped) -{ - // Minimum at 10, maximum at 100 - std::optional value_; - OptionalIntegerKeyword keyword(value_, 10, 100, 1, "Null Text"); - - // Null value_ to start with - EXPECT_TRUE(!value_); - // Set the value representing null - EXPECT_TRUE(keyword.setData(10)); - EXPECT_TRUE(!value_); - // Set an actual value - EXPECT_TRUE(keyword.setData(50)); - EXPECT_TRUE(value_); - EXPECT_EQ(value_.value(), 50); - // Set the maximum value - EXPECT_TRUE(keyword.setData(100)); - EXPECT_TRUE(value_); - EXPECT_EQ(value_.value(), 100); - // Set above the maximum value (fail) - EXPECT_FALSE(keyword.setData(105)); - EXPECT_TRUE(value_); - EXPECT_EQ(value_.value(), 100); - // Set below the minimum value indicating null - EXPECT_TRUE(keyword.setData(-100)); - EXPECT_TRUE(!value_); -} - -} // namespace UnitTest diff --git a/tests/keywords/range.cpp b/tests/keywords/range.cpp deleted file mode 100644 index bf5a6d75a8..0000000000 --- a/tests/keywords/range.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright (c) 2026 Team Dissolve and contributors - -#include "keywords/range.h" -#include - -namespace UnitTest -{ -TEST(RangeKeywordTest, Basic) -{ - // Unlimited range - Range value_; - RangeKeyword keyword(value_); - - // Set an actual value - EXPECT_TRUE(keyword.setData(1.5, 4.5)); - EXPECT_NEAR(value_.minimum(), 1.5, 1.0e-8); - EXPECT_NEAR(value_.maximum(), 4.5, 1.0e-8); - - // Set the same numbers but with max > min - EXPECT_TRUE(keyword.setData(4.5, 1.5)); - EXPECT_NEAR(value_.minimum(), 1.5, 1.0e-8); - EXPECT_NEAR(value_.maximum(), 4.5, 1.0e-8); -} - -TEST(RangeKeywordTest, Clamped) -{ - // Minimum at 0.0, maximum at 100.0 - Range value_; - RangeKeyword keyword(value_, 0.0, 100.0); - - // Set an acceptable range within the limits - EXPECT_TRUE(keyword.setData(40.0, 60.0)); - EXPECT_NEAR(value_.minimum(), 40.0, 1.0e-8); - EXPECT_NEAR(value_.maximum(), 60.0, 1.0e-8); - - // Set range to the allowed limits - EXPECT_TRUE(keyword.setData(0.0, 100.0)); - EXPECT_NEAR(value_.minimum(), 0.0, 1.0e-8); - EXPECT_NEAR(value_.maximum(), 100.0, 1.0e-8); - - // Try to set outside the allowed limits - EXPECT_FALSE(keyword.setMinimum(-1.0)); - EXPECT_NEAR(value_.minimum(), 0.0, 1.0e-8); - EXPECT_FALSE(keyword.setMaximum(101.0)); - EXPECT_NEAR(value_.maximum(), 100.0, 1.0e-8); - EXPECT_FALSE(keyword.setData(-1.0, 50.0)); - EXPECT_NEAR(value_.minimum(), 0.0, 1.0e-8); - EXPECT_NEAR(value_.maximum(), 100.0, 1.0e-8); - EXPECT_FALSE(keyword.setData(0.0, 101.0)); - EXPECT_NEAR(value_.minimum(), 0.0, 1.0e-8); - EXPECT_NEAR(value_.maximum(), 100.0, 1.0e-8); -} - -} // namespace UnitTest diff --git a/tests/testData.h b/tests/testData.h index 23419f1d2e..447f58e191 100644 --- a/tests/testData.h +++ b/tests/testData.h @@ -4,6 +4,7 @@ #pragma once #include "classes/coreData.h" +#include "classes/partialSet.h" #include "classes/species.h" #include "kernels/energy.h" #include "kernels/force.h" @@ -135,14 +136,6 @@ class DissolveSystemTest { return checkDouble(quantity, A.value(), B, threshold); } - // Test sampled double - [[nodiscard]] bool checkSampledDouble(std::string_view quantity, std::string_view tag, double B, double threshold) - { - // Locate the target reference data - const auto &A = dissolve_.processingModuleData().retrieve(tag); - - return checkDouble(quantity, A.value(), B, threshold); - } // Test Data1D [[nodiscard]] static bool checkData1D(const Data1D &dataA, std::string_view nameA, const Data1D &dataB, std::string_view nameB, double tolerance = 5.0e-3, @@ -194,24 +187,6 @@ class DissolveSystemTest return !notOK; } - // Test SampledVector data - [[nodiscard]] bool checkSampledVector(std::string_view tag, const std::vector &referenceData, - double tolerance = 5.0e-3, - Error::ErrorType errorType = Error::ErrorType::EuclideanError) - { - // Locate the target reference data - auto optData = dissolve_.processingModuleData().search(tag); - if (!optData) - throw(std::runtime_error(std::format("No data with tag '{}' exists.\n", tag))); - const auto &data = optData->get(); - - // Generate the error estimate and compare against the threshold value - auto error = Error::error(errorType, data.values(), referenceData).error; - auto notOK = std::isnan(error) || error > tolerance; - Messenger::print("Target data '{}' has error of {:7.3e} with reference data and is {} (threshold is {:6.3e})\n\n", tag, - error, notOK ? "NOT OK" : "OK", tolerance); - return !notOK; - } // Test Vec3 data static void checkVec3(const Vector3 &A, const Vector3 &B, double tolerance = 1.0e-6) {