ENH: consolidate allow/deny wordRes filtering

- wrap as wordRes::filter functor

- support allow/deny when loading cloud fields to a registry
This commit is contained in:
Mark Olesen
2022-02-03 16:56:51 +01:00
parent fb4fe06306
commit e806d18612
9 changed files with 171 additions and 82 deletions

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef predicates_H
#define predicates_H
#ifndef Foam_predicates_H
#define Foam_predicates_H
#include <string>
#include <type_traits>
@ -44,7 +44,6 @@ SourceFiles
namespace Foam
{
namespace predicates
{
@ -115,7 +114,6 @@ struct never : std::false_type
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace predicates
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -43,8 +43,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef scalarPredicates_H
#define scalarPredicates_H
#ifndef Foam_scalarPredicates_H
#define Foam_scalarPredicates_H
#include "scalar.H"
#include "predicates.H"

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -361,16 +361,17 @@ struct foundOp
//- Return ids for items with matching names.
// Uses a combination of allow and deny lists
//
// An empty 'allow' list accepts everything not in the 'deny' list.
// A literal match has higher priority over a regex match.
// An empty 'allow' accepts everything not in 'deny'.
// A literal 'allow' match has higher priority than any 'deny'.
// A regex 'allow' match has lower priority than any 'deny'.
//
// Eg,
// Example (when applied to a list of words),
// \verbatim
// input: ( abc apple wall wall1 wall2 )
// allow: ( abc def "wall.*" )
// deny: ( "[ab].*" wall )
// input: ( abc apple test other val val1 val2 wall wall1 wall2 )
// allow: ( abc def "t.*" other val val1 "wall.*" )
// deny: ( "[ab].*" "t.*" other "val[0-9]" wall )
//
// result: (abc wall1 wall2)
// result: (abc other val val1 wall1 wall2)
// \endverbatim
//
// \return List indices for matches
@ -379,7 +380,7 @@ labelList findMatching
(
const StringListType& input,
const wordRes& allow,
const wordRes& deny = wordRes(),
const wordRes& deny = wordRes::null(),
AccessOp aop = noOp()
);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -147,6 +147,9 @@ Foam::labelList Foam::stringListOps::findMatching
return identity(len);
}
// Use combined accept/reject filter
const wordRes::filter pred(allow, deny);
labelList indices(len);
label count = 0;
@ -154,25 +157,7 @@ Foam::labelList Foam::stringListOps::findMatching
{
const std::string& text = aop(input[i]);
bool accept = false;
if (allow.size())
{
const auto result = allow.matched(text);
accept =
(
result == wordRe::LITERAL
? true
: (result == wordRe::REGEX && !deny.match(text))
);
}
else
{
accept = !deny.match(text);
}
if (accept)
if (pred(text))
{
indices[count] = i;
++count;

View File

@ -37,8 +37,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef wordReList_H
#define wordReList_H
#ifndef Foam_wordReList_H
#define Foam_wordReList_H
#include "wordRe.H"
#include "List.H"
@ -48,7 +48,6 @@ Description
namespace Foam
{
typedef UList<wordRe> wordReUList;
typedef List<wordRe> wordReList;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,8 +35,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef wordRes_H
#define wordRes_H
#ifndef Foam_wordRes_H
#define Foam_wordRes_H
#include "wordReList.H"
@ -78,25 +78,7 @@ class wordRes
public:
// Public Classes
//- Functor wrapper for matching against a List of wordRe
struct matcher
{
const UList<wordRe>& values;
matcher(const UList<wordRe>& selectors)
:
values(selectors)
{}
//- True if text matches ANY of the entries.
// Allows use as a predicate.
inline bool operator()(const std::string& text) const;
};
// Factory Methods
// Static Data / Methods
//- Return a null wordRes - a reference to the NullObject
inline static const wordRes& null();
@ -153,6 +135,61 @@ public:
//- Identical to match(), for use as a predicate.
inline bool operator()(const std::string& text) const;
// Functors
//- Functor wrapper of a list of wordRe for matching
struct matcher
{
//- Construct with 'allow' matcher
inline matcher(const UList<wordRe>& allow);
//- Nothing defined
inline bool empty() const noexcept;
//- True if text matches ANY of the entries.
// Allows use as a predicate.
inline bool operator()(const std::string& text) const;
private:
const UList<wordRe>& allow_;
};
//- Functor wrapper of allow/deny lists of wordRe for filtering
//
// An empty 'allow' accepts everything not in 'deny'.
// A literal 'allow' match has higher priority than any 'deny'.
// A regex 'allow' match has lower priority than any 'deny'.
//
// Example (when applied to a list of words),
// \verbatim
// input: ( abc apple test other val val1 val2 wall wall1 wall2 )
// allow: ( abc def "t.*" other val val1 "wall.*" )
// deny: ( "[ab].*" "t.*" other "val[0-9]" wall )
//
// result: (abc other val val1 wall1 wall2)
// \endverbatim
struct filter
{
//- Construct with 'allow' and 'deny' matchers
inline filter
(
const UList<wordRe>& allow,
const UList<wordRe>& deny
);
//- Nothing defined
inline bool empty() const noexcept;
//- True if matched but not blocked
inline bool operator()(const std::string& text) const;
private:
const UList<wordRe>& allow_;
const UList<wordRe>& deny_;
};
};

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -135,9 +135,73 @@ inline bool Foam::wordRes::operator()(const std::string& text) const
}
// * * * * * * * * * * * * * * * * Functors * * * * * * * * * * * * * * * * //
inline Foam::wordRes::matcher::matcher
(
const UList<wordRe>& allow
)
:
allow_(allow)
{}
inline Foam::wordRes::filter::filter
(
const UList<wordRe>& allow,
const UList<wordRe>& deny
)
:
allow_(allow),
deny_(deny)
{}
inline bool Foam::wordRes::matcher::empty() const noexcept
{
return allow_.empty();
}
inline bool Foam::wordRes::filter::empty() const noexcept
{
return (allow_.empty() && deny_.empty());
}
inline bool Foam::wordRes::matcher::operator()(const std::string& text) const
{
return (wordRes::first_match(values, text) >= 0);
return (wordRes::first_match(allow_, text) >= 0);
}
inline bool Foam::wordRes::filter::operator()(const std::string& text) const
{
if (allow_.empty())
{
// No allow specified, so accept everything that is NOT blocked
return (deny_.empty() || (wordRes::first_match(deny_, text) < 0));
}
else if (deny_.empty())
{
// Nothing blocked, apply accept filter
return (wordRes::first_match(allow_, text) >= 0);
}
else
{
// Both accept and deny filters, need to search more carefully
const auto result = wordRes::found_matched(allow_, text);
return
(
result == wordRe::LITERAL
? true
:
(
result == wordRe::REGEX
&& (wordRes::first_match(deny_, text) < 0)
)
);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,8 +36,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef Cloud_H
#define Cloud_H
#ifndef Foam_Cloud_H
#define Foam_Cloud_H
#include "cloud.H"
#include "IDLList.H"
@ -253,7 +253,8 @@ public:
void readFromFiles
(
objectRegistry& obr,
const wordRes& selectFields
const wordRes& selectFields,
const wordRes& excludeFields = wordRes::null()
) const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017, 2020 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -267,7 +267,8 @@ template<class ParticleType>
void Foam::Cloud<ParticleType>::readFromFiles
(
objectRegistry& obr,
const wordRes& selectFields
const wordRes& selectFields,
const wordRes& excludeFields
) const
{
IOobjectList cloudObjects
@ -280,39 +281,42 @@ void Foam::Cloud<ParticleType>::readFromFiles
false
);
forAllIters(cloudObjects, iter)
const wordRes::filter pred(selectFields, excludeFields);
forAllConstIters(cloudObjects, iter)
{
if (selectFields.size() && !selectFields.match(iter()->name()))
const IOobject& io = *(iter.val());
const word& fldName = io.name();
if (!pred(fldName))
{
continue;
continue; // reject
}
IOobject ioNew
(
iter()->name(),
fldName,
time().timeName(),
obr,
IOobject::NO_READ,
IOobject::NO_WRITE
);
auto& object = *iter();
const bool stored
(
readStoreFile<label>(object, ioNew)
|| readStoreFile<scalar>(object, ioNew)
|| readStoreFile<vector>(object, ioNew)
|| readStoreFile<sphericalTensor>(object, ioNew)
|| readStoreFile<symmTensor>(object, ioNew)
|| readStoreFile<tensor>(object, ioNew)
readStoreFile<label>(io, ioNew)
|| readStoreFile<scalar>(io, ioNew)
|| readStoreFile<vector>(io, ioNew)
|| readStoreFile<sphericalTensor>(io, ioNew)
|| readStoreFile<symmTensor>(io, ioNew)
|| readStoreFile<tensor>(io, ioNew)
);
if (!stored)
{
DebugInfo
<< "Unhandled field type " << iter()->headerClassName()
<< endl;
<< "Unhandled field:" << fldName
<< " type:" << io.headerClassName() << endl;
}
}
}