- clockValue class for managing the clock values only, with a null
constructor that does not query the system clock (can defer to later).
Can also be used directly for +/- operations.
- refactor clockTime, cpuTime, clock to reduce storage.
- The bitSet class replaces the old PackedBoolList class.
The redesign provides better block-wise access and reduced method
calls. This helps both in cases where the bitSet may be relatively
sparse, and in cases where advantage of contiguous operations can be
made. This makes it easier to work with a bitSet as top-level object.
In addition to the previously available count() method to determine
if a bitSet is being used, now have simpler queries:
- all() - true if all bits in the addressable range are empty
- any() - true if any bits are set at all.
- none() - true if no bits are set.
These are faster than count() and allow early termination.
The new test() method tests the value of a single bit position and
returns a bool without any ambiguity caused by the return type
(like the get() method), nor the const/non-const access (like
operator[] has). The name corresponds to what std::bitset uses.
The new find_first(), find_last(), find_next() methods provide a faster
means of searching for bits that are set.
This can be especially useful when using a bitSet to control an
conditional:
OLD (with macro):
forAll(selected, celli)
{
if (selected[celli])
{
sumVol += mesh_.cellVolumes()[celli];
}
}
NEW (with const_iterator):
for (const label celli : selected)
{
sumVol += mesh_.cellVolumes()[celli];
}
or manually
for
(
label celli = selected.find_first();
celli != -1;
celli = selected.find_next()
)
{
sumVol += mesh_.cellVolumes()[celli];
}
- When marking up contiguous parts of a bitset, an interval can be
represented more efficiently as a labelRange of start/size.
For example,
OLD:
if (isA<processorPolyPatch>(pp))
{
forAll(pp, i)
{
ignoreFaces.set(i);
}
}
NEW:
if (isA<processorPolyPatch>(pp))
{
ignoreFaces.set(pp.range());
}
This class is largely a pre-C++11 holdover. It is now possible to
simply use move construct/assignment directly.
In a few rare cases (eg, polyMesh::resetPrimitives) it has been
replaced by an autoPtr.
Improve alignment of its behaviour with std::shared_ptr
- element_type typedef
- swap, reset methods
* additional reference access methods:
cref()
returns a const reference, synonymous with operator().
This provides a more verbose alternative to using the '()' operator
when that is desired.
Mnemonic: a const form of 'ref()'
constCast()
returns a non-const reference, regardless if the underlying object
itself is a managed pointer or a const object.
This is similar to ref(), but more permissive.
Mnemonic: const_cast<>
Using the constCast() method greatly reduces the amount of typing
and reading. And since the data type is already defined via the tmp
template parameter, the type deduction is automatically known.
Previously,
const tmp<volScalarField>& tfld;
const_cast<volScalarField&>(tfld()).rename("name");
volScalarField& fld = const_cast<volScalarField&>(tfld());
Now,
tfld.constCast().rename("name");
auto& fld = tfld.constCast();
--
BUG: attempts to move tmp value that may still be shared.
- old code simply checked isTmp() to decide if the contents could be
transfered. However, this means that the content of a shared tmp
would be removed, leaving other instances without content.
* movable() method checks that for a non-null temporary that is
unique (not shared).
Improve alignment of its behaviour with std::unique_ptr
- element_type typedef
- release() method - identical to ptr() method
- get() method to get the pointer without checking and without releasing it.
- operator*() for dereferencing
Method name changes
- renamed rawPtr() to get()
- renamed rawRef() to ref(), removed unused const version.
Removed methods/operators
- assignment from a raw pointer was deleted (was rarely used).
Can be convenient, but uncontrolled and potentially unsafe.
Do allow assignment from a literal nullptr though, since this
can never leak (and also corresponds to the unique_ptr API).
Additional methods
- clone() method: forwards to the clone() method of the underlying
data object with argument forwarding.
- reset(autoPtr&&) as an alternative to operator=(autoPtr&&)
STYLE: avoid implicit conversion from autoPtr to object type in many places
- existing implementation has the following:
operator const T&() const { return operator*(); }
which means that the following code works:
autoPtr<mapPolyMesh> map = ...;
updateMesh(*map); // OK: explicit dereferencing
updateMesh(map()); // OK: explicit dereferencing
updateMesh(map); // OK: implicit dereferencing
for clarity it may preferable to avoid the implicit dereferencing
- prefer operator* to operator() when deferenced a return value
so it is clearer that a pointer is involve and not a function call
etc Eg, return *meshPtr_; vs. return meshPtr_();
- relocated HashSetPlusEqOp and HashTablePlusEqOp to
HashSetOps::plusEqOp and HashTableOps::plusEqOp, respectively
- additional functions for converting between a labelHashSet
and a PackedBoolList or List<bool>:
From lists selections to labelHashSet indices:
HashSetOps::used(const PackedBoolList&);
HashSetOps::used(const UList<bool>&);
From labelHashSet to list forms:
PackedBoolList bitset(const labelHashSet&);
List<bool> bools(const labelHashSet&);
- relocated ListAppendEqOp and ListUniqueEqOp to ListOps::appendEqOp
and ListOps::UniqueEqOp, respectively for better code isolation and
documentation of purpose.
- relocated setValues to ListOps::setValue() with many more
alternative selectors possible
- relocated createWithValues to ListOps::createWithValue
for better code isolation. The default initialization value is itself
now a default parameter, which allow for less typing.
Negative indices in the locations to set are now silently ignored,
which makes it possible to use an oldToNew mapping that includes
negative indices.
- additional ListOps::createWithValue taking a single position to set,
available both in copy assign and move assign versions.
Since a negative index is ignored, it is possible to combine with
the output of List::find() etc.
STYLE: changes for PackedList
- code simplication in the PackedList iterators, including dropping
the unused operator() on iterators, which is not available in plain
list versions either.
- improved sizing for PackedBoolList creation from a labelUList.
ENH: additional List constructors, for handling single element list.
- can assist in reducing constructor ambiguity, but can also helps
memory optimization when creating a single element list.
For example,
labelListList labels(one(), identity(mesh.nFaces()));
- This class is largely a pre-C++11 holdover, prior to having movable
references.
- align internals with autoPtr instead of always unconditionally
allocating memory. The valid() method can be used to check for a null
pointer.
- Consolidate into a single file, in anticipation of future removal.
- rvalue() is a (transitional) means of converting Xfer content to a
reference for move construct, move assign semantics.
- valid() method for consistency with autoPtr and tmp classes
- simplify structure, removed unused constuctors.
- transfer from base objects via '=' assignment removed as being too
non-transparent
- add New factory method with perfect forwarding.
- the transfer method was previously a copy
- use std::reverse_iterator adaptors in FixedList
This greatly reduces the amount of code and now avoids the array-bounds
warning for FixedList::rend()
- use pointer arithmetic instead of dereferencing the internal array
- without these will use the normal move construct + move assign.
This is similarly efficient, but avoids the inadvertently having the
incorrect Swap being used for derived classes.
STYLE: remove unused xfer methods for HashTable, HashSet
- unneeded since move construct and move assignment are possible
- can stop producing content when the target number of entries has
been reached.
- change return type to labelList instead an Xfer container.
This allows return-value-optimization and avoids a surrounding
allocation. This potentially breaks existing code.
- make PackedList and PackedBoolList moveable. Drop xfer wrappers.
- support move construct/assignment for linked-lists themselves
and when moving into a 'normal' list
- better consistency with begin/end signatures and the various
iterators.
- for indirect linked-lists, provide iterator access to the underlying
data element address: iter.get() vs &(iter())
- add standard '->' indirection for iterators (as per normal STL
definitions)
* For most cases, this conversion would be largely unintentional
and also less efficient. If the regex is desirable, the caller
should invoke it explicitly.
For example,
findStrings(regExp(str), listOfStrings);
Or use one of the keyType, wordRe, wordRes variants instead.
If string is to be used as a plain (non-regex) matcher,
this can be directly invoked
findMatchingStrings(str, listOfStrings);
or using the ListOps instead:
findIndices(listOfStrings, str);
* provide function interfaces for keyType.
- subsetList, inplaceSubsetList with optional inverted logic.
- use moveable elements where possible.
- allow optional starting offset for the identity global function.
Eg, 'identity(10, start)' vs 'identity(10) + start'
- Eg instead of using labelHashSet, used HashSet<label> which uses
the string::hash for hashing. Other places inadvertently using the
string::hash instead of Hash<label> for hashing.
STYLE: use Map<..> instead of HashTable<.., label, Hash<label>>
- reduces clutter
- add copy construct from UList
- remove copy construct from dissimilar types.
This templated constructor was too generous in what it accepted.
For the special cases where a copy constructor is required with
a change in the data type, now use the createList factory method,
which accepts a unary operator. Eg,
auto scalars = scalarList::createList
(
labels,
[](const label& val){ return 1.5*val; }
);
- this currently just strips off the leading parent directory name
"/this/path/and/subdirs/name"
relative("/this/path") -> "and/subdirs/name"
relative("/this") -> "path/and/subdirs/name"
- simplify structure.
- protect against nullptr when resetting memory streams
- make UIListStream swappable
- add uiliststream as an example of using a plain std::istream
- define regExp::results_type using SubStrings container for handling
groups. This makes a later shift to std::smatch easier, but changes
the regExp API for matching with groups. Previously had list element
0 for regex group 1, now list element 0 is the entire match and list
element 1 is regex group 1.
Old:
List<std::string> mat;
if (re.match(text, mat)) Info<< "group 1: " << mat[0] << nl;
New:
regExp::results_type mat;
if (re.match(text, mat)) Info<< "group 1: " << mat.str(1) << nl;
- can be used to handle when options become redundant, but it is
undesirable to treat its presence as an error. Can now tag it as
being ignored.
argList::ignoreOptionCompat({"oldOption", 1706}, true);
argList::ignoreOptionCompat({"oldBoolOpttion", 1706}, false);
command -oldOption xyz -oldBoolOpttion
- use succincter method names that more closely resemble dictionary
and HashTable method names. This improves method name consistency
between classes and also requires less typing effort:
args.found(optName) vs. args.optionFound(optName)
args.readIfPresent(..) vs. args.optionReadIfPresent(..)
...
args.opt<scalar>(optName) vs. args.optionRead<scalar>(optName)
args.read<scalar>(index) vs. args.argRead<scalar>(index)
- the older method names forms have been retained for code compatibility,
but are now deprecated
- now avoid Istream and token mechanism in favour of a simpler string
parser. This makes the code clearer, smaller, robuster.
- provide convenience ge/gt/le/lt static constructors for scalarRange
for using bounds directly with specifying via a string parameter.
- scalarRange, scalarRanges now follow the unary predicate pattern
(using an operator() for testing). This allows their reuse in
other contexts. Eg, for filtering operations:
myHash.filterValues(scalarRange::ge(100));
- remove unused scalarRanges methods that were specific to handling
lists of time values. These were superseded by timeSelector methods
several versions ago.
- required if there is no system openmp and libomp or libgomp are
only found in the clang hierarchy
STYLE: add some notes in the openmp rules.
- the _OPENMP macro is now used in low-level testing files
- The -rotate-angle option allows convenient specification of a
rotation about an arbitrary axis. Eg, -rotate-angle '((1 1 1) 45)'
- The -origin option can be used to temporarily shift the origin
for the rotation operations. For example,
-origin '(0 0 1)' -rotate-angle '((1 0 0) 180)'
for mirroring.
- the vector normalise() method modifies the object inplace,
the normalised function returns a copy.
vector vec1(1,2,3);
vec1.normalise();
vs
vector vec1(1,2,3);
vec1 /= mag(vec1) + VSMALL;
For const usage, can use either of these
const vector vec2a(normalised(vector(1,2,3)));
const vector vec2b(vector(1,2,3).normalise());
- relocate some standard functionality to TimePaths to allow a lighter
means of managing time directories without using the entire Time
mechanism.
- optional enableLibs for Time construction (default is on)
and a corresponding argList::noLibs() and "-no-libs" option
STYLE:
- mark Time::outputTime() as deprecated MAY-2016
- use pre-increment for runTime, although there is no difference in
behaviour or performance.
- include amount of free system memory in profiling, which can give an
indication of when swapping is about to start
- profilingSummary utility to collect profiling from parallel
calculations. Collects profiling information from processor
directories and summarize the time spent and number of calls as (max
avg min) values.
- split now optionally retains empty substrings.
Added split on fixed field width.
- Foam::name() now formats directly into string buffer, which a
removes one layer of copying and also avoids using a non-constexpr
in the temporary.
STYLE: explicit type narrowing on zero-padded output for ensight