mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support token conversion of scalar to label (#1696)
- this specifically arises in the case we have used the `#eval` syntax to generate a value. However, since the expressions produce scalar/vector/tensor etc, the tokenized value will *not* be introduced into the dictionary as a label, even if it appears to be an integer value. Eg, eval "2*5", eval "sqrt(100)" both yield `scalar(100)`, which will not be suitable for any consumer expecting a label value. With the `#calc` version, this problem is glossed over since it uses a string buffer for the output (which can suppress the decimal) and re-parses the string into tokens, which causes a label to be recognized. - Since we obviously already support implicit handling of ints as floats (when reading), now also allow conversion of float representations of integral values. Uses the ad hoc value of 1e-4 for deciding if the value deviates too far from being integral. - As a side-effect, can now also support scientific notation when specifying integers. Eg, (10 100 1e+3) for cell counts.
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2016-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,6 +31,7 @@ License
|
||||
#include "parsing.H"
|
||||
#include "IOstreams.H"
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
@ -94,6 +95,34 @@ Foam::Istream& Foam::operator>>(Istream& is, int32_t& val)
|
||||
{
|
||||
val = int32_t(t.labelToken());
|
||||
}
|
||||
else if (t.isScalar())
|
||||
{
|
||||
const scalar sval(t.scalarToken());
|
||||
const intmax_t parsed = intmax_t(std::round(sval));
|
||||
val = 0 + int32_t(parsed);
|
||||
|
||||
// Accept integral floating-point values.
|
||||
// Eg, from string expression evaluation (#1696)
|
||||
|
||||
if (parsed < INT32_MIN || parsed > INT32_MAX)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected integral (int32), value out-of-range "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
else if (1e-4 < std::abs(sval - scalar(parsed)))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected integral (int32), found non-integral value "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,6 +31,7 @@ License
|
||||
#include "parsing.H"
|
||||
#include "IOstreams.H"
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
@ -94,6 +95,34 @@ Foam::Istream& Foam::operator>>(Istream& is, int64_t& val)
|
||||
{
|
||||
val = int64_t(t.labelToken());
|
||||
}
|
||||
else if (t.isScalar())
|
||||
{
|
||||
const scalar sval(t.scalarToken());
|
||||
const intmax_t parsed = intmax_t(std::round(sval));
|
||||
val = 0 + int64_t(parsed);
|
||||
|
||||
// Accept integral floating-point values.
|
||||
// Eg, from string expression evaluation (#1696)
|
||||
|
||||
if (parsed < INT64_MIN || parsed > INT64_MAX)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected integral (int64), value out-of-range "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
else if (1e-4 < std::abs(sval - scalar(parsed)))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected integral (int64), found non-integral value "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -30,6 +30,7 @@ License
|
||||
#include "parsing.H"
|
||||
#include "IOstreams.H"
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
@ -93,6 +94,34 @@ Foam::Istream& Foam::operator>>(Istream& is, uint32_t& val)
|
||||
{
|
||||
val = uint32_t(t.labelToken());
|
||||
}
|
||||
else if (t.isScalar())
|
||||
{
|
||||
const scalar sval(t.scalarToken());
|
||||
const uintmax_t parsed = uintmax_t(std::round(sval));
|
||||
val = 0 + uint32_t(parsed);
|
||||
|
||||
// Accept integral floating-point values.
|
||||
// Eg, from string expression evaluation (#1696)
|
||||
|
||||
if ((sval < -1e-4) || parsed > UINT32_MAX)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected label (uint32), value out-of-range "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
else if (1e-4 < std::abs(sval - scalar(parsed)))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected label (uint32), found non-integral value "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2014-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -30,6 +30,7 @@ License
|
||||
#include "parsing.H"
|
||||
#include "IOstreams.H"
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
@ -93,6 +94,34 @@ Foam::Istream& Foam::operator>>(Istream& is, uint64_t& val)
|
||||
{
|
||||
val = uint64_t(t.labelToken());
|
||||
}
|
||||
else if (t.isScalar())
|
||||
{
|
||||
const scalar sval(t.scalarToken());
|
||||
const uintmax_t parsed = uintmax_t(std::round(sval));
|
||||
val = 0 + uint64_t(parsed);
|
||||
|
||||
// Accept integral floating-point values.
|
||||
// Eg, from string expression evaluation (#1696)
|
||||
|
||||
if ((sval < -1e-4) || parsed > UINT64_MAX)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected label (uint64), value out-of-range "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
else if (1e-4 < std::abs(sval - scalar(parsed)))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "Expected label (uint64), found non-integral value "
|
||||
<< t.info()
|
||||
<< exit(FatalIOError);
|
||||
is.setBad();
|
||||
return is;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
|
||||
Reference in New Issue
Block a user