diff --git a/applications/test/exprValue/Make/files b/applications/test/exprValue/Make/files index 312329154a..e205df0b3c 100644 --- a/applications/test/exprValue/Make/files +++ b/applications/test/exprValue/Make/files @@ -1,3 +1,3 @@ -Test-exprValue.C +Test-exprValue.cxx EXE = $(FOAM_USER_APPBIN)/Test-exprValue diff --git a/applications/test/exprValue/Test-exprValue.C b/applications/test/exprValue/Test-exprValue.cxx similarity index 65% rename from applications/test/exprValue/Test-exprValue.C rename to applications/test/exprValue/Test-exprValue.cxx index fc48f6b534..a4753b365f 100644 --- a/applications/test/exprValue/Test-exprValue.C +++ b/applications/test/exprValue/Test-exprValue.cxx @@ -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::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 map; + map(1) = value; + Info<< "map: " << map << nl; + + if (UPstream::parRun()) + { + Info<< "After broadcast" << nl; + printInfo(value); + } } diff --git a/src/OpenFOAM/expressions/value/exprValue.C b/src/OpenFOAM/expressions/value/exprValue.C index e7ee984568..3e7a44b6d3 100644 --- a/src/OpenFOAM/expressions/value/exprValue.C +++ b/src/OpenFOAM/expressions/value/exprValue.C @@ -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(); \ + const Type* b = rhs.data_.get(); \ + 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<< diff --git a/src/OpenFOAM/expressions/value/exprValue.H b/src/OpenFOAM/expressions/value/exprValue.H index 07260cc86b..014e36f205 100644 --- a/src/OpenFOAM/expressions/value/exprValue.H +++ b/src/OpenFOAM/expressions/value/exprValue.H @@ -44,13 +44,14 @@ SourceFiles #include "exprTraits.H" #include "error.H" +#include "contiguous.H" #include "tokenList.H" #include "InfoProxy.H" #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// 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(this); + } + + //- Pointer to the data content as byte data + char* data_bytes() noexcept + { + return reinterpret_cast(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 : 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<>