ENH: add clear/append method to Enum and std::ostream output

- allows use of Enum in more situations where a tiny Map/HashTable
  replacement is desirable. The new methods can be combined with
  null constructed for to have a simple low-weight caching system
  for words/integers instead of fitting in a HashTable.
This commit is contained in:
Mark Olesen
2019-11-25 18:15:31 +01:00
committed by Andrew Heather
parent daac96f165
commit 6dd3cd0e51
4 changed files with 148 additions and 6 deletions

View File

@ -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
(

View File

@ -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);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -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;
}
// ************************************************************************* //