Commit 8e11daa7 authored by Praetorius, Simon's avatar Praetorius, Simon

test of strtonumber adapted to from_chars conversion

parent 406849ce
Pipeline #1609 failed with stage
in 4 minutes and 26 seconds
...@@ -21,7 +21,7 @@ function(add_dune_quadmath_flags _targets) ...@@ -21,7 +21,7 @@ function(add_dune_quadmath_flags _targets)
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
set_property(TARGET ${_target} set_property(TARGET ${_target}
APPEND_STRING APPEND_STRING
PROPERTY COMPILE_FLAGS "-fext-numeric-literals ") PROPERTY COMPILE_FLAGS "-fext-numeric-literals -Wno-pedantic ")
endif() endif()
endforeach(_target ${_targets}) endforeach(_target ${_targets})
endif(QUADMATH_FOUND) endif(QUADMATH_FOUND)
......
# File for module specific CMake tests. # File for module specific CMake tests.
include(AddQuadMathFlags)
find_package(QuadMath)
\ No newline at end of file
...@@ -48,7 +48,7 @@ set(HAVE_QUADMATH ${QUADMATH_FOUND}) ...@@ -48,7 +48,7 @@ set(HAVE_QUADMATH ${QUADMATH_FOUND})
# -fext-numeric-literals is a GCC extension not available in other compilers like clang # -fext-numeric-literals is a GCC extension not available in other compilers like clang
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
set(_QUADMATH_EXT_NUMERIC_LITERALS "-fext-numeric-literals") set(_QUADMATH_EXT_NUMERIC_LITERALS "-fext-numeric-literals" "-Wno-pedantic")
endif() endif()
# register all QuadMath related flags # register all QuadMath related flags
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
overwritten overwritten
*/ */
/* Define if you have the GCC Quad-Precision library. The value should be ENABLE_QUADMATH
to facilitate activating and deactivating QuadMath using compile flags. */
#cmakedefine HAVE_QUADMATH ENABLE_QUADMATH
/* begin private */ /* begin private */
/* Name of package */ /* Name of package */
#define PACKAGE "@DUNE_MOD_NAME@" #define PACKAGE "@DUNE_MOD_NAME@"
......
...@@ -116,6 +116,7 @@ namespace Dune ...@@ -116,6 +116,7 @@ namespace Dune
mutable container_type cachedData_; mutable container_type cachedData_;
}; };
// implementation of the ThreadLocal policy. Data is stored in thread_local variable. // implementation of the ThreadLocal policy. Data is stored in thread_local variable.
template <class Container> template <class Container>
struct ThreadLocalPolicy struct ThreadLocalPolicy
......
This diff is collapsed.
This diff is collapsed.
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <dune/common/strtonumber.hh>
#include <dune/common/typetraits.hh> #include <dune/common/typetraits.hh>
namespace Dune namespace Dune
...@@ -53,7 +54,7 @@ namespace Dune ...@@ -53,7 +54,7 @@ namespace Dune
{} {}
// constructor from pointer to null-terminated byte string // constructor from pointer to null-terminated byte string
Float128(const char* str) noexcept explicit Float128(const char* str) noexcept
: value_(strtoflt128(str, NULL)) : value_(strtoflt128(str, NULL))
{} {}
...@@ -389,6 +390,21 @@ namespace Dune ...@@ -389,6 +390,21 @@ namespace Dune
struct IsNumber<Impl::Float128> struct IsNumber<Impl::Float128>
: public std::true_type {}; : public std::true_type {};
namespace Impl
{
// Specialization of StrToNumber converter for Float128 type
template<>
struct StrToNumber<Float128,void>
{
static Float128 eval (const char* first, const char* last)
{
auto parser = [](const char* str, char** end) { return strtoflt128(str, end); };
return StrToNumberParser<float128_t>::eval(first,last,parser);
}
};
} // end namespace Impl
} // end namespace Dune } // end namespace Dune
namespace std namespace std
......
...@@ -33,7 +33,7 @@ namespace Dune ...@@ -33,7 +33,7 @@ namespace Dune
{ {
static T eval (const char* first, const char* /*last*/) static T eval (const char* first, const char* /*last*/)
{ {
return T(first);; return T(first);
} }
}; };
...@@ -60,10 +60,16 @@ namespace Dune ...@@ -60,10 +60,16 @@ namespace Dune
T value; T value;
auto result = Std::from_chars(first, last, value); auto result = Std::from_chars(first, last, value);
// require that all characters are consumed during conversion
char const* end = result.ptr;
bool all_consumed = (end != first);
while (all_consumed && (end != last) && (*end != '\0'))
all_consumed = std::isspace(*end++);
if (result.ec == std::errc::result_out_of_range) { if (result.ec == std::errc::result_out_of_range) {
DUNE_THROW(RangeError, std::error_condition(result.ec).message()); DUNE_THROW(RangeError, std::error_condition(result.ec).message());
} }
else if (result.ec == std::errc::invalid_argument) { else if (result.ec == std::errc::invalid_argument || !all_consumed) {
DUNE_THROW(InvalidArgument, DUNE_THROW(InvalidArgument,
"Conversion of '" << first << "' to number failed. Possible reason: invalid string or locale format."); "Conversion of '" << first << "' to number failed. Possible reason: invalid string or locale format.");
} }
...@@ -90,7 +96,7 @@ namespace Dune ...@@ -90,7 +96,7 @@ namespace Dune
// The parser has the signature `T(const char*, char**)` and may set the errno // The parser has the signature `T(const char*, char**)` and may set the errno
// in case of a range error. // in case of a range error.
template<typename Parser> template<typename Parser>
T eval (const char* first, const char* /*last*/, Parser parser) static T eval (const char* first, const char* last, Parser parser)
{ {
char* end; char* end;
auto old_errno = errno; auto old_errno = errno;
...@@ -104,7 +110,7 @@ namespace Dune ...@@ -104,7 +110,7 @@ namespace Dune
// test whether all non-space characters are consumed during conversion // test whether all non-space characters are consumed during conversion
bool all_consumed = (end != first); bool all_consumed = (end != first);
while (all_consumed && (*end != '\0')) while (all_consumed && (end != last) && (*end != '\0'))
all_consumed = std::isspace(*end++); all_consumed = std::isspace(*end++);
if (!all_consumed) { if (!all_consumed) {
...@@ -115,7 +121,6 @@ namespace Dune ...@@ -115,7 +121,6 @@ namespace Dune
return convertToRange<T>(x); return convertToRange<T>(x);
} }
private:
// Check whether a numeric conversion is safe // Check whether a numeric conversion is safe
template<typename U> template<typename U>
static T convertToRange (U const& u) static T convertToRange (U const& u)
......
...@@ -44,10 +44,10 @@ int main() ...@@ -44,10 +44,10 @@ int main()
Float128 x3 = 1.0; Float128 x3 = 1.0;
Float128 x4 = 1.0l; Float128 x4 = 1.0l;
int z1 = x1; DUNE_UNUSED int z1 = x1;
float z2 = x2; DUNE_UNUSED float z2 = x2;
double z3 = x3; DUNE_UNUSED double z3 = x3;
long double z4 = x4; DUNE_UNUSED long double z4 = x4;
// field-vector // field-vector
FieldVector<Float128,3> v{1,2,3}, x; FieldVector<Float128,3> v{1,2,3}, x;
...@@ -78,8 +78,8 @@ int main() ...@@ -78,8 +78,8 @@ int main()
M.solve(v, x); // x = M^(-1)*v M.solve(v, x); // x = M^(-1)*v
auto M3 = M.leftmultiplyany(M2); DUNE_UNUSED auto M3 = M.leftmultiplyany(M2);
auto M4 = M.rightmultiplyany(M2); DUNE_UNUSED auto M4 = M.rightmultiplyany(M2);
using namespace FMatrixHelp; using namespace FMatrixHelp;
......
...@@ -121,19 +121,11 @@ int main() ...@@ -121,19 +121,11 @@ int main()
std::srand(std::time(nullptr)); std::srand(std::time(nullptr));
using Types = std::tuple<bool, signed short, signed int, signed long, signed long long, using Types = std::tuple<bool, signed short, signed int, signed long, signed long long,
unsigned short, unsigned int, unsigned long, unsigned long long, unsigned short, unsigned int, unsigned long, unsigned long long
float, double, long double
#if HAVE_QUADMATH
, Float128
#endif
>; >;
TestSuite test; TestSuite test;
test.check(strTo<char>("0") == '\0');
test.check(strTo<signed char>("0") == '\0');
test.check(strTo<unsigned char>("0") == '\0');
Hybrid::forEach(Types{}, [&test](auto value) Hybrid::forEach(Types{}, [&test](auto value)
{ {
using namespace Dune; using namespace Dune;
...@@ -161,7 +153,7 @@ int main() ...@@ -161,7 +153,7 @@ int main()
bool exception = false; bool exception = false;
try { try {
T val3 = strTo<T>(("1" + oss2.str()).c_str()); // add one more digit in front of number DUNE_UNUSED T val3 = strTo<T>(("1" + oss2.str()).c_str()); // add one more digit in front of number
} catch(Dune::RangeError const&) { } catch(Dune::RangeError const&) {
exception = true; exception = true;
} }
...@@ -189,8 +181,8 @@ int main() ...@@ -189,8 +181,8 @@ int main()
test.check(cmp(value, val0), "Locale_C"); test.check(cmp(value, val0), "Locale_C");
char* new_loc = setlocale(LC_NUMERIC, "de_DE.UTF-8"); char* new_loc = setlocale(LC_NUMERIC, "de_DE.UTF-8");
if (new_loc) { if (new_loc && Std::is_detected<Impl::HasFromChars, T>::value) {
T val1 = strTo<T>("1,5"); T val1 = strTo<T>("1.5");
test.check(cmp(value, val1), "Locale_de_DE"); test.check(cmp(value, val1), "Locale_de_DE");
} else { } else {
std::cout << "### skipped locale de_DE.UTF-8 test\n"; std::cout << "### skipped locale de_DE.UTF-8 test\n";
...@@ -199,7 +191,7 @@ int main() ...@@ -199,7 +191,7 @@ int main()
setlocale(LC_NUMERIC, "C"); setlocale(LC_NUMERIC, "C");
bool exception = false; bool exception = false;
try { try {
T val2 = strTo<T>("1,5"); DUNE_UNUSED T val2 = strTo<T>("1,5");
} catch(Dune::InvalidArgument const&) { } catch(Dune::InvalidArgument const&) {
exception = true; exception = true;
} }
...@@ -207,7 +199,7 @@ int main() ...@@ -207,7 +199,7 @@ int main()
exception = false; exception = false;
try { try {
T val2 = strTo<T>("1.5__"); DUNE_UNUSED T val2 = strTo<T>("1.5__");
} catch(Dune::InvalidArgument const&) { } catch(Dune::InvalidArgument const&) {
exception = true; exception = true;
} }
...@@ -215,7 +207,7 @@ int main() ...@@ -215,7 +207,7 @@ int main()
exception = false; exception = false;
try { try {
T val2 = strTo<T>("1.5 "); DUNE_UNUSED T val2 = strTo<T>("1.5 ");
} catch(Dune::InvalidArgument const&) { } catch(Dune::InvalidArgument const&) {
exception = true; exception = true;
} }
...@@ -223,7 +215,7 @@ int main() ...@@ -223,7 +215,7 @@ int main()
exception = false; exception = false;
try { try {
T val2 = strTo<T>(" 1.5"); DUNE_UNUSED T val2 = strTo<T>(" 1.5");
} catch(Dune::InvalidArgument const&) { } catch(Dune::InvalidArgument const&) {
exception = true; exception = true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment