Commit 26fef427 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: provide lookupOrDefault for NamedEnum - makes for easier use.

parent b8300759
......@@ -66,6 +66,9 @@ int main(int argc, char *argv[])
const List<namedEnumTest::option> options
= namedEnumTest::namedEnum.enums();
dictionary testDict;
testDict.add("lookup1", "c");
Info<< "enums: " << options << nl;
Info<< "loop over enums (as list):" << nl;
......@@ -88,6 +91,30 @@ int main(int argc, char *argv[])
<< namedEnumTest::namedEnum["a"] << nl
<< namedEnumTest::namedEnum[namedEnumTest::a] << nl;
Info<< "--- test dictionary lookup ---" << endl;
{
Info<< "dict: " << testDict << endl;
namedEnumTest::option gotOpt =
namedEnumTest::namedEnum.lookupOrDefault
(
"test",
testDict,
namedEnumTest::option::a
);
Info<< "got: " << gotOpt << endl;
gotOpt = namedEnumTest::namedEnum.lookupOrDefault
(
"lookup1",
testDict,
namedEnumTest::option::a
);
Info<< "got: " << gotOpt << endl;
}
Info<< "--- test read construction ---" << endl;
namedEnumTest::option dummy(namedEnumTest::namedEnum.read(Sin));
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -24,33 +24,60 @@ License
\*---------------------------------------------------------------------------*/
#include "NamedEnum.H"
#include "dictionary.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Enum, int nEnum>
template<class StringType>
Foam::List<StringType> Foam::NamedEnum<Enum, nEnum>::getNamesList()
{
List<StringType> lst(nEnum);
label count = 0;
for (int enumi=0; enumi < nEnum; ++enumi)
{
if (names[enumi] && names[enumi][0])
{
lst[count++] = names[enumi];
}
}
lst.setSize(count);
return lst;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Enum, int nEnum>
Foam::NamedEnum<Enum, nEnum>::NamedEnum()
:
HashTable<int>(2*nEnum)
table_type(2*nEnum)
{
for (int enumI = 0; enumI < nEnum; ++enumI)
for (int enumi=0; enumi < nEnum; ++enumi)
{
if (!names[enumI] || names[enumI][0] == '\0')
if (names[enumi] && names[enumi][0])
{
insert(names[enumi], enumi);
}
else
{
stringList goodNames(enumI);
// Bad name - generate error message
stringList goodNames(enumi);
for (int i = 0; i < enumI; ++i)
for (int i = 0; i < enumi; ++i)
{
goodNames[i] = names[i];
}
FatalErrorInFunction
<< "Illegal enumeration name at position " << enumI << endl
<< "after entries " << goodNames << ".\n"
<< "Illegal enumeration name at position " << enumi << nl
<< "after entries " << goodNames << nl
<< "Possibly your NamedEnum<Enum, nEnum>::names array"
<< " is not of size " << nEnum << endl
<< abort(FatalError);
}
insert(names[enumI], enumI);
}
}
......@@ -60,14 +87,13 @@ Foam::NamedEnum<Enum, nEnum>::NamedEnum()
template<class Enum, int nEnum>
Enum Foam::NamedEnum<Enum, nEnum>::read(Istream& is) const
{
const word name(is);
HashTable<int>::const_iterator iter = find(name);
const word enumName(is);
table_type::const_iterator iter = find(enumName);
if (!iter.found())
{
FatalIOErrorInFunction(is)
<< name << " is not in enumeration: "
<< enumName << " is not in enumeration: "
<< sortedToc() << exit(FatalIOError);
}
......@@ -78,45 +104,47 @@ Enum Foam::NamedEnum<Enum, nEnum>::read(Istream& is) const
template<class Enum, int nEnum>
void Foam::NamedEnum<Enum, nEnum>::write(const Enum e, Ostream& os) const
{
os << operator[](e);
os << names[int(e)];
}
template<class Enum, int nEnum>
Foam::stringList Foam::NamedEnum<Enum, nEnum>::strings()
Enum Foam::NamedEnum<Enum, nEnum>::lookup
(
const word& key,
const dictionary& dict
) const
{
stringList lst(nEnum);
const word enumName(dict.lookup(key));
table_type::const_iterator iter = find(enumName);
label nElem = 0;
for (int enumI = 0; enumI < nEnum; ++enumI)
if (!iter.found())
{
if (names[enumI] && names[enumI][0])
{
lst[nElem++] = names[enumI];
}
FatalIOErrorInFunction(dict)
<< enumName << " is not in enumeration: "
<< sortedToc() << exit(FatalIOError);
}
lst.setSize(nElem);
return lst;
return Enum(iter.object());
}
template<class Enum, int nEnum>
Foam::wordList Foam::NamedEnum<Enum, nEnum>::words()
Enum Foam::NamedEnum<Enum, nEnum>::lookupOrDefault
(
const word& key,
const dictionary& dict,
const enum_type deflt
) const
{
wordList lst(nEnum);
label nElem = 0;
for (int enumI = 0; enumI < nEnum; ++enumI)
if (dict.found(key))
{
if (names[enumI] && names[enumI][0])
{
lst[nElem++] = names[enumI];
}
return lookup(key, dict);
}
else
{
return deflt;
}
lst.setSize(nElem);
return lst;
}
......@@ -125,18 +153,32 @@ Foam::List<Enum> Foam::NamedEnum<Enum, nEnum>::enums()
{
List<Enum> lst(nEnum);
label nElem = 0;
for (int enumI = 0; enumI < nEnum; ++enumI)
label count = 0;
for (int enumi = 0; enumi < nEnum; ++enumi)
{
if (names[enumI] && names[enumI][0])
if (names[enumi] && names[enumi][0])
{
lst[nElem++] = Enum(enumI);
lst[count++] = Enum(enumi);
}
}
lst.setSize(nElem);
lst.setSize(count);
return lst;
}
template<class Enum, int nEnum>
Foam::stringList Foam::NamedEnum<Enum, nEnum>::strings()
{
return getNamesList<string>();
}
template<class Enum, int nEnum>
Foam::wordList Foam::NamedEnum<Enum, nEnum>::words()
{
return getNamesList<word>();
}
// ************************************************************************* //
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -25,7 +25,9 @@ Class
Foam::NamedEnum
Description
Initialise the NamedEnum HashTable from the static list of names.
A NamedEnum is a wrapper around a static list of names that represent
a particular enumeration. Internally it uses a HashTable for quicker
lookups.
SourceFiles
NamedEnum.C
......@@ -44,6 +46,7 @@ SourceFiles
namespace Foam
{
class dictionary;
// Forward declaration
template<class Enum, int> class NamedEnum;
......@@ -57,11 +60,19 @@ class NamedEnum
:
public HashTable<int>
{
//- nEnum must be positive (non-zero)
//- The nEnum must be positive (non-zero)
static_assert(nEnum > 0, "nEnum must be positive (non-zero)");
//- The type of HashTable used for the lookup.
typedef HashTable<int> table_type;
// Private Member Functions
//- The names as a list of strings
template<class StringType>
static List<StringType> getNamesList();
//- Disallow default bitwise copy construct
NamedEnum(const NamedEnum&) = delete;
......@@ -71,6 +82,10 @@ class NamedEnum
public:
//- The type of enumeration wrapped by NamedEnum
typedef Enum enum_type;
// Static data members
//- The set of names corresponding to the enumeration Enum
......@@ -87,10 +102,33 @@ public:
//- Read a word from Istream and return the corresponding
// enumeration element
Enum read(Istream& is) const;
enum_type read(Istream& is) const;
//- Write the name representation of the enumeration to an Ostream
void write(const Enum e, Ostream& os) const;
void write(const enum_type e, Ostream& os) const;
//- Lookup the key in the dictionary and return the corresponding
// enumeration element based on its name.
// Fatal if anything is incorrect.
enum_type lookup
(
const word& key,
const dictionary& dict
) const;
//- Find the key in the dictionary and return the corresponding
// enumeration element based on its name.
// Return the default value if the key was not found in the dictionary.
// Fatal if enumerated name was incorrect.
enum_type lookupOrDefault
(
const word& key,
const dictionary& dict,
const enum_type deflt
) const;
//- List of enumerations
static List<enum_type> enums();
//- The set of names as a list of strings
static stringList strings();
......@@ -98,26 +136,23 @@ public:
//- The set of names as a list of words
static wordList words();
//- List of enumerations
static List<Enum> enums();
// Member Operators
//- Return the enumeration element corresponding to the given name
const Enum operator[](const char* name) const
inline const enum_type operator[](const char* name) const
{
return Enum(HashTable<int>::operator[](name));
return enum_type(table_type::operator[](name));
}
//- Return the enumeration element corresponding to the given name
const Enum operator[](const word& name) const
inline const enum_type operator[](const word& name) const
{
return Enum(HashTable<int>::operator[](name));
return enum_type(table_type::operator[](name));
}
//- Return the name of the given enumeration element
const char* operator[](const Enum e) const
inline const char* operator[](const enum_type e) const
{
return names[int(e)];
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment