diff --git a/applications/test/Enum/Test-Enum.C b/applications/test/Enum/Test-Enum.C index 064b77d4634534976ac61a5b185491255e2d97ba..f6f4d507f920ac5527c083e2e64ced6e8f1fbf54 100644 --- a/applications/test/Enum/Test-Enum.C +++ b/applications/test/Enum/Test-Enum.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018-2019 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -73,7 +73,7 @@ const Foam::Enum<int> otherNames1 // Can use for integers as well, but not scalar etc. -const Foam::Enum<int> otherNames2 +Foam::Enum<int> otherNames2 ({ { 0, "a" }, { 2, "b" }, @@ -110,6 +110,34 @@ int main(int argc, char *argv[]) << " values: " << flatOutput(otherNames2.values()) << nl << nl; + otherNames2.append + ({ + { 15, "fifteen"}, + { 16, "sixteen"} + }); + + Info<<"Other Enum (appended)" << nl + << " names: " << otherNames2 << nl + << " values: " << flatOutput(otherNames2.values()) + << nl << nl; + + std::cout + <<"stdout: "<< otherNames2 + << nl << nl; + + + otherNames2.clear(); + otherNames2.append + ({ + { 1, "one"}, + { 2, "two"} + }); + + Info<<"After clear and append:" << nl + << otherNames2 << nl + << otherNames2.values() << nl + << nl; + dictionary testDict; testDict.add("lookup1", "c"); diff --git a/src/OpenFOAM/primitives/enums/Enum.C b/src/OpenFOAM/primitives/enums/Enum.C index 591ea9f6226e0d324cf13acb8a01356269f67990..8c8eabca77b7bc82a576df5778be31e207a8493e 100644 --- a/src/OpenFOAM/primitives/enums/Enum.C +++ b/src/OpenFOAM/primitives/enums/Enum.C @@ -44,7 +44,6 @@ Foam::Enum<EnumType>::Enum { keys_[i] = pair.second; vals_[i] = int(pair.first); - ++i; } } @@ -63,6 +62,26 @@ Foam::List<Foam::word> Foam::Enum<EnumType>::sortedToc() const } +template<class EnumType> +void Foam::Enum<EnumType>::append +( + std::initializer_list<std::pair<EnumType, const char*>> list +) +{ + label i = size(); + + keys_.resize(i + list.size()); + vals_.resize(i + list.size()); + + for (const auto& pair : list) + { + keys_[i] = pair.second; + vals_[i] = int(pair.first); + ++i; + } +} + + template<class EnumType> EnumType Foam::Enum<EnumType>::get(const word& enumName) const { @@ -115,6 +134,35 @@ EnumType Foam::Enum<EnumType>::read(Istream& is) const } +template<class EnumType> +bool Foam::Enum<EnumType>::read +( + Istream& is, + EnumType& e, + const bool mandatory +) const +{ + const word enumName(is); + + const label idx = find(enumName); + + if (idx >= 0) + { + e = EnumType(vals_[idx]); + return true; + } + + if (mandatory) + { + FatalIOErrorInFunction(is) + << enumName << " is not in enumeration: " << *this << nl + << exit(FatalIOError); + } + + return false; +} + + template<class EnumType> EnumType Foam::Enum<EnumType>::get ( diff --git a/src/OpenFOAM/primitives/enums/Enum.H b/src/OpenFOAM/primitives/enums/Enum.H index a8c190ab3e39d81f133a8e061a0ae44b6edd5d29..7d97a89c7537af3313fa8849bea6ef981dd5996b 100644 --- a/src/OpenFOAM/primitives/enums/Enum.H +++ b/src/OpenFOAM/primitives/enums/Enum.H @@ -28,7 +28,8 @@ Class Description Enum is a wrapper around a list of names/values that represent particular - enumeration values. All dictionary searches use a literal (not regex). + enumeration (or int) values. + All dictionary searches use a literal (not regex). SourceFiles Enum.C @@ -41,6 +42,7 @@ SourceFiles #include "wordList.H" #include <initializer_list> +#include <ostream> #include <utility> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -73,7 +75,7 @@ public: //- The type of enumeration represented by the Enum typedef EnumType value_type; - // Normally only enum, but be generous and allow integrals as well + // Allow enums and integrals (should fit within an int) static_assert ( std::is_enum<EnumType>::value || std::is_integral<EnumType>::value, @@ -83,6 +85,9 @@ public: // Constructors + //- Construct null (empty list) + Enum() = default; + //- Construct from a values/names list. // Duplicate values are permitted (eg, for aliases). // Duplicate names are permitted, but won't make much sense. @@ -112,6 +117,19 @@ public: inline const List<int>& values() const; + // Modify + + //- Clear all entries + inline void clear(); + + //- Append value/key pairs to the lists of known enumerations + // Does not check for duplicate entries + void append + ( + std::initializer_list<std::pair<EnumType, const char*>> list + ); + + // Query //- Find the index of the given name. @@ -197,6 +215,15 @@ public: //- Read a word from Istream and return the corresponding enumeration EnumType read(Istream& is) const; + //- Read a word from Istream, lookup named enumeration. + // \return true on success. Fatal if mandatory and not found. + bool read + ( + Istream& is, + EnumType& val, + const bool mandatory = true + ) const; + //- Write the name representation of the enumeration to an Ostream // A noop if the enumeration wasn't found. inline void write(const EnumType e, Ostream& os) const; @@ -266,6 +293,10 @@ public: template<class EnumType> inline Ostream& operator<<(Ostream& os, const Enum<EnumType>& list); +//- Write enumeration names, without line-breaks (ie, FlatOutput) +template<class EnumType> +inline std::ostream& operator<<(std::ostream& os, const Enum<EnumType>& list); + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/enums/EnumI.H b/src/OpenFOAM/primitives/enums/EnumI.H index 8a637cd0168754900de8757a28d99d56b9a9f3ed..0b990bed67cdd05d9cd6a0845890d159ea315f5a 100644 --- a/src/OpenFOAM/primitives/enums/EnumI.H +++ b/src/OpenFOAM/primitives/enums/EnumI.H @@ -55,6 +55,14 @@ inline const Foam::List<int>& Foam::Enum<EnumType>::values() const } +template<class EnumType> +inline void Foam::Enum<EnumType>::clear() +{ + keys_.clear(); + vals_.clear(); +} + + template<class EnumType> inline Foam::label Foam::Enum<EnumType>::find(const word& enumName) const { @@ -173,10 +181,37 @@ inline EnumType Foam::Enum<EnumType>::operator() // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // template<class EnumType> -inline Foam::Ostream& Foam::operator<<(Ostream& os, const Enum<EnumType>& list) +inline Foam::Ostream& Foam::operator<< +( + Ostream& os, + const Enum<EnumType>& list +) { return list.names().writeList(os, 0); } +template<class EnumType> +inline std::ostream& Foam::operator<< +( + std::ostream& os, + const Enum<EnumType>& list +) +{ + os << '('; + + unsigned i = 0; + + for (const word& k : list.names()) + { + if (i++) os << ' '; + os << k; + } + + os << ')'; + + return os; +} + + // ************************************************************************* //