return defaultEnumValue;
}
- // Check if option string can be mapped to a valid enum value
+ // Check if option string can be mapped to a valid enum value.
+ //
+ // Note that this cannot be replaced with
+ // StringToEnumValueConverter until all instantiations of this
+ // function have a matching enumValueToString, and all of the
+ // latter are in the same namespace. Currently some of those
+ // function declarations are in gmx namespace and some are not.
const auto* optionString = (*inp)[ii].value_.c_str();
for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
{
void PreprocessingAtomTypes::printTypes(FILE* out)
{
- fprintf(out, "[ %s ]\n", dir2str(Directive::d_atomtypes));
+ fprintf(out, "[ %s ]\n", enumValueToString(Directive::d_atomtypes));
fprintf(out,
"; %6s %8s %8s %8s %12s %12s\n",
"type",
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
* Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static void print_top_system(FILE* out, const char* title)
{
- fprintf(out, "[ %s ]\n", dir2str(Directive::d_system));
+ fprintf(out, "[ %s ]\n", enumValueToString(Directive::d_system));
fprintf(out, "; Name\n");
fprintf(out, "%s\n\n", title[0] ? title : "Protein");
}
if (!mols.empty())
{
- fprintf(out, "[ %s ]\n", dir2str(Directive::d_molecules));
+ fprintf(out, "[ %s ]\n", enumValueToString(Directive::d_molecules));
fprintf(out, "; %-15s %5s\n", "Compound", "#mols");
for (const auto& mol : mols)
{
{
if (at && atype && cgnr)
{
- fprintf(out, "[ %s ]\n", dir2str(Directive::d_moleculetype));
+ fprintf(out, "[ %s ]\n", enumValueToString(Directive::d_moleculetype));
fprintf(out, "; %-15s %5s\n", "Name", "nrexcl");
fprintf(out, "%-15s %5d\n\n", molname ? molname : "Protein", nrexcl);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
// If the enumeration is extended, but there is no matching
// name, then at least one element will be value initialized,
// ie. to nullptr, which this test will catch.
- auto name = dir2str(d);
+ auto name = enumValueToString(d);
EXPECT_NE(name, nullptr);
}
}
#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringtoenumvalueconverter.h"
-/* Must correspond to the Directive enum in grompp_impl.h */
-static gmx::EnumerationArray<Directive, const char*> directive_names = {
- { "defaults",
- "atomtypes",
- "bondtypes",
- "constrainttypes",
- "pairtypes",
- "angletypes",
- "dihedraltypes",
- "nonbond_params",
- "implicit_genborn_params",
- "implicit_surface_params",
- "cmaptypes",
- /* All the directives above can not appear after moleculetype */
- "moleculetype",
- "atoms",
- "virtual_sites1",
- "virtual_sites2",
- "virtual_sites3",
- "virtual_sites4",
- "virtual_sitesn",
- "bonds",
- "exclusions",
- "pairs",
- "pairs_nb",
- "angles",
- "dihedrals",
- "constraints",
- "settles",
- "polarization",
- "water_polarization",
- "thole_polarization",
- "system",
- "molecules",
- "position_restraints",
- "angle_restraints",
- "angle_restraints_z",
- "distance_restraints",
- "orientation_restraints",
- "dihedral_restraints",
- "cmap",
- "intermolecular_interactions",
- "maxdirs",
- "invalid",
- "none" }
-};
+const char* enumValueToString(Directive d)
+{
+ /* Must correspond to the Directive enum in topdirs.h */
+ static constexpr gmx::EnumerationArray<Directive, const char*> directiveNames = {
+ "defaults",
+ "atomtypes",
+ "bondtypes",
+ "constrainttypes",
+ "pairtypes",
+ "angletypes",
+ "dihedraltypes",
+ "nonbond_params",
+ "implicit_genborn_params",
+ "implicit_surface_params",
+ "cmaptypes",
+ /* All the directives above can not appear after moleculetype */
+ "moleculetype",
+ "atoms",
+ "virtual_sites1",
+ "virtual_sites2",
+ "virtual_sites3",
+ "virtual_sites4",
+ "virtual_sitesn",
+ "bonds",
+ "exclusions",
+ "pairs",
+ "pairs_nb",
+ "angles",
+ "dihedrals",
+ "constraints",
+ "settles",
+ "polarization",
+ "water_polarization",
+ "thole_polarization",
+ "system",
+ "molecules",
+ "position_restraints",
+ "angle_restraints",
+ "angle_restraints_z",
+ "distance_restraints",
+ "orientation_restraints",
+ "dihedral_restraints",
+ "cmap",
+ "intermolecular_interactions",
+ "maxdirs",
+ "invalid",
+ "none"
+ };
+ return directiveNames[d];
+}
int ifunc_index(Directive d, int type)
{
case Directive::d_orientation_restraints: return F_ORIRES;
case Directive::d_dihedral_restraints: return F_DIHRES;
default:
- gmx_fatal(FARGS, "invalid directive %s in ifunc_index (%s:%d)", dir2str(d), __FILE__, __LINE__);
+ gmx_fatal(FARGS, "invalid directive %s in ifunc_index (%s:%d)", enumValueToString(d), __FILE__, __LINE__);
}
}
-const char* dir2str(Directive d)
+enum class DeprecatedDirectives : int
+{
+ d_dummies1,
+ d_dummies2,
+ d_dummies3,
+ d_dummies4,
+ d_dummiesn,
+ Count
+};
+
+static const char* enumValueToString(DeprecatedDirectives d)
{
- int index = static_cast<int>(d);
- return directive_names[index];
+ static constexpr gmx::EnumerationArray<DeprecatedDirectives, const char*> directiveNames = {
+ "dummies1", "dummies2", "dummies3", "dummies4", "dummiesn"
+ };
+ return directiveNames[d];
}
Directive str2dir(char* dstr)
{
- char buf[STRLEN], *ptr;
+ static const gmx::StringToEnumValueConverter<Directive, enumValueToString, gmx::StringCompareType::CaseAndDashInsensitive> s_converter;
- /* Hack to be able to read old topologies */
- if (gmx_strncasecmp_min(dstr, "dummies", 7) == 0)
+ if (std::optional<Directive> d = s_converter.valueFrom(dstr); d.has_value())
{
- sprintf(buf, "virtual_sites%s", dstr + 7);
- ptr = buf;
- }
- else
- {
- ptr = dstr;
+ return d.value();
}
+ // Also handle deprecated directives that have modern replacements, like
+ // "dummies*" -> "virtual_sites*"
- for (auto d : gmx::EnumerationWrapper<Directive>())
+ static const gmx::StringToEnumValueConverter<DeprecatedDirectives, enumValueToString, gmx::StringCompareType::CaseAndDashInsensitive>
+ s_converterForDeprecated;
+
+ if (std::optional<DeprecatedDirectives> d = s_converterForDeprecated.valueFrom(dstr); d.has_value())
{
- if (gmx_strcasecmp_min(ptr, dir2str(static_cast<Directive>(d))) == 0)
- {
- return static_cast<Directive>(d);
- }
+ static constexpr gmx::EnumerationArray<DeprecatedDirectives, Directive> s_deprecatedDirectiveToDirective = {
+ Directive::d_vsites1, Directive::d_vsites2, Directive::d_vsites3,
+ Directive::d_vsites4, Directive::d_vsitesn,
+ };
+ return s_deprecatedDirectiveToDirective[d.value()];
}
-
return Directive::d_invalid;
}
Count
};
+const char* enumValueToString(Directive d);
+
struct DirStack
{
Directive d;
int ifunc_index(Directive d, int type);
-const char* dir2str(Directive d);
-
Directive str2dir(char* dstr);
void DS_Init(DirStack** DS);
gmx_fatal(FARGS,
"%s\nInvalid order for directive %s",
cpp_error(&handle, eCPP_SYNTAX),
- dir2str(newd));
+ enumValueToString(newd));
/* d = Directive::d_invalid; */
}
"in a part belonging to a different molecule than you intended to.\n"
"In that case move the \"%s\" section to the right molecule.",
aa[i],
- dir2str(d),
+ enumValueToString(d),
at->nr,
- dir2str(d),
- dir2str(d));
+ enumValueToString(d),
+ enumValueToString(d));
warning_error_and_exit(wi, message, FARGS);
}
for (int j = i + 1; (j < nral); j++)
"Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy");
if (aa[i] == aa[j])
{
- auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
+ auto message = gmx::formatString(
+ "Duplicate atom index (%d) in %s", aa[i], enumValueToString(d));
if (ftype == F_ANGRES)
{
/* Since the angle restraints uses 2 pairs of atoms to
"in a part belonging to a different molecule than you intended to.\n"
"In that case move the \"%s\" section to the right molecule.",
aa[i],
- dir2str(d),
+ enumValueToString(d),
at->nr,
- dir2str(d),
- dir2str(d));
+ enumValueToString(d),
+ enumValueToString(d));
warning_error_and_exit(wi, message, FARGS);
}
{
if (aa[i] == aa[j])
{
- auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
+ auto message = gmx::formatString(
+ "Duplicate atom index (%d) in %s", aa[i], enumValueToString(d));
warning_error(wi, message);
}
}
ptr += n;
if (ret == 0)
{
- auto message = gmx::formatString("Expected an atom index in section \"%s\"", dir2str(d));
+ auto message =
+ gmx::formatString("Expected an atom index in section \"%s\"", enumValueToString(d));
warning_error_and_exit(wi, message, FARGS);
}
if (nj == 0)
{
- auto message =
- gmx::formatString("Expected more than one atom index in section \"%s\"", dir2str(d));
+ auto message = gmx::formatString("Expected more than one atom index in section \"%s\"",
+ enumValueToString(d));
warning_error_and_exit(wi, message, FARGS);
}
nrfp = NRFP(ftype);
/* header */
- fprintf(out, "[ %s ]\n", dir2str(d));
+ fprintf(out, "[ %s ]\n", enumValueToString(d));
fprintf(out, "; ");
if (!bDih)
{
if (have_excl)
{
- fprintf(out, "[ %s ]\n", dir2str(Directive::d_exclusions));
+ fprintf(out, "[ %s ]\n", enumValueToString(Directive::d_exclusions));
fprintf(out, "; %4s %s\n", "i", "excluded from i");
for (i = 0; i < natoms; i++)
{
const char* as;
double qres, qtot;
- as = dir2str(Directive::d_atoms);
+ as = enumValueToString(Directive::d_atoms);
fprintf(out, "[ %s ]\n", as);
fprintf(out,
"; %4s %10s %6s %7s%6s %6s %10s %10s %6s %10s %10s\n",