ENH: add standard _byte access for exprValue

- allows UPstream::broadcast and direct read/write

- add operator== for exprValue
This commit is contained in:
Mark Olesen 2023-11-17 10:15:41 +01:00
parent 24188d70a6
commit 636a654f4a
4 changed files with 141 additions and 6 deletions

View File

@ -1,3 +1,3 @@
Test-exprValue.C
Test-exprValue.cxx
EXE = $(FOAM_USER_APPBIN)/Test-exprValue

View File

@ -22,12 +22,13 @@ Description
#include "IOstreams.H"
#include "ITstream.H"
#include "exprValue.H"
#include "Pstream.H"
using namespace Foam;
void printInfo(const expressions::exprValue& val)
{
Info<< "Boxed type:" << int(val.typeCode())
Pout<< "Boxed type:" << int(val.typeCode())
<< " (" << val.valueTypeName() << ") good:"
<< val.good() << " => " << val << nl;
}
@ -74,16 +75,28 @@ expressions::exprValue tryParse(const std::string& str)
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::noCheckProcessorDirectories();
#include "setRootCase.H"
// Aborts
// expressions::exprValue value(std::string(""));
// Regular broadcast doesn't work
Info<< "exprValue"
<< " sizeof:" << sizeof(expressions::exprValue)
<< " contiguous:" << is_contiguous<expressions::exprValue>::value
<< nl << nl;
{
expressions::exprValue value;
Info<< "exprValue"
<< " sizeof:" << value.size_bytes()
<< nl << nl;
// Info<< "value: " << value << nl;
// Nothing
printInfo(value);
@ -102,8 +115,47 @@ int main(int argc, char *argv[])
value.clear();
printInfo(value);
value = 100 * vector(1,0,0);
if (UPstream::parRun())
{
Info<< "Before broadcast" << nl;
}
if (UPstream::master())
{
value = 100 * vector(1,0,0);
}
printInfo(value);
expressions::exprValue oldValue(value);
// Since the IO serialization is not symmetric (in ASCII) there
// is no 'operator>>' defined and thus the regular Pstream::broadcast
// will not compile.
// Even although the data are contiguous and that code branch is never
// used.
// Fails to compile: Pstream::broadcast(value);
// Broadcast manually
UPstream::broadcast
(
value.data_bytes(),
value.size_bytes(),
UPstream::worldComm
);
Pout<< "same values: " << (oldValue == value) << nl;
// Can put them in a Map and write, but reading will not work...
Map<expressions::exprValue> map;
map(1) = value;
Info<< "map: " << map << nl;
if (UPstream::parRun())
{
Info<< "After broadcast" << nl;
printInfo(value);
}
}

View File

@ -300,6 +300,51 @@ bool Foam::expressions::exprValue::read(ITstream& is)
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
bool Foam::expressions::exprValue::operator==(const exprValue& rhs) const
{
if (typeCode_ != rhs.typeCode_)
{
// Types must match
return false;
}
else if (this == &rhs)
{
return true;
}
switch (typeCode_)
{
#undef doLocalCode
#define doLocalCode(Type, UnusedParam) \
\
case expressions::valueTypeCode::type_##Type : \
{ \
const Type* a = data_.get<Type>(); \
const Type* b = rhs.data_.get<Type>(); \
return (a && b && (*a == *b)); \
break; \
}
FOR_ALL_EXPR_VALUE_TYPES(doLocalCode);
#undef doLocalCode
// exprValue may only be a subset of valueTypeCode types
default: break;
}
return false;
}
bool Foam::expressions::exprValue::operator<(const exprValue& rhs) const
{
// Not yet sortable
return false;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<

View File

@ -44,13 +44,14 @@ SourceFiles
#include "exprTraits.H"
#include "error.H"
#include "contiguous.H"
#include "tokenList.H"
#include "InfoProxy.H"
#include <typeinfo>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Execute macro for known exprValue types, with more probably ones first
// Execute macro for known exprValue types, with more frequent ones first
#undef FOR_ALL_EXPR_VALUE_TYPES
#define FOR_ALL_EXPR_VALUE_TYPES(Macro, ...) \
Macro(scalar, __VA_ARGS__) \
@ -306,6 +307,40 @@ public:
void operator=(const Foam::zero) { fill_zero(); }
// Low-level access
//- Pointer to the data content as byte data
const char* cdata_bytes() const noexcept
{
return reinterpret_cast<const char*>(this);
}
//- Pointer to the data content as byte data
char* data_bytes() noexcept
{
return reinterpret_cast<char*>(this);
}
//- Size of the (contiguous) data content as byte data
//- is compile-time constant
static constexpr unsigned size_bytes() noexcept
{
return sizeof(exprValue);
}
// Member Functions
//- Compare (type,value) for equality
bool operator==(const exprValue& rhs) const;
//- Compare (type,value) for inequality
bool operator!=(const exprValue& rhs) const { return !(*this == rhs); }
//- Compare (type,value) - currently not implemented.
bool operator<(const exprValue& rhs) const;
// Output
//- Return info proxy for printing information to a stream
@ -323,10 +358,13 @@ public:
} // End namespace expressions
//- The data content are contiguous
template<> struct is_contiguous<expressions::exprValue> : std::true_type {};
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
//- Write value to output stream in ASCII format
//- Write value to output stream in ASCII format. No output for !good().
Ostream& operator<<(Ostream& os, const expressions::exprValue& val);
template<>