From ea701b23e1d96fafee836f823e059f576ca05e3c Mon Sep 17 00:00:00 2001
From: double-conversion Upstream <kwrobot@kitware.com>
Date: Thu, 25 Oct 2018 16:46:15 -0400
Subject: [PATCH] doubleconversion 2018-10-25 (58a98568)

Code extracted from:

    https://gitlab.kitware.com/third-party/double-conversion.git

at commit 58a985685fd92f482822ba519e3d0c4d17b238fc (for/vtk-20181025-3.1.1).
---
 CMakeLists.txt                         |  32 +--
 Changelog                              |  71 +++++++
 README.kitware.md                      |  18 +-
 double-conversion/CMakeLists.txt       |  57 ------
 double-conversion/bignum-dtoa.cc       |   8 +-
 double-conversion/bignum-dtoa.h        |   2 +-
 double-conversion/bignum.cc            |  13 +-
 double-conversion/bignum.h             |   2 +-
 double-conversion/cached-powers.cc     |  10 +-
 double-conversion/cached-powers.h      |   2 +-
 double-conversion/diy-fp.cc            |   4 +-
 double-conversion/diy-fp.h             |   2 +-
 double-conversion/double-conversion.cc | 262 ++++++++++++++++++++-----
 double-conversion/double-conversion.h  |  49 ++++-
 double-conversion/fast-dtoa.cc         |   8 +-
 double-conversion/fast-dtoa.h          |   2 +-
 double-conversion/fixed-dtoa.cc        |   6 +-
 double-conversion/fixed-dtoa.h         |   2 +-
 double-conversion/ieee.h               |   2 +-
 double-conversion/strtod.cc            |  49 +++--
 double-conversion/strtod.h             |   2 +-
 double-conversion/utils.h              |  51 +++--
 22 files changed, 441 insertions(+), 213 deletions(-)
 create mode 100644 Changelog
 delete mode 100644 double-conversion/CMakeLists.txt

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f011d832113..1fe06e7c22d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,3 @@
-cmake_minimum_required(VERSION 3.3)
-project(doubleconversion)
-
 set(headers
   double-conversion/bignum.h
   double-conversion/cached-powers.h
@@ -10,7 +7,8 @@ set(headers
   double-conversion/fixed-dtoa.h
   double-conversion/ieee.h
   double-conversion/strtod.h
-  double-conversion/utils.h)
+  double-conversion/utils.h
+  "${CMAKE_CURRENT_BINARY_DIR}/vtkdoubleconversion_export.h")
 
 set(sources
   double-conversion/bignum.cc
@@ -22,28 +20,12 @@ set(sources
   double-conversion/fixed-dtoa.cc
   double-conversion/strtod.cc)
 
-vtk_add_library(vtkdoubleconversion
-  ${sources}
-  ${headers})
-
-target_include_directories(
-  vtkdoubleconversion
-  PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-    $<INSTALL_INTERFACE:${VTK_INSTALL_INCLUDE_DIR}>
-)
+vtk_module_add_module(VTK::doubleconversion
+  SOURCES ${sources}
+  HEADERS ${headers}
+  HEADERS_SUBDIR "vtkdoubleconversion")
 
 include(GenerateExportHeader)
-generate_export_header(vtkdoubleconversion
+generate_export_header(doubleconversion
   EXPORT_MACRO_NAME VTKDOUBLECONVERSION_EXPORT
   EXPORT_FILE_NAME vtkdoubleconversion_export.h)
-
-if (NOT VTK_INSTALL_NO_DEVELOPMENT)
-  install(
-    DIRECTORY double-conversion/
-    DESTINATION "${VTK_INSTALL_INCLUDE_DIR}/vtkdoubleconversion/double-conversion"
-    FILES_MATCHING PATTERN "*.h")
-  install(
-    FILES ${CMAKE_CURRENT_BINARY_DIR}/vtkdoubleconversion_export.h
-    DESTINATION "${VTK_INSTALL_INCLUDE_DIR}/vtkdoubleconversion/double-conversion")
-endif()
diff --git a/Changelog b/Changelog
new file mode 100644
index 00000000000..dfaaa91a120
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,71 @@
+2018-09-09:
+  Fix bug where large hex literals would lose their minus sign.
+  Added support for separator characters (which adds a new optional
+  argument). Thus increasing the version number to 3.1.0
+  Added support for hexadecimal float literals.
+  Support for more architectures.
+
+2017-12-06:
+  Renamed `DISALLOW_COPY_AND_ASSIGN` and `DISALLOW_IMPLICIT_CONSTRUCTORS`
+  macros to `DC_DISALLOW_COPY_AND_ASSIGN` and
+  `DC_DISALLOW_IMPLICIT_CONSTRUCTORS` to make it easier to integrate the
+  library with other libraries that have similar macros.
+
+2017-08-05:
+  Tagged v3.0.0.
+  Due to the directory rename switching to a new version number.
+  The API for the library itself hasn't changed.
+
+2017-03-04:
+  Avoid negative shift. Fixes #41.
+
+2016-11-17:
+  Support RISC-V.
+
+
+2016-09-10:
+  Add fPIC flag on x86_64 if the compiler supports it. Fixes #34.
+
+2015 and 2016:
+  Lots of improvements to the build system.
+
+2015:
+  Warning fixes.
+
+2015-05-19:
+  Rename 'src' directory to 'double-conversion'.
+
+2014-03-08:
+  Update version number for cmake.
+  Support shared libraries with cmake.
+  Add build instructions to the README.
+
+2014-01-12:
+  Tagged v2.0.1.
+  Fix compilation for ARMv8 64bit (used wrong define).
+  Improved SConstruct file. Thanks to Milan Bouchet-Valat and Elan Ruusamäe.
+  Fixed lots of warnings (especially on Windows). Thanks to Greg Smith.
+
+2013-11-09:
+  Tagged v2.0.0.
+  String-to-Double|Float: ALLOW_LEADING_SPACES and similar flags now include
+  new-lines, tabs and all Unicode whitespace characters.
+
+2013-11-09:
+  Tagged v1.1.2.
+  Add support for ARM 64 and OsX ppc.
+  Rewrite tests so they pass under Visual Studio.
+  Add CMake build system support.
+  Fix warnings.
+
+2012-06-10:
+  Tagged v1.1.1.
+  Null terminate exponent buffer (only an issue when asserts are enabled).
+  Support more architectures.
+
+2012-02-05:
+  Merged in Single-branch with single-precision support.
+  Tagged v1.1 (based on b28450f33e1db493948a535d8f84e88fa211bd10).
+
+2012-02-05:
+  Tagged v1.0 (based on eda0196e9ac8fcdf59e92cb62885ee0af5391969).
diff --git a/README.kitware.md b/README.kitware.md
index 1307d1b621f..8bb0971bc91 100644
--- a/README.kitware.md
+++ b/README.kitware.md
@@ -1,10 +1,12 @@
-double-conversion fork for VTK
----------------------
+# double-conversion fork for VTK
 
-This branch contains required changes to embed double-conversion into VTK.
-This includes the following:
+This branch contains changes required to embed double-conversion into VTK.
+This includes changes made primarily to the build system to allow it to be
+embedded into another source tree as well as a header to facilitate mangling
+of the symbols to avoid conflicts with other copies of the library within a
+single process.
 
-* add `.gitattributes`
-* integrate VTK's module system (added CMakeLists.vtk.txt)
-* update `double-conversion/utils.h` to include exports header and mangle namespace.
-* add exports to `double-conversion/utils.h and `double-conversion/double-conversion.h`.
+  * add `.gitattributes`
+  * integrate VTK's module system
+  * mangle symbols for VTK
+  * export symbols
diff --git a/double-conversion/CMakeLists.txt b/double-conversion/CMakeLists.txt
deleted file mode 100644
index 2d13b36af1f..00000000000
--- a/double-conversion/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-set(headers
-  bignum.h
-  cached-powers.h
-  diy-fp.h
-  double-conversion.h
-  fast-dtoa.h
-  fixed-dtoa.h
-  ieee.h
-  strtod.h
-  utils.h
-  )
-
-add_library(double-conversion
-bignum.cc
-bignum-dtoa.cc
-cached-powers.cc
-diy-fp.cc
-double-conversion.cc
-fast-dtoa.cc
-fixed-dtoa.cc
-strtod.cc
-${headers}
-)
-
-target_include_directories(double-conversion PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>)
-
-# Add fPIC on x86_64 when supported.
-include(CheckCXXCompilerFlag)
-check_cxx_compiler_flag(-fPIC CXX_HAS_FPIC)
-
-if(CXX_HAS_FPIC AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
-  set_target_properties(double-conversion PROPERTIES COMPILE_FLAGS "-fPIC")
-endif()
-
-#
-# associates the list of headers with the library
-# for the purposes of installation/import into other projects
-set_target_properties(double-conversion
-    PROPERTIES PUBLIC_HEADER "${headers}")
-
-if (BUILD_SHARED_LIBS)
-  set_target_properties(double-conversion
-    PROPERTIES VERSION ${double-conversion_SOVERSION}
-               SOVERSION ${double-conversion_SOVERSION_MAJOR})
-endif()
-
-#
-# install command to set up library install
-# given the above PUBLIC_HEADER property set, this
-# pulls along all the header files with the library.
-install(TARGETS double-conversion
-  EXPORT double-conversionLibraryDepends
-  RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
-  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib
-  ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib
-  PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/double-conversion"
-  COMPONENT dev)
diff --git a/double-conversion/bignum-dtoa.cc b/double-conversion/bignum-dtoa.cc
index f1ad7a5ae8d..526f96edf54 100644
--- a/double-conversion/bignum-dtoa.cc
+++ b/double-conversion/bignum-dtoa.cc
@@ -25,12 +25,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <math.h>
+#include <cmath>
 
-#include "bignum-dtoa.h"
+#include <double-conversion/bignum-dtoa.h>
 
-#include "bignum.h"
-#include "ieee.h"
+#include <double-conversion/bignum.h>
+#include <double-conversion/ieee.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/bignum-dtoa.h b/double-conversion/bignum-dtoa.h
index 34b961992d6..9d15ce3dce9 100644
--- a/double-conversion/bignum-dtoa.h
+++ b/double-conversion/bignum-dtoa.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
 #define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/bignum.cc b/double-conversion/bignum.cc
index 8892de8f2a3..a7bc86d0c0e 100644
--- a/double-conversion/bignum.cc
+++ b/double-conversion/bignum.cc
@@ -25,13 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "bignum.h"
-#include "utils.h"
+#include <double-conversion/bignum.h>
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
 Bignum::Bignum()
-    : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
+    : bigits_buffer_(), bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
   for (int i = 0; i < kBigitCapacity; ++i) {
     bigits_[i] = 0;
   }
@@ -445,26 +445,27 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
   mask >>= 2;
   uint64_t this_value = base;
 
-  bool delayed_multipliciation = false;
+  bool delayed_multiplication = false;
   const uint64_t max_32bits = 0xFFFFFFFF;
   while (mask != 0 && this_value <= max_32bits) {
     this_value = this_value * this_value;
     // Verify that there is enough space in this_value to perform the
     // multiplication.  The first bit_size bits must be 0.
     if ((power_exponent & mask) != 0) {
+      ASSERT(bit_size > 0);
       uint64_t base_bits_mask =
           ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
       bool high_bits_zero = (this_value & base_bits_mask) == 0;
       if (high_bits_zero) {
         this_value *= base;
       } else {
-        delayed_multipliciation = true;
+        delayed_multiplication = true;
       }
     }
     mask >>= 1;
   }
   AssignUInt64(this_value);
-  if (delayed_multipliciation) {
+  if (delayed_multiplication) {
     MultiplyByUInt32(base);
   }
 
diff --git a/double-conversion/bignum.h b/double-conversion/bignum.h
index 7c289fa2f6b..238a351196e 100644
--- a/double-conversion/bignum.h
+++ b/double-conversion/bignum.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_BIGNUM_H_
 #define DOUBLE_CONVERSION_BIGNUM_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/cached-powers.cc b/double-conversion/cached-powers.cc
index 2b43f064127..6f771e9c73d 100644
--- a/double-conversion/cached-powers.cc
+++ b/double-conversion/cached-powers.cc
@@ -25,13 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <stdarg.h>
-#include <limits.h>
-#include <math.h>
+#include <climits>
+#include <cmath>
+#include <cstdarg>
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
-#include "cached-powers.h"
+#include <double-conversion/cached-powers.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/cached-powers.h b/double-conversion/cached-powers.h
index 61a50614cf1..eabff4a15af 100644
--- a/double-conversion/cached-powers.h
+++ b/double-conversion/cached-powers.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_
 #define DOUBLE_CONVERSION_CACHED_POWERS_H_
 
-#include "diy-fp.h"
+#include <double-conversion/diy-fp.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/diy-fp.cc b/double-conversion/diy-fp.cc
index ddd1891b168..82b0d08af4e 100644
--- a/double-conversion/diy-fp.cc
+++ b/double-conversion/diy-fp.cc
@@ -26,8 +26,8 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-#include "diy-fp.h"
-#include "utils.h"
+#include <double-conversion/diy-fp.h>
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/diy-fp.h b/double-conversion/diy-fp.h
index 2edf34674ee..e2011d43e5a 100644
--- a/double-conversion/diy-fp.h
+++ b/double-conversion/diy-fp.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_DIY_FP_H_
 #define DOUBLE_CONVERSION_DIY_FP_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/double-conversion.cc b/double-conversion/double-conversion.cc
index 6f21a0124c4..ecd1a5ef3f1 100644
--- a/double-conversion/double-conversion.cc
+++ b/double-conversion/double-conversion.cc
@@ -25,17 +25,18 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <limits.h>
-#include <math.h>
+#include <climits>
+#include <locale>
+#include <cmath>
 
-#include "double-conversion.h"
+#include <double-conversion/double-conversion.h>
 
-#include "bignum-dtoa.h"
-#include "fast-dtoa.h"
-#include "fixed-dtoa.h"
-#include "ieee.h"
-#include "strtod.h"
-#include "utils.h"
+#include <double-conversion/bignum-dtoa.h>
+#include <double-conversion/fast-dtoa.h>
+#include <double-conversion/fixed-dtoa.h>
+#include <double-conversion/ieee.h>
+#include <double-conversion/strtod.h>
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
@@ -414,21 +415,55 @@ void DoubleToStringConverter::DoubleToAscii(double v,
 }
 
 
+namespace {
+
+inline char ToLower(char ch) {
+  static const std::ctype<char>& cType =
+      std::use_facet<std::ctype<char> >(std::locale::classic());
+  return cType.tolower(ch);
+}
+
+inline char Pass(char ch) {
+  return ch;
+}
+
+template <class Iterator, class Converter>
+static inline bool ConsumeSubStringImpl(Iterator* current,
+                                        Iterator end,
+                                        const char* substring,
+                                        Converter converter) {
+  ASSERT(converter(**current) == *substring);
+  for (substring++; *substring != '\0'; substring++) {
+    ++*current;
+    if (*current == end || converter(**current) != *substring) {
+      return false;
+    }
+  }
+  ++*current;
+  return true;
+}
+
 // Consumes the given substring from the iterator.
 // Returns false, if the substring does not match.
 template <class Iterator>
 static bool ConsumeSubString(Iterator* current,
                              Iterator end,
-                             const char* substring) {
-  ASSERT(**current == *substring);
-  for (substring++; *substring != '\0'; substring++) {
-    ++*current;
-    if (*current == end || **current != *substring) return false;
+                             const char* substring,
+                             bool allow_case_insensibility) {
+  if (allow_case_insensibility) {
+    return ConsumeSubStringImpl(current, end, substring, ToLower);
+  } else {
+    return ConsumeSubStringImpl(current, end, substring, Pass);
   }
-  ++*current;
-  return true;
 }
 
+// Consumes first character of the str is equal to ch
+inline bool ConsumeFirstCharacter(char ch,
+                                         const char* str,
+                                         bool case_insensibility) {
+  return case_insensibility ? ToLower(ch) == str[0] : ch == str[0];
+}
+}  // namespace
 
 // Maximum number of significant digits in decimal representation.
 // The longest possible double in decimal representation is
@@ -502,7 +537,7 @@ static bool IsDecimalDigitForRadix(int c, int radix) {
 #pragma optimize("",on)
 #else
 static bool inline IsDecimalDigitForRadix(int c, int radix) {
-	return '0' <= c && c <= '9' && (c - '0') < radix;
+  return '0' <= c && c <= '9' && (c - '0') < radix;
 }
 #endif
 // Returns true if 'c' is a character digit that is valid for the given radix.
@@ -516,17 +551,86 @@ static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
   return radix > 10 && c >= a_character && c < a_character + radix - 10;
 }
 
+// Returns true, when the iterator is equal to end.
+template<class Iterator>
+static bool Advance (Iterator* it, char separator, int base, Iterator& end) {
+  if (separator == StringToDoubleConverter::kNoSeparator) {
+    ++(*it);
+    return *it == end;
+  }
+  if (!isDigit(**it, base)) {
+    ++(*it);
+    return *it == end;
+  }
+  ++(*it);
+  if (*it == end) return true;
+  if (*it + 1 == end) return false;
+  if (**it == separator && isDigit(*(*it + 1), base)) {
+    ++(*it);
+  }
+  return *it == end;
+}
+
+// Checks whether the string in the range start-end is a hex-float string.
+// This function assumes that the leading '0x'/'0X' is already consumed.
+//
+// Hex float strings are of one of the following forms:
+//   - hex_digits+ 'p' ('+'|'-')? exponent_digits+
+//   - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+
+//   - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+
+template<class Iterator>
+static bool IsHexFloatString(Iterator start,
+                             Iterator end,
+                             char separator,
+                             bool allow_trailing_junk) {
+  ASSERT(start != end);
+
+  Iterator current = start;
+
+  bool saw_digit = false;
+  while (isDigit(*current, 16)) {
+    saw_digit = true;
+    if (Advance(&current, separator, 16, end)) return false;
+  }
+  if (*current == '.') {
+    if (Advance(&current, separator, 16, end)) return false;
+    while (isDigit(*current, 16)) {
+      saw_digit = true;
+      if (Advance(&current, separator, 16, end)) return false;
+    }
+    if (!saw_digit) return false;  // Only the '.', but no digits.
+  }
+  if (*current != 'p' && *current != 'P') return false;
+  if (Advance(&current, separator, 16, end)) return false;
+  if (*current == '+' || *current == '-') {
+    if (Advance(&current, separator, 16, end)) return false;
+  }
+  if (!isDigit(*current, 10)) return false;
+  if (Advance(&current, separator, 16, end)) return true;
+  while (isDigit(*current, 10)) {
+    if (Advance(&current, separator, 16, end)) return true;
+  }
+  return allow_trailing_junk || !AdvanceToNonspace(&current, end);
+}
+
 
 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
+//
+// If parse_as_hex_float is true, then the string must be a valid
+// hex-float.
 template <int radix_log_2, class Iterator>
 static double RadixStringToIeee(Iterator* current,
                                 Iterator end,
                                 bool sign,
+                                char separator,
+                                bool parse_as_hex_float,
                                 bool allow_trailing_junk,
                                 double junk_string_value,
                                 bool read_as_double,
                                 bool* result_is_junk) {
   ASSERT(*current != end);
+  ASSERT(!parse_as_hex_float ||
+      IsHexFloatString(*current, end, separator, allow_trailing_junk));
 
   const int kDoubleSize = Double::kSignificandSize;
   const int kSingleSize = Single::kSignificandSize;
@@ -534,27 +638,39 @@ static double RadixStringToIeee(Iterator* current,
 
   *result_is_junk = true;
 
+  int64_t number = 0;
+  int exponent = 0;
+  const int radix = (1 << radix_log_2);
+  // Whether we have encountered a '.' and are parsing the decimal digits.
+  // Only relevant if parse_as_hex_float is true.
+  bool post_decimal = false;
+
   // Skip leading 0s.
   while (**current == '0') {
-    ++(*current);
-    if (*current == end) {
+    if (Advance(current, separator, radix, end)) {
       *result_is_junk = false;
       return SignedZero(sign);
     }
   }
 
-  int64_t number = 0;
-  int exponent = 0;
-  const int radix = (1 << radix_log_2);
-
-  do {
+  while (true) {
     int digit;
     if (IsDecimalDigitForRadix(**current, radix)) {
       digit = static_cast<char>(**current) - '0';
+      if (post_decimal) exponent -= radix_log_2;
     } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
       digit = static_cast<char>(**current) - 'a' + 10;
+      if (post_decimal) exponent -= radix_log_2;
     } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
       digit = static_cast<char>(**current) - 'A' + 10;
+      if (post_decimal) exponent -= radix_log_2;
+    } else if (parse_as_hex_float && **current == '.') {
+      post_decimal = true;
+      Advance(current, separator, radix, end);
+      ASSERT(*current != end);
+      continue;
+    } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
+      break;
     } else {
       if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
         break;
@@ -577,17 +693,26 @@ static double RadixStringToIeee(Iterator* current,
       int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
       int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
       number >>= overflow_bits_count;
-      exponent = overflow_bits_count;
+      exponent += overflow_bits_count;
 
       bool zero_tail = true;
       for (;;) {
-        ++(*current);
-        if (*current == end || !isDigit(**current, radix)) break;
+        if (Advance(current, separator, radix, end)) break;
+        if (parse_as_hex_float && **current == '.') {
+          // Just run over the '.'. We are just trying to see whether there is
+          // a non-zero digit somewhere.
+          Advance(current, separator, radix, end);
+          ASSERT(*current != end);
+          post_decimal = true;
+        }
+        if (!isDigit(**current, radix)) break;
         zero_tail = zero_tail && **current == '0';
-        exponent += radix_log_2;
+        if (!post_decimal) exponent += radix_log_2;
       }
 
-      if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
+      if (!parse_as_hex_float &&
+          !allow_trailing_junk &&
+          AdvanceToNonspace(current, end)) {
         return junk_string_value;
       }
 
@@ -609,15 +734,37 @@ static double RadixStringToIeee(Iterator* current,
       }
       break;
     }
-    ++(*current);
-  } while (*current != end);
+    if (Advance(current, separator, radix, end)) break;
+  }
 
   ASSERT(number < ((int64_t)1 << kSignificandSize));
   ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
 
   *result_is_junk = false;
 
-  if (exponent == 0) {
+  if (parse_as_hex_float) {
+    ASSERT(**current == 'p' || **current == 'P');
+    Advance(current, separator, radix, end);
+    ASSERT(*current != end);
+    bool is_negative = false;
+    if (**current == '+') {
+      Advance(current, separator, radix, end);
+      ASSERT(*current != end);
+    } else if (**current == '-') {
+      is_negative = true;
+      Advance(current, separator, radix, end);
+      ASSERT(*current != end);
+    }
+    int written_exponent = 0;
+    while (IsDecimalDigitForRadix(**current, 10)) {
+      written_exponent = 10 * written_exponent + **current - '0';
+      if (Advance(current, separator, radix, end)) break;
+    }
+    if (is_negative) written_exponent = -written_exponent;
+    exponent += written_exponent;
+  }
+
+  if (exponent == 0 || number == 0) {
     if (sign) {
       if (number == 0) return -0.0;
       number = -number;
@@ -626,10 +773,10 @@ static double RadixStringToIeee(Iterator* current,
   }
 
   ASSERT(number != 0);
-  return Double(DiyFp(number, exponent)).value();
+  double result = Double(DiyFp(number, exponent)).value();
+  return sign ? -result : result;
 }
 
-
 template <class Iterator>
 double StringToDoubleConverter::StringToIeee(
     Iterator input,
@@ -645,6 +792,7 @@ double StringToDoubleConverter::StringToIeee(
   const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
   const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
   const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
+  const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0;
 
   // To make sure that iterator dereferencing is valid the following
   // convention is used:
@@ -694,8 +842,8 @@ double StringToDoubleConverter::StringToIeee(
   }
 
   if (infinity_symbol_ != NULL) {
-    if (*current == infinity_symbol_[0]) {
-      if (!ConsumeSubString(&current, end, infinity_symbol_)) {
+    if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) {
+      if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensibility)) {
         return junk_string_value_;
       }
 
@@ -713,8 +861,8 @@ double StringToDoubleConverter::StringToIeee(
   }
 
   if (nan_symbol_ != NULL) {
-    if (*current == nan_symbol_[0]) {
-      if (!ConsumeSubString(&current, end, nan_symbol_)) {
+    if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) {
+      if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensibility)) {
         return junk_string_value_;
       }
 
@@ -733,8 +881,7 @@ double StringToDoubleConverter::StringToIeee(
 
   bool leading_zero = false;
   if (*current == '0') {
-    ++current;
-    if (current == end) {
+    if (Advance(&current, separator_, 10, end)) {
       *processed_characters_count = static_cast<int>(current - input);
       return SignedZero(sign);
     }
@@ -742,16 +889,24 @@ double StringToDoubleConverter::StringToIeee(
     leading_zero = true;
 
     // It could be hexadecimal value.
-    if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
+    if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
+        (*current == 'x' || *current == 'X')) {
       ++current;
-      if (current == end || !isDigit(*current, 16)) {
-        return junk_string_value_;  // "0x".
+
+      bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
+                IsHexFloatString(current, end, separator_, allow_trailing_junk);
+
+      if (current == end) return junk_string_value_;  // "0x"
+      if (!parse_as_hex_float && !isDigit(*current, 16)) {
+        return junk_string_value_;
       }
 
       bool result_is_junk;
       double result = RadixStringToIeee<4>(&current,
                                            end,
                                            sign,
+                                           separator_,
+                                           parse_as_hex_float,
                                            allow_trailing_junk,
                                            junk_string_value_,
                                            read_as_double,
@@ -765,8 +920,7 @@ double StringToDoubleConverter::StringToIeee(
 
     // Ignore leading zeros in the integer part.
     while (*current == '0') {
-      ++current;
-      if (current == end) {
+      if (Advance(&current, separator_, 10, end)) {
         *processed_characters_count = static_cast<int>(current - input);
         return SignedZero(sign);
       }
@@ -787,8 +941,7 @@ double StringToDoubleConverter::StringToIeee(
       nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
     }
     octal = octal && *current < '8';
-    ++current;
-    if (current == end) goto parsing_done;
+    if (Advance(&current, separator_, 10, end)) goto parsing_done;
   }
 
   if (significant_digits == 0) {
@@ -799,8 +952,7 @@ double StringToDoubleConverter::StringToIeee(
     if (octal && !allow_trailing_junk) return junk_string_value_;
     if (octal) goto parsing_done;
 
-    ++current;
-    if (current == end) {
+    if (Advance(&current, separator_, 10, end)) {
       if (significant_digits == 0 && !leading_zero) {
         return junk_string_value_;
       } else {
@@ -813,8 +965,7 @@ double StringToDoubleConverter::StringToIeee(
       // Integer part consists of 0 or is absent. Significant digits start after
       // leading zeros (if any).
       while (*current == '0') {
-        ++current;
-        if (current == end) {
+        if (Advance(&current, separator_, 10, end)) {
           *processed_characters_count = static_cast<int>(current - input);
           return SignedZero(sign);
         }
@@ -834,8 +985,7 @@ double StringToDoubleConverter::StringToIeee(
         // Ignore insignificant digits in the fractional part.
         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
       }
-      ++current;
-      if (current == end) goto parsing_done;
+      if (Advance(&current, separator_, 10, end)) goto parsing_done;
     }
   }
 
@@ -851,9 +1001,11 @@ double StringToDoubleConverter::StringToIeee(
   if (*current == 'e' || *current == 'E') {
     if (octal && !allow_trailing_junk) return junk_string_value_;
     if (octal) goto parsing_done;
+    Iterator junk_begin = current;
     ++current;
     if (current == end) {
       if (allow_trailing_junk) {
+        current = junk_begin;
         goto parsing_done;
       } else {
         return junk_string_value_;
@@ -865,6 +1017,7 @@ double StringToDoubleConverter::StringToIeee(
       ++current;
       if (current == end) {
         if (allow_trailing_junk) {
+          current = junk_begin;
           goto parsing_done;
         } else {
           return junk_string_value_;
@@ -874,6 +1027,7 @@ double StringToDoubleConverter::StringToIeee(
 
     if (current == end || *current < '0' || *current > '9') {
       if (allow_trailing_junk) {
+        current = junk_begin;
         goto parsing_done;
       } else {
         return junk_string_value_;
@@ -918,6 +1072,8 @@ double StringToDoubleConverter::StringToIeee(
     result = RadixStringToIeee<3>(&start,
                                   buffer + buffer_pos,
                                   sign,
+                                  separator_,
+                                  false, // Don't parse as hex_float.
                                   allow_trailing_junk,
                                   junk_string_value_,
                                   read_as_double,
diff --git a/double-conversion/double-conversion.h b/double-conversion/double-conversion.h
index 49db8180fe9..c995eb783b7 100644
--- a/double-conversion/double-conversion.h
+++ b/double-conversion/double-conversion.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
 #define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
@@ -294,13 +294,18 @@ class VTKDOUBLECONVERSION_EXPORT DoubleToStringConverter {
   // should be at least kBase10MaximalLength + 1 characters long.
   static const int kBase10MaximalLength = 17;
 
-  // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or
-  // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v'
-  // after it has been casted to a single-precision float. That is, in this
-  // mode static_cast<float>(v) must not be NaN, +Infinity or -Infinity.
+  // Converts the given double 'v' to digit characters. 'v' must not be NaN,
+  // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also
+  // applies to 'v' after it has been casted to a single-precision float. That
+  // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or
+  // -Infinity.
   //
   // The result should be interpreted as buffer * 10^(point-length).
   //
+  // The digits are written to the buffer in the platform's charset, which is
+  // often UTF-8 (with ASCII-range digits) but may be another charset, such
+  // as EBCDIC.
+  //
   // The output depends on the given mode:
   //  - SHORTEST: produce the least amount of digits for which the internal
   //   identity requirement is still satisfied. If the digits are printed
@@ -389,9 +394,13 @@ class VTKDOUBLECONVERSION_EXPORT StringToDoubleConverter {
     ALLOW_TRAILING_JUNK = 4,
     ALLOW_LEADING_SPACES = 8,
     ALLOW_TRAILING_SPACES = 16,
-    ALLOW_SPACES_AFTER_SIGN = 32
+    ALLOW_SPACES_AFTER_SIGN = 32,
+    ALLOW_CASE_INSENSIBILITY = 64,
+    ALLOW_HEX_FLOATS = 128,
   };
 
+  static const uc16 kNoSeparator = '\0';
+
   // Flags should be a bit-or combination of the possible Flags-enum.
   //  - NO_FLAGS: no special flags.
   //  - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
@@ -421,6 +430,13 @@ class VTKDOUBLECONVERSION_EXPORT StringToDoubleConverter {
   //  - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
   //       Ex: StringToDouble("-   123.2") -> -123.2.
   //           StringToDouble("+   123.2") -> 123.2
+  //  - ALLOW_CASE_INSENSIBILITY: ignore case of characters for special values:
+  //      infinity and nan.
+  //  - ALLOW_HEX_FLOATS: allows hexadecimal float literals.
+  //      This *must* start with "0x" and separate the exponent with "p".
+  //      Examples: 0x1.2p3 == 9.0
+  //                0x10.1p0 == 16.0625
+  //      ALLOW_HEX and ALLOW_HEX_FLOATS are indendent.
   //
   // empty_string_value is returned when an empty string is given as input.
   // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
@@ -445,6 +461,12 @@ class VTKDOUBLECONVERSION_EXPORT StringToDoubleConverter {
   //  - they must not have the same first character.
   //  - they must not start with digits.
   //
+  // If the separator character is not kNoSeparator, then that specific
+  // character is ignored when in between two valid digits of the significant.
+  // It is not allowed to appear in the exponent.
+  // It is not allowed to lead or trail the number.
+  // It is not allowed to appear twice next to each other.
+  //
   // Examples:
   //  flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
   //  empty_string_value = 0.0,
@@ -484,16 +506,26 @@ class VTKDOUBLECONVERSION_EXPORT StringToDoubleConverter {
   //    StringToDouble("01239E45") -> 1239e45.
   //    StringToDouble("-infinity") -> NaN  // junk_string_value.
   //    StringToDouble("NaN") -> NaN  // junk_string_value.
+  //
+  //  flags = NO_FLAGS,
+  //  separator = ' ':
+  //    StringToDouble("1 2 3 4") -> 1234.0
+  //    StringToDouble("1  2") -> NaN // junk_string_value
+  //    StringToDouble("1 000 000.0") -> 1000000.0
+  //    StringToDouble("1.000 000") -> 1.0
+  //    StringToDouble("1.0e1 000") -> NaN // junk_string_value
   StringToDoubleConverter(int flags,
                           double empty_string_value,
                           double junk_string_value,
                           const char* infinity_symbol,
-                          const char* nan_symbol)
+                          const char* nan_symbol,
+                          uc16 separator = kNoSeparator)
       : flags_(flags),
         empty_string_value_(empty_string_value),
         junk_string_value_(junk_string_value),
         infinity_symbol_(infinity_symbol),
-        nan_symbol_(nan_symbol) {
+        nan_symbol_(nan_symbol),
+        separator_(separator) {
   }
 
   // Performs the conversion.
@@ -528,6 +560,7 @@ class VTKDOUBLECONVERSION_EXPORT StringToDoubleConverter {
   const double junk_string_value_;
   const char* const infinity_symbol_;
   const char* const nan_symbol_;
+  const uc16 separator_;
 
   template <class Iterator>
   double StringToIeee(Iterator start_pointer,
diff --git a/double-conversion/fast-dtoa.cc b/double-conversion/fast-dtoa.cc
index 61350383a95..e5c222291f5 100644
--- a/double-conversion/fast-dtoa.cc
+++ b/double-conversion/fast-dtoa.cc
@@ -25,11 +25,11 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "fast-dtoa.h"
+#include <double-conversion/fast-dtoa.h>
 
-#include "cached-powers.h"
-#include "diy-fp.h"
-#include "ieee.h"
+#include <double-conversion/cached-powers.h>
+#include <double-conversion/diy-fp.h>
+#include <double-conversion/ieee.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/fast-dtoa.h b/double-conversion/fast-dtoa.h
index 5f1e8eee5e5..ac4317c04dd 100644
--- a/double-conversion/fast-dtoa.h
+++ b/double-conversion/fast-dtoa.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
 #define DOUBLE_CONVERSION_FAST_DTOA_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/fixed-dtoa.cc b/double-conversion/fixed-dtoa.cc
index 0f55a0b6eb3..8c111aca642 100644
--- a/double-conversion/fixed-dtoa.cc
+++ b/double-conversion/fixed-dtoa.cc
@@ -25,10 +25,10 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <math.h>
+#include <cmath>
 
-#include "fixed-dtoa.h"
-#include "ieee.h"
+#include <double-conversion/fixed-dtoa.h>
+#include <double-conversion/ieee.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/fixed-dtoa.h b/double-conversion/fixed-dtoa.h
index 3bdd08e21f5..a9436fc9f61 100644
--- a/double-conversion/fixed-dtoa.h
+++ b/double-conversion/fixed-dtoa.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
 #define DOUBLE_CONVERSION_FIXED_DTOA_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/ieee.h b/double-conversion/ieee.h
index 4a5fe8f9c0a..baaeced31ce 100644
--- a/double-conversion/ieee.h
+++ b/double-conversion/ieee.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_DOUBLE_H_
 #define DOUBLE_CONVERSION_DOUBLE_H_
 
-#include "diy-fp.h"
+#include <double-conversion/diy-fp.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/strtod.cc b/double-conversion/strtod.cc
index 17abcbb2a55..e8cc13f2de9 100644
--- a/double-conversion/strtod.cc
+++ b/double-conversion/strtod.cc
@@ -25,13 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include <stdarg.h>
-#include <limits.h>
+#include <climits>
+#include <cstdarg>
 
-#include "strtod.h"
-#include "bignum.h"
-#include "cached-powers.h"
-#include "ieee.h"
+#include <double-conversion/bignum.h>
+#include <double-conversion/cached-powers.h>
+#include <double-conversion/ieee.h>
+#include <double-conversion/strtod.h>
 
 namespace double_conversion {
 
@@ -205,7 +205,7 @@ static bool DoubleStrtod(Vector<const char> trimmed,
   // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
   // the same problem.
   return false;
-#endif
+#else
   if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
     int read_digits;
     // The trimmed input fits into a double.
@@ -243,6 +243,7 @@ static bool DoubleStrtod(Vector<const char> trimmed,
     }
   }
   return false;
+#endif
 }
 
 
@@ -471,6 +472,30 @@ double Strtod(Vector<const char> buffer, int exponent) {
   }
 }
 
+static float SanitizedDoubletof(double d) {
+  ASSERT(d >= 0.0);
+  // ASAN has a sanitize check that disallows casting doubles to floats if
+  // they are too big.
+  // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks
+  // The behavior should be covered by IEEE 754, but some projects use this
+  // flag, so work around it.
+  float max_finite = 3.4028234663852885981170418348451692544e+38;
+  // The half-way point between the max-finite and infinity value.
+  // Since infinity has an even significand everything equal or greater than
+  // this value should become infinity.
+  double half_max_finite_infinity =
+      3.40282356779733661637539395458142568448e+38;
+  if (d >= max_finite) {
+    if (d >= half_max_finite_infinity) {
+      return Single::Infinity();
+    } else {
+      return max_finite;
+    }
+  } else {
+    return static_cast<float>(d);
+  }
+}
+
 float Strtof(Vector<const char> buffer, int exponent) {
   char copy_buffer[kMaxSignificantDecimalDigits];
   Vector<const char> trimmed;
@@ -482,7 +507,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
   double double_guess;
   bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
 
-  float float_guess = static_cast<float>(double_guess);
+  float float_guess = SanitizedDoubletof(double_guess);
   if (float_guess == double_guess) {
     // This shortcut triggers for integer values.
     return float_guess;
@@ -505,15 +530,15 @@ float Strtof(Vector<const char> buffer, int exponent) {
   double double_next = Double(double_guess).NextDouble();
   double double_previous = Double(double_guess).PreviousDouble();
 
-  float f1 = static_cast<float>(double_previous);
+  float f1 = SanitizedDoubletof(double_previous);
   float f2 = float_guess;
-  float f3 = static_cast<float>(double_next);
+  float f3 = SanitizedDoubletof(double_next);
   float f4;
   if (is_correct) {
     f4 = f3;
   } else {
     double double_next2 = Double(double_next).NextDouble();
-    f4 = static_cast<float>(double_next2);
+    f4 = SanitizedDoubletof(double_next2);
   }
   (void) f2;  // Mark variable as used.
   ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
@@ -528,7 +553,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
          (f1 == f2 && f2 != f3 && f3 == f4) ||
          (f1 == f2 && f2 == f3 && f3 != f4));
 
-  // guess and next are the two possible canditates (in the same way that
+  // guess and next are the two possible candidates (in the same way that
   // double_guess was the lower candidate for a double-precision guess).
   float guess = f1;
   float next = f4;
diff --git a/double-conversion/strtod.h b/double-conversion/strtod.h
index ed0293b8f54..322651621fb 100644
--- a/double-conversion/strtod.h
+++ b/double-conversion/strtod.h
@@ -28,7 +28,7 @@
 #ifndef DOUBLE_CONVERSION_STRTOD_H_
 #define DOUBLE_CONVERSION_STRTOD_H_
 
-#include "utils.h"
+#include <double-conversion/utils.h>
 
 namespace double_conversion {
 
diff --git a/double-conversion/utils.h b/double-conversion/utils.h
index bfd29c4e38d..9354b5ff64e 100644
--- a/double-conversion/utils.h
+++ b/double-conversion/utils.h
@@ -28,16 +28,15 @@
 #ifndef DOUBLE_CONVERSION_UTILS_H_
 #define DOUBLE_CONVERSION_UTILS_H_
 
-// xxx(kitware)
-// include exports header
+// XXX(kitware): // include exports header
 #include "vtkdoubleconversion_export.h"
 // mangle the double_conversion namespace
-#define double_conversion vtkdoubleconversion
+#define double_conversion vtkdouble_conversion
 
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
 
-#include <assert.h>
+#include <cassert>
 #ifndef ASSERT
 #define ASSERT(condition)         \
     assert(condition);
@@ -73,8 +72,24 @@ inline void abort_noreturn() { abort(); }
 // the output of the division with the expected result. (Inlining must be
 // disabled.)
 // On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
+//
+// For example:
+/*
+// -- in div.c
+double Div_double(double x, double y) { return x / y; }
+
+// -- in main.c
+double Div_double(double x, double y);  // Forward declaration.
+
+int main(int argc, char** argv) {
+  return Div_double(89255.0, 1e22) == 89255e-22;
+}
+*/
+// Run as follows ./main || echo "correct"
+//
+// If it prints "correct" then the architecture should be here, in the "correct" section.
 #if defined(_M_X64) || defined(__x86_64__) || \
-    defined(__ARMEL__) || defined(__avr32__) || \
+    defined(__ARMEL__) || defined(__avr32__) || defined(_M_ARM) || defined(_M_ARM64) || \
     defined(__hppa__) || defined(__ia64__) || \
     defined(__mips__) || \
     defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
@@ -82,10 +97,12 @@ inline void abort_noreturn() { abort(); }
     defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
     defined(__SH4__) || defined(__alpha__) || \
     defined(_MIPS_ARCH_MIPS32R2) || \
-    defined(__AARCH64EL__) || defined(__aarch64__) || \
-    defined(__riscv)
+    defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \
+    defined(__riscv) || \
+    defined(__or1k__)
 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
-#elif defined(__mc68000__)
+#elif defined(__mc68000__) || \
+    defined(__pnacl__) || defined(__native_client__)
 #undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
 #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
 #if defined(_WIN32)
@@ -98,12 +115,6 @@ inline void abort_noreturn() { abort(); }
 #error Target architecture was not detected as supported by Double-Conversion.
 #endif
 
-#if defined(__GNUC__)
-#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
-#else
-#define DOUBLE_CONVERSION_UNUSED
-#endif
-
 #if defined(_WIN32) && !defined(__MINGW32__)
 
 typedef signed char int8_t;
@@ -330,8 +341,12 @@ template <class Dest, class Source>
 inline Dest VTKDOUBLECONVERSION_EXPORT BitCast(const Source& source) {
   // Compile time assertion: sizeof(Dest) == sizeof(Source)
   // A compile error here means your Dest and Source have different sizes.
-  DOUBLE_CONVERSION_UNUSED
-      typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+#if __cplusplus >= 201103L
+  static_assert(sizeof(Dest) == sizeof(Source),
+                "source and destination size mismatch");
+#else
+  typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+#endif
 
   Dest dest;
   memmove(&dest, &source, sizeof(dest));
-- 
GitLab