From 9b9a988964691e9fbe75511d8238fedff9acb332 Mon Sep 17 00:00:00 2001 From: ebasov Date: Wed, 15 Jan 2025 16:20:48 +0300 Subject: [PATCH] Rebuild For MSVSPhere 10 --- .firebird.metadata | 2 +- .gitignore | 2 +- .../0001-Port-to-RISC-V-64-bit-riscv64.patch | 134 - ...ed-code-compatible-with-gcc-6-in-C-1.patch | 29 - SOURCES/autoconf.patch | 24 + SOURCES/btyacc-honour-build-flags.patch | 12 + SOURCES/c++17.patch | 144 + SOURCES/cloop-honour-build-flags.patch | 76 +- SOURCES/examples-honour-build-flags.patch | 28 + SOURCES/firebird-configure-c99.patch | 45 + .../fix_build_on_big_endian_platforms.patch | 36 - SOURCES/no-copy-from-icu.patch | 29 +- SOURCES/noexcept.patch | 664 + SOURCES/ttmath-abseil.4.0.0.patch | 21255 ---------------- SPECS/firebird.spec | 258 +- 15 files changed, 1191 insertions(+), 21547 deletions(-) delete mode 100644 SOURCES/0001-Port-to-RISC-V-64-bit-riscv64.patch delete mode 100644 SOURCES/Make-the-generated-code-compatible-with-gcc-6-in-C-1.patch create mode 100644 SOURCES/autoconf.patch create mode 100644 SOURCES/btyacc-honour-build-flags.patch create mode 100644 SOURCES/c++17.patch create mode 100644 SOURCES/examples-honour-build-flags.patch create mode 100644 SOURCES/firebird-configure-c99.patch delete mode 100644 SOURCES/fix_build_on_big_endian_platforms.patch create mode 100644 SOURCES/noexcept.patch delete mode 100644 SOURCES/ttmath-abseil.4.0.0.patch diff --git a/.firebird.metadata b/.firebird.metadata index 9b2992e..308d8c7 100644 --- a/.firebird.metadata +++ b/.firebird.metadata @@ -1 +1 @@ -21c0a91ca2917110f8ebd64b5e1ca15de2ef92e1 SOURCES/Firebird-4.0.0.2496-0.tar.xz +9cfc22f51f9d655b39f5b215b3e2bf17834f0321 SOURCES/Firebird-4.0.4.3010-0.tar.xz diff --git a/.gitignore b/.gitignore index e969071..eddd821 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/Firebird-4.0.0.2496-0.tar.xz +SOURCES/Firebird-4.0.4.3010-0.tar.xz diff --git a/SOURCES/0001-Port-to-RISC-V-64-bit-riscv64.patch b/SOURCES/0001-Port-to-RISC-V-64-bit-riscv64.patch deleted file mode 100644 index 6fcc1fc..0000000 --- a/SOURCES/0001-Port-to-RISC-V-64-bit-riscv64.patch +++ /dev/null @@ -1,134 +0,0 @@ -diff -urN Firebird-3.0.3.32900-0.old/builds/posix/prefix.linux_riscv64 Firebird-3.0.3.32900-0/builds/posix/prefix.linux_riscv64 ---- Firebird-3.0.3.32900-0.old/builds/posix/prefix.linux_riscv64 1970-01-01 01:00:00.000000000 +0100 -+++ Firebird-3.0.3.32900-0/builds/posix/prefix.linux_riscv64 2018-03-19 08:56:57.254118156 +0000 -@@ -0,0 +1,26 @@ -+# The contents of this file are subject to the Interbase Public -+# License Version 1.0 (the "License"); you may not use this file -+# except in compliance with the License. You may obtain a copy -+# of the License at http://www.Inprise.com/IPL.html -+# -+# Software distributed under the License is distributed on an -+# "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express -+# or implied. See the License for the specific language governing -+# rights and limitations under the License. -+# -+# The Original Code was created by Inprise Corporation -+# and its predecessors. Portions created by Inprise Corporation are -+# Copyright (C) Inprise Corporation. -+# -+# All Rights Reserved. -+# Contributor(s): ______________________________________. -+# Start of file prefix.linux: $(VERSION) $(PLATFORM) -+# -+# Richard W.M. Jones, Red Hat Inc. -+ -+WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof -Wno-narrowing -Wno-unused-local-typedefs -+ -+PROD_FLAGS=-O3 -DLINUX -DRISCV64 -pipe -p -MMD -fPIC -fsigned-char -fmessage-length=0 -+DEV_FLAGS=-ggdb -DLINUX -DRISCV64 -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0 $(WARN_FLAGS) -+ -+CXXFLAGS := $(CXXFLAGS) -std=c++11 -diff -urN Firebird-3.0.3.32900-0.old/configure.ac Firebird-3.0.3.32900-0/configure.ac ---- Firebird-3.0.3.32900-0.old/configure.ac 2018-03-19 08:56:23.222156918 +0000 -+++ Firebird-3.0.3.32900-0/configure.ac 2018-03-19 08:56:57.254118156 +0000 -@@ -251,6 +251,18 @@ - libdir=/usr/lib64 - ;; - -+ riscv64*-*-linux*) -+ MAKEFILE_PREFIX=linux_riscv64 -+ INSTALL_PREFIX=linux -+ PLATFORM=LINUX -+ AC_DEFINE(LINUX, 1, [Define this if OS is Linux]) -+ EDITLINE_FLG=Y -+ SHRLIB_EXT=so -+ STD_EDITLINE=true -+ STD_ICU=true -+ libdir=/usr/lib64 -+ ;; -+ - powerpc64le-*-linux*) - MAKEFILE_PREFIX=linux_powerpc64el - INSTALL_PREFIX=linux -diff -urN Firebird-3.0.3.32900-0.old/src/common/classes/DbImplementation.cpp Firebird-3.0.3.32900-0/src/common/classes/DbImplementation.cpp ---- Firebird-3.0.3.32900-0.old/src/common/classes/DbImplementation.cpp 2018-02-02 11:00:35.000000000 +0000 -+++ Firebird-3.0.3.32900-0/src/common/classes/DbImplementation.cpp 2018-03-19 08:56:57.254118156 +0000 -@@ -49,6 +49,7 @@ - static const UCHAR CpuArm64 = 15; - static const UCHAR CpuPowerPc64el = 16; - static const UCHAR CpuM68k = 17; -+static const UCHAR CpuRiscV64 = 18; - - static const UCHAR OsWindows = 0; - static const UCHAR OsLinux = 1; -@@ -89,7 +90,8 @@ - "Alpha", - "ARM64", - "PowerPC64el", -- "M68k" -+ "M68k", -+ "RiscV64" - }; - - const char* operatingSystem[] = { -@@ -116,22 +118,22 @@ - // This table lists pre-fb3 implementation codes - const UCHAR backwardTable[FB_NELEM(hardware) * FB_NELEM(operatingSystem)] = - { --// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el --/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, --/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85, --/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, --/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, --/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, --/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, --/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, --/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, --/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el RiscV64 -+/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85, 88, -+/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, -+/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - const UCHAR backEndianess[FB_NELEM(hardware)] = - { --// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el M68k -- 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1 -+// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el M68k RiscV64 -+ 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, - }; - - } // anonymous namespace -diff -urN Firebird-3.0.3.32900-0.old/src/common/common.h Firebird-3.0.3.32900-0/src/common/common.h ---- Firebird-3.0.3.32900-0.old/src/common/common.h 2018-03-19 08:56:23.377156741 +0000 -+++ Firebird-3.0.3.32900-0/src/common/common.h 2018-03-19 08:56:57.255118154 +0000 -@@ -135,6 +135,10 @@ - #define FB_CPU CpuArm64 - #endif /* ARM64 */ - -+#ifdef RISCV64 -+#define FB_CPU CpuRiscV64 -+#endif /* RISCV64 */ -+ - #ifdef sparc - #define FB_CPU CpuUltraSparc - #define RISC_ALIGNMENT -diff -urN Firebird-3.0.3.32900-0.old/src/jrd/inf_pub.h Firebird-3.0.3.32900-0/src/jrd/inf_pub.h ---- Firebird-3.0.3.32900-0.old/src/jrd/inf_pub.h 2018-02-02 11:00:36.000000000 +0000 -+++ Firebird-3.0.3.32900-0/src/jrd/inf_pub.h 2018-03-19 08:56:57.255118154 +0000 -@@ -245,7 +245,7 @@ - isc_info_db_impl_linux_ppc64el = 85, - isc_info_db_impl_linux_ppc64 = 86, - isc_info_db_impl_linux_m68k = 87, -- -+ isc_info_db_impl_linux_riscv64 = 88, - - isc_info_db_impl_last_value // Leave this LAST! - }; diff --git a/SOURCES/Make-the-generated-code-compatible-with-gcc-6-in-C-1.patch b/SOURCES/Make-the-generated-code-compatible-with-gcc-6-in-C-1.patch deleted file mode 100644 index 981b09b..0000000 --- a/SOURCES/Make-the-generated-code-compatible-with-gcc-6-in-C-1.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: asfernandes -Date: Sat, 5 Mar 2016 03:39:36 +0000 -Subject: Make the generated code compatible with gcc 6 in C++-14 mode. - (cherry picked from commit 3618aa2171674babf79ef935aa049c40a3db1321) -Patch-mainline: -Git-commit: 3618aa2171674babf79ef935aa049c40a3db1321 -References: bsc#964466 CORE-5099 - ---- - src/gpre/c_cxx.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/gpre/c_cxx.cpp b/src/gpre/c_cxx.cpp -index df175dca9465..bafce8f282bf 100644 ---- a/src/gpre/c_cxx.cpp -+++ b/src/gpre/c_cxx.cpp -@@ -2820,7 +2820,7 @@ static void gen_request(const gpre_req* request) - printa(0, "static %sshort\n isc_%dl = %d;", - (request->req_flags & REQ_extend_dpb) ? "" : CONST_STR, - request->req_ident, request->req_length); -- printa(0, "static %schar\n isc_%d [] = {", CONST_STR, request->req_ident); -+ printa(0, "static %sunsigned char\n isc_%d [] = {", CONST_STR, request->req_ident); - - const TEXT* string_type = "blr"; - if (gpreGlob.sw_raw) --- -2.8.2 - - diff --git a/SOURCES/autoconf.patch b/SOURCES/autoconf.patch new file mode 100644 index 0000000..e058262 --- /dev/null +++ b/SOURCES/autoconf.patch @@ -0,0 +1,24 @@ +From 3fe8f6510de79689a26868e244840b24dcb19567 Mon Sep 17 00:00:00 2001 +From: AlexPeshkoff +Date: Wed, 23 Nov 2022 20:30:03 +0300 +Subject: [PATCH] Fixed #7394: autoconf 2.72 support + +--- + configure.ac | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 75af92e862c..800453d25fa 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -696,8 +696,9 @@ if test "$STD_EDITLINE" = "true"; then + AC_CHECK_LIB(readline, readline, [READLINE=readline EDITLINE_FLG=Y], + [STD_EDITLINE=false + if test "$EDITLINE_FLG" = "Y"; then +- AC_MSG_WARN([[[--with-system-editline specified, not found. Using bundled editline]]])]))) ++ AC_MSG_WARN([[[--with-system-editline specified, not found. Using bundled editline]]]) + fi ++ ]))) + fi + XE_RESTORE_ENV() + diff --git a/SOURCES/btyacc-honour-build-flags.patch b/SOURCES/btyacc-honour-build-flags.patch new file mode 100644 index 0000000..cb9f38c --- /dev/null +++ b/SOURCES/btyacc-honour-build-flags.patch @@ -0,0 +1,12 @@ +--- a/extern/btyacc/Makefile 2022-08-12 15:24:40.846774310 +0200 ++++ a/extern/btyacc/Makefile 2022-08-12 15:26:20.954809720 +0200 +@@ -12,7 +12,7 @@ + # across all of our supported compilers/platforms. + + # Vanilla CFLAGS +-CFLAGS= ++CFLAGS=-fPIC -pie + + # No LDFLAGS + #LDFLAGS= + diff --git a/SOURCES/c++17.patch b/SOURCES/c++17.patch new file mode 100644 index 0000000..76cd4e2 --- /dev/null +++ b/SOURCES/c++17.patch @@ -0,0 +1,144 @@ +From ff49d71b0cdbab75f8a22717c4f88343a5961868 Mon Sep 17 00:00:00 2001 +From: Adriano dos Santos Fernandes +Date: Mon, 31 May 2021 08:55:26 -0300 +Subject: [PATCH] Set POSIX build to use C++17. + +--- + CMakeLists.txt | 4 ++-- + builds/posix/make.defaults | 2 +- + builds/posix/prefix.freebsd_amd64 | 2 +- + configure.ac | 2 +- + examples/extauth/Makefile | 2 +- + examples/interfaces/makefile | 2 +- + extern/icu/android/aarch64/config.sh | 2 +- + extern/icu/android/armv7a/config.sh | 4 ++-- + extern/icu/android/linux/config.sh | 2 +- + 9 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 620fd032af4..5f336efd611 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -206,14 +206,14 @@ if (MINGW) + set(CMAKE_STATIC_LIBRARY_PREFIX) + + add_definitions(-D_WIN32_WINNT=0x0600) +- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -std=c++11") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 -std=c++17") + endif() + + if (UNIX) + set(OS_DIR posix) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") +- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -msse4 -std=c++11") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -msse4 -std=c++17") + + if (NOT CMAKE_CROSSCOMPILING) + set(LIB_readline readline) +diff --git a/builds/posix/make.defaults b/builds/posix/make.defaults +index d96e89053fa..57bbb006865 100755 +--- a/builds/posix/make.defaults ++++ b/builds/posix/make.defaults +@@ -103,7 +103,7 @@ GLOB_OPTIONS:= + #____________________________________________________________________________ + + # Global c++ flags: firebird needs no RTTI, choose build standard +-PLUSPLUS_FLAGS:= -fno-rtti -std=c++11 ++PLUSPLUS_FLAGS:= -fno-rtti -std=c++17 + + # If this is defined then we use special rules useful for developers only + IsDeveloper = @DEVEL_FLG@ +diff --git a/builds/posix/prefix.freebsd_amd64 b/builds/posix/prefix.freebsd_amd64 +index f27567a2715..0736d87e935 100644 +--- a/builds/posix/prefix.freebsd_amd64 ++++ b/builds/posix/prefix.freebsd_amd64 +@@ -26,4 +26,4 @@ DEV_FLAGS=-ggdb -DFREEBSD -DAMD64 -pipe -MMD -p -fPIC -Wall -Wno-non-virtual-dto + # This file must be compiled with SSE4.2 support + %/CRC32C.o: CXXFLAGS += -msse4 + +-CXXFLAGS := $(CXXFLAGS) -std=c++11 ++CXXFLAGS := $(CXXFLAGS) -std=c++17 +diff --git a/configure.ac b/configure.ac +index 9b40be43101..e4a83cf8d3b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -899,7 +899,7 @@ dnl if 64-bit mode, then archive tool, ar, needs -X64 option + fi + + XE_SAVE_ENV() +-CXXFLAGS="$CXXFLAGS -std=c++11" ++CXXFLAGS="$CXXFLAGS -std=c++17" + AC_CACHE_CHECK([whether the C++ compiler understands noexcept], [ac_cv_cxx_noexcept], [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int f(int x) noexcept { return x + 1; }]], [[]])], + [ac_cv_cxx_noexcept=yes], [ac_cv_cxx_noexcept=no])]) +diff --git a/examples/extauth/Makefile b/examples/extauth/Makefile +index 9da7bbd357f..3c8b878d225 100644 +--- a/examples/extauth/Makefile ++++ b/examples/extauth/Makefile +@@ -61,7 +61,7 @@ KEYGEN_objects=$(INTERMED)/keygen.o + TCWRAP_objects=$(INTERMED)/TcWrapper.o + KEY_AUTH_objects=$(INTERMED)/ExtAuth.o + +-CXXFLAGS=-std=c++11 -pthread -I$(ROOT)/include -fPIC $(TOMCRYPT_COMPILE) ++CXXFLAGS=-std=c++17 -pthread -I$(ROOT)/include -fPIC $(TOMCRYPT_COMPILE) + LDFLAGS=-pthread -L$(LIB) -Wl,-rpath,'$$ORIGIN/../lib' $(TOMCRYPT_LINK) + + LINK_LIBS=-lfbclient -ltomcrypt -ltommath +diff --git a/examples/interfaces/makefile b/examples/interfaces/makefile +index 153c3d558dc..b65dba90a7d 100644 +--- a/examples/interfaces/makefile ++++ b/examples/interfaces/makefile +@@ -33,7 +33,7 @@ FBCLIENT = $(FIREBIRD)/lib/libfbclient.so + # General Compiler and linker Defines for Linux + # --------------------------------------------------------------------- + CXX = c++ +-CXXFLAGS= -c -Wall -g3 -std=c++11 -fno-rtti $(INCLUDE) ++CXXFLAGS= -c -Wall -g3 -std=c++17 -fno-rtti $(INCLUDE) + RM = rm -f + + # +diff --git a/extern/icu/android/aarch64/config.sh b/extern/icu/android/aarch64/config.sh +index 51ef623a3c5..f464d930ec2 100755 +--- a/extern/icu/android/aarch64/config.sh ++++ b/extern/icu/android/aarch64/config.sh +@@ -18,7 +18,7 @@ + --enable-dyload \ + --with-cross-build=$CROSS_BUILD_DIR \ + CFLAGS='-Os' \ +- CXXFLAGS='--std=c++11' \ ++ CXXFLAGS='--std=c++17' \ + LDFLAGS='-static-libstdc++' \ + CC=aarch64-linux-android24-clang \ + CXX=aarch64-linux-android24-clang++ \ +diff --git a/extern/icu/android/armv7a/config.sh b/extern/icu/android/armv7a/config.sh +index fe1bd037456..0e458c690e7 100755 +--- a/extern/icu/android/armv7a/config.sh ++++ b/extern/icu/android/armv7a/config.sh +@@ -18,10 +18,10 @@ + --enable-dyload \ + --with-cross-build=$CROSS_BUILD_DIR \ + CFLAGS='-Os -march=armv7-a -mfloat-abi=softfp -mfpu=neon' \ +- CXXFLAGS='--std=c++11 -march=armv7-a -mfloat-abi=softfp -mfpu=neon' \ ++ CXXFLAGS='--std=c++17 -march=armv7-a -mfloat-abi=softfp -mfpu=neon' \ + LDFLAGS='-static-libstdc++ -march=armv7-a -Wl,--fix-cortex-a8' \ + CC=arm-linux-androideabi-clang \ + CXX=arm-linux-androideabi-clang++ \ + AR=arm-linux-androideabi-ar \ + RANLIB=arm-linux-androideabi-ranlib \ +- --with-data-packaging=archive +\ No newline at end of file ++ --with-data-packaging=archive +diff --git a/extern/icu/android/linux/config.sh b/extern/icu/android/linux/config.sh +index a8b56024aae..6e7d9c5f5c8 100755 +--- a/extern/icu/android/linux/config.sh ++++ b/extern/icu/android/linux/config.sh +@@ -1,7 +1,7 @@ + #!/bin/sh + ../source/runConfigureICU Linux --prefix=$PWD/prebuilt \ + CFLAGS="-Os" \ +- CXXFLAGS="--std=c++11" \ ++ CXXFLAGS="--std=c++17" \ + --enable-static \ + --enable-shared=no \ + --enable-extras=no \ diff --git a/SOURCES/cloop-honour-build-flags.patch b/SOURCES/cloop-honour-build-flags.patch index b854300..3ce2e2f 100644 --- a/SOURCES/cloop-honour-build-flags.patch +++ b/SOURCES/cloop-honour-build-flags.patch @@ -1,38 +1,54 @@ -diff --git a/extern/cloop/Makefile b/extern/cloop/Makefile -index 08516c2..1573dc2 100644 +Description: make cloop build honor compiler/linker flags from the environment +Author: Damyan Ivanov +Forwarded: no + --- a/extern/cloop/Makefile +++ b/extern/cloop/Makefile -@@ -6,7 +6,7 @@ TARGET := release - - CC := $(CC) - CXX := $(CXX) --LD := $(CXX) -+LD := $(CXX) $(LDFLAGS) - - SRC_DIR := src - BUILD_DIR := build -@@ -27,8 +27,9 @@ SRCS_CPP := $(foreach sdir,$(SRC_DIRS),$(wildcard $(sdir)/*.cpp)) +@@ -27,8 +27,8 @@ SRCS_CPP := $(foreach sdir,$(SRC_DIRS),$ OBJS_C := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS_C)) OBJS_CPP := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS_CPP)) -C_FLAGS := -ggdb -fPIC -MMD -MP -W -Wall -Wno-unused-parameter --CXX_FLAGS := $(C_FLAGS) -+COMMON_C_FLAGS := -ggdb -fPIC -MMD -MP -W -Wall -Wno-unused-parameter -+C_FLAGS := $(COMMON_C_FLAGS) $(CFLAGS) $(CPPFLAGS) -+CXX_FLAGS := $(COMMON_C_FLAGS) $(CXXFLAGS) $(CPPFLAGS) - FPC_FLAGS := -Mdelphi +-CXX_FLAGS := $(C_FLAGS) -std=c++11 ++C_FLAGS := -ggdb -fPIC -MMD -MP -W -Wall -Wno-unused-parameter $(CPPFLAGS) $(CFLAGS) ++CXX_FLAGS := $(C_FLAGS) $(CXXFLAGS) -std=c++11 + FPC_FLAGS := -Mdelphi -Cg ifeq ($(shell uname),FreeBSD) -diff --git a/extern/btyacc/Makefile b/extern/btyacc/Makefile -index f432965..52d8443 100644 ---- a/extern/btyacc/Makefile -+++ b/extern/btyacc/Makefile -@@ -12,7 +12,7 @@ HDRS = defs.h mstring.h - # across all of our supported compilers/platforms. - - # Vanilla CFLAGS --CFLAGS= -+CFLAGS=-fPIE - - # No LDFLAGS - #LDFLAGS= +@@ -94,7 +94,7 @@ $(BIN_DIR)/cloop: \ + $(OBJ_DIR)/cloop/Main.o \ + | $(BIN_DIR) + +- $(LD) $^ -o $@ $(LIBS) ++ $(LD) $(LDFLAGS) $^ -o $@ $(LIBS) + + $(SRC_DIR)/tests/test1/CalcCApi.h: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl + $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c-header $@ CALC_C_API_H CALC_I +@@ -121,23 +121,23 @@ $(BIN_DIR)/test1-c$(SHRLIB_EXT): \ + $(OBJ_DIR)/tests/test1/CalcCApi.o \ + $(OBJ_DIR)/tests/test1/CTest.o \ + +- $(LD) $^ -shared $(DL_LIB) -o $@ $(LIBS) ++ $(LD) $(LDFLAGS) $^ -shared $(DL_LIB) -o $@ $(LIBS) + + $(BIN_DIR)/test1-c$(EXE_EXT): \ + $(OBJ_DIR)/tests/test1/CalcCApi.o \ + $(OBJ_DIR)/tests/test1/CTest.o \ + +- $(LD) $^ $(DL_LIB) -o $@ $(LIBS) ++ $(LD) $(LDFLAGS) $^ $(DL_LIB) -o $@ $(LIBS) + + $(BIN_DIR)/test1-cpp$(SHRLIB_EXT): \ + $(OBJ_DIR)/tests/test1/CppTest.o \ + +- $(LD) $^ -shared $(DL_LIB) -o $@ $(LIBS) ++ $(LD) $(LDFLAGS) $^ -shared $(DL_LIB) -o $@ $(LIBS) + + $(BIN_DIR)/test1-cpp$(EXE_EXT): \ + $(OBJ_DIR)/tests/test1/CppTest.o \ + +- $(LD) $^ $(DL_LIB) -o $@ $(LIBS) ++ $(LD) $(LDFLAGS) $^ $(DL_LIB) -o $@ $(LIBS) + + $(BIN_DIR)/test1-pascal$(SHRLIB_EXT): \ + $(SRC_DIR)/tests/test1/PascalClasses.pas \ diff --git a/SOURCES/examples-honour-build-flags.patch b/SOURCES/examples-honour-build-flags.patch new file mode 100644 index 0000000..fc7ebd9 --- /dev/null +++ b/SOURCES/examples-honour-build-flags.patch @@ -0,0 +1,28 @@ +diff --git a/builds/posix/Makefile.in.plugins_examples b/builds/posix/Makefile.in.plugins_examples +index 989e80d..344f487 100644 +--- a/builds/posix/Makefile.in.plugins_examples ++++ b/builds/posix/Makefile.in.plugins_examples +@@ -101,7 +101,7 @@ AllObjects += $(CA_Objects) + crypt_app: $(CRYPT_APP) + + $(CRYPT_APP): $(CA_Objects) +- $(EXE_LINK) $(LSB_UNDEF) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) ++ $(EXE_LINK) $(EXE_LINK_OPTIONS) $(LSB_UNDEF) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) + + + include $(ROOT)/gen/make.shared.targets +diff --git a/examples/extauth/Makefile b/examples/extauth/Makefile +index 3c8b878..7de22a8 100644 +--- a/examples/extauth/Makefile ++++ b/examples/extauth/Makefile +@@ -61,8 +61,8 @@ KEYGEN_objects=$(INTERMED)/keygen.o + TCWRAP_objects=$(INTERMED)/TcWrapper.o + KEY_AUTH_objects=$(INTERMED)/ExtAuth.o + +-CXXFLAGS=-std=c++17 -pthread -I$(ROOT)/include -fPIC $(TOMCRYPT_COMPILE) +-LDFLAGS=-pthread -L$(LIB) -Wl,-rpath,'$$ORIGIN/../lib' $(TOMCRYPT_LINK) ++CXXFLAGS+=-std=c++17 -pthread -I$(ROOT)/include -fPIC $(TOMCRYPT_COMPILE) ++LDFLAGS+=-pthread -L$(LIB) -Wl,-rpath,'$$ORIGIN/../lib' $(TOMCRYPT_LINK) + + LINK_LIBS=-lfbclient -ltomcrypt -ltommath + diff --git a/SOURCES/firebird-configure-c99.patch b/SOURCES/firebird-configure-c99.patch new file mode 100644 index 0000000..f24ba4a --- /dev/null +++ b/SOURCES/firebird-configure-c99.patch @@ -0,0 +1,45 @@ +Add missing int return types for main in the configure script. +Implicit ints are a language feature that was removed in C99. + +Submitted upstream: + +diff --git a/configure.ac b/configure.ac +index 05edb5ec9410ff50..0474dc850dfd04bc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1038,7 +1038,7 @@ AC_CHECK_FUNCS(sem_init) + if test "$ac_cv_func_sem_init" = "yes"; then + AC_MSG_CHECKING(for working sem_init()) + AC_RUN_IFELSE([AC_LANG_SOURCE([[#include +- main () { ++ int main () { + sem_t s; + return sem_init(&s,0,0); + } +@@ -1079,7 +1079,7 @@ AC_SYS_LARGEFILE + if test "$ac_cv_sys_file_offset_bits" = "no"; then + AC_MSG_CHECKING(for native large file support) + AC_RUN_IFELSE([AC_LANG_SOURCE([[#include +- main () { ++ int main () { + return !(sizeof(off_t) == 8); + }]])],[ac_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64) + AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)],[]) +@@ -1126,7 +1126,7 @@ dnl EKU: try to determine the alignment of long and double + dnl replaces FB_ALIGNMENT and FB_DOUBLE_ALIGN in src/jrd/common.h + AC_MSG_CHECKING(alignment of long) + AC_RUN_IFELSE([AC_LANG_SOURCE([[#include +-main () { ++int main () { + struct s { + char a; + union { long long x; sem_t y; } b; +@@ -1137,7 +1137,7 @@ AC_MSG_RESULT($ac_cv_c_alignment) + AC_DEFINE_UNQUOTED(FB_ALIGNMENT, $ac_cv_c_alignment, [Alignment of long]) + + AC_MSG_CHECKING(alignment of double) +-AC_RUN_IFELSE([AC_LANG_SOURCE([[main () { ++AC_RUN_IFELSE([AC_LANG_SOURCE([[int main () { + struct s { + char a; + double b; diff --git a/SOURCES/fix_build_on_big_endian_platforms.patch b/SOURCES/fix_build_on_big_endian_platforms.patch deleted file mode 100644 index 73be27b..0000000 --- a/SOURCES/fix_build_on_big_endian_platforms.patch +++ /dev/null @@ -1,36 +0,0 @@ -From cd0682bc55eb01d53278d09edc1e9e2e9bfb9983 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Dan=20Hor=C3=A1k?= -Date: Fri, 11 Jun 2021 12:39:31 +0200 -Subject: [PATCH] fix build on big endian platforms (#6852) - -* fix missing declaration of type_alignments[] for big endian platforms -* add missing definition of lwp for big endian platforms ---- - src/jrd/sort.cpp | 1 + - src/jrd/sort.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/src/jrd/sort.cpp b/src/jrd/sort.cpp -index 37f5f816407..77ca69c2536 100644 ---- a/src/jrd/sort.cpp -+++ b/src/jrd/sort.cpp -@@ -713,6 +713,7 @@ void Sort::diddleKey(UCHAR* record, bool direction, bool duplicateHandling) - for (sort_key_def* key = m_description.begin(), *end = m_description.end(); key < end; key++) - { - UCHAR* p = record + key->getSkdOffset(); -+ SORTP* lwp = (SORTP*) p; - USHORT n = key->getSkdLength(); - USHORT complement = key->skd_flags & SKD_descending; - -diff --git a/src/jrd/sort.h b/src/jrd/sort.h -index 8e23e70ccc5..e3bbbb7779c 100644 ---- a/src/jrd/sort.h -+++ b/src/jrd/sort.h -@@ -27,6 +27,7 @@ - #include "../include/fb_blk.h" - #include "../common/DecFloat.h" - #include "../jrd/TempSpace.h" -+#include "../jrd/align.h" - - namespace Jrd { - diff --git a/SOURCES/no-copy-from-icu.patch b/SOURCES/no-copy-from-icu.patch index 7f84e0b..3dfbd6d 100644 --- a/SOURCES/no-copy-from-icu.patch +++ b/SOURCES/no-copy-from-icu.patch @@ -1,18 +1,6 @@ -diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in -index bb4ceb1..87e75a2 100644 ---- a/builds/posix/Makefile.in -+++ b/builds/posix/Makefile.in -@@ -534,7 +534,7 @@ $(GSTAT): $(GSTAT_Objects) $(COMMON_LIB) - isql: $(ISQL) - - $(ISQL): $(ISQL_Objects) $(COMMON_LIB) -- $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LIBEDITLINE) $(TERMLIB) $(LINK_LIBS) $(call LINK_DARWIN_RPATH,..) -+ $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LIBEDITLINE) $(TERMLIB) $(LINK_LIBS) $(ICU_LIBS) $(call LINK_DARWIN_RPATH,..) - - nbackup: $(NBACKUP) - -diff --git a/src/isql/isql.epp b/src/isql/isql.epp -index 79da1f7..4554252 100644 +Description: Link isql with ICU instead of embedding part of it in the source +Author: Damyan Ivanov + --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -173,34 +173,6 @@ const char* UNKNOWN = "*unknown*"; @@ -50,3 +38,14 @@ index 79da1f7..4554252 100644 // Return the number of characters of a string. static unsigned charLength(SSHORT charset, unsigned len, const char* str) { +--- a/builds/posix/Makefile.in ++++ b/builds/posix/Makefile.in +@@ -543,7 +543,7 @@ $(GSTAT): $(GSTAT_Objects) $(COMMON_LIB + isql: $(ISQL) + + $(ISQL): $(ISQL_Objects) $(COMMON_LIB) +- $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LIBEDITLINE) $(TERMLIB) $(LINK_LIBS) ++ $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LIBEDITLINE) $(TERMLIB) $(LINK_LIBS) $(ICU_LIBS) + + nbackup: $(NBACKUP) + diff --git a/SOURCES/noexcept.patch b/SOURCES/noexcept.patch new file mode 100644 index 0000000..f1a1f48 --- /dev/null +++ b/SOURCES/noexcept.patch @@ -0,0 +1,664 @@ +From a999f35f0fad27798fdc88a3f5cdf2e3e9041594 Mon Sep 17 00:00:00 2001 +From: Adriano dos Santos Fernandes +Date: Mon, 31 May 2021 08:55:26 -0300 +Subject: [PATCH] Replace FB_NOTHROW by noexcept and remove FB_THROW. + +--- + src/common/classes/alloc.cpp | 128 +++++++++++++++++------------------ + src/common/classes/alloc.h | 74 ++++++++------------ + 2 files changed, 94 insertions(+), 108 deletions(-) + +diff --git a/src/common/classes/alloc.cpp b/src/common/classes/alloc.cpp +index 1bd6ad4f09d..ee91ab89df8 100644 +--- a/src/common/classes/alloc.cpp ++++ b/src/common/classes/alloc.cpp +@@ -68,19 +68,19 @@ + #define VALGRIND_FIX_IT // overrides suspicious valgrind behavior + #endif // USE_VALGRIND + +-void* operator new(size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++void* operator new(size_t s ALLOC_PARAMS) + { + return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS); + } +-void* operator new[](size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++void* operator new[](size_t s ALLOC_PARAMS) + { + return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS); + } +-void operator delete(void* mem ALLOC_PARAMS) FB_NOTHROW ++void operator delete(void* mem ALLOC_PARAMS) noexcept + { + MemoryPool::globalFree(mem); + } +-void operator delete[](void* mem ALLOC_PARAMS) FB_NOTHROW ++void operator delete[](void* mem ALLOC_PARAMS) noexcept + { + MemoryPool::globalFree(mem); + } +@@ -109,7 +109,7 @@ static const int GUARD_BYTES = 0; + #endif + + template +-T absVal(T n) FB_NOTHROW ++T absVal(T n) noexcept + { + return n < 0 ? -n : n; + } +@@ -160,7 +160,7 @@ struct FailedBlock + FailedBlock* failedList = NULL; + #endif + +-void corrupt(const char* text) FB_NOTHROW ++void corrupt(const char* text) noexcept + { + #ifdef DEV_BUILD + fprintf(stderr, "%s\n", text); +@@ -377,7 +377,7 @@ class MemHeader + + #ifdef MEM_DEBUG + void print_contents(bool used, FILE* file, bool used_only, +- const char* filter_path, const size_t filter_len) FB_NOTHROW ++ const char* filter_path, const size_t filter_len) noexcept + { + if (used || !used_only) + { +@@ -406,7 +406,7 @@ class MemHeader + } + #endif + +- void validate(MemPool* p, StatInt& vUse) FB_NOTHROW ++ void validate(MemPool* p, StatInt& vUse) noexcept + { + if (p == pool && !isExtent()) + vUse += getSize(); +@@ -461,7 +461,7 @@ class MemBaseHunk + } + + public: +- void validate(MemPool* pool, size_t hdr, StatInt& vMap, StatInt& vUse) FB_NOTHROW ++ void validate(MemPool* pool, size_t hdr, StatInt& vMap, StatInt& vUse) noexcept + { + if (length >= DEFAULT_ALLOCATION) + { +@@ -526,7 +526,7 @@ class MemSmallHunk : public MemBaseHunk + + #ifdef MEM_DEBUG + void print_contents(FILE* file, MemPool* pool, bool used_only, +- const char* filter_path, const size_t filter_len) FB_NOTHROW ++ const char* filter_path, const size_t filter_len) noexcept + { + UCHAR* m = ((UCHAR*) this) + hdrSize(); + fprintf(file, "Small hunk %p: memory=[%p:%p) spaceRemaining=%" SIZEFORMAT " length=%" SIZEFORMAT "\n", +@@ -598,7 +598,7 @@ class MemMediumHunk : public MemBaseHunk + + #ifdef MEM_DEBUG + void print_contents(FILE* file, MemPool* pool, bool used_only, +- const char* filter_path, const size_t filter_len) FB_NOTHROW ++ const char* filter_path, const size_t filter_len) noexcept + { + UCHAR* m = ((UCHAR*) this) + hdrSize(); + fprintf(file, "Medium hunk %p: memory=[%p:%p) spaceRemaining=%" SIZEFORMAT " length=%" SIZEFORMAT "\n", +@@ -630,7 +630,7 @@ class MemBigHunk + + #ifdef MEM_DEBUG + void print_contents(FILE* file, MemPool* pool, bool used_only, +- const char* filter_path, const size_t filter_len) FB_NOTHROW ++ const char* filter_path, const size_t filter_len) noexcept + { + fprintf(file, "Big hunk %p: memory=%p length=%" SIZEFORMAT "\n", + this, block, length); +@@ -1647,7 +1647,7 @@ class FreeObjects + + ~FreeObjects(); + +- FreeObjPtr allocateBlock(MemPool* pool, size_t from, size_t& size) FB_THROW (OOM_EXCEPTION) ++ FreeObjPtr allocateBlock(MemPool* pool, size_t from, size_t& size) + { + size_t full_size = size + (from ? 0 : ListBuilder::MEM_OVERHEAD); + if (full_size > Limits::TOP_LIMIT) +@@ -1696,7 +1696,7 @@ class FreeObjects + + #ifdef MEM_DEBUG + void print_contents(FILE* file, MemPool* pool, bool used_only, +- const char* filter_path, const size_t filter_len) FB_NOTHROW ++ const char* filter_path, const size_t filter_len) noexcept + { + for (Extent* ext = currentExtent; ext; ext = ext->next) + ext->print_contents(file, pool, used_only, filter_path, filter_len); +@@ -1717,7 +1717,7 @@ class FreeObjects + ListBuilder listBuilder; + Extent* currentExtent; + +- MemBlock* newBlock(MemPool* pool, unsigned slot) FB_THROW (OOM_EXCEPTION); ++ MemBlock* newBlock(MemPool* pool, unsigned slot); + }; + + +@@ -1799,26 +1799,26 @@ class MemPool + }; + #endif // VALIDATE_POOL + +- MemBlock* alloc(size_t from, size_t& length, bool flagRedirect) FB_THROW (OOM_EXCEPTION); +- void releaseBlock(MemBlock *block, bool flagDecr) FB_NOTHROW; ++ MemBlock* alloc(size_t from, size_t& length, bool flagRedirect); ++ void releaseBlock(MemBlock *block, bool flagDecr) noexcept; + + public: +- void* allocate(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); +- MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); ++ void* allocate(size_t size ALLOC_PARAMS); ++ MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS); + + private: +- virtual void memoryIsExhausted(void) FB_THROW (OOM_EXCEPTION); +- void* allocRaw(size_t length) FB_THROW (OOM_EXCEPTION); +- static void releaseMemory(void* block, bool flagExtent) FB_NOTHROW; +- static void releaseRaw(bool destroying, void *block, size_t size, bool use_cache = true) FB_NOTHROW; +- void* getExtent(size_t from, size_t& to) FB_THROW (OOM_EXCEPTION); ++ virtual void memoryIsExhausted(void); ++ void* allocRaw(size_t length); ++ static void releaseMemory(void* block, bool flagExtent) noexcept; ++ static void releaseRaw(bool destroying, void *block, size_t size, bool use_cache = true) noexcept; ++ void* getExtent(size_t from, size_t& to); + + public: +- static void releaseExtent(bool destroying, void *block, size_t size, MemPool* pool) FB_NOTHROW; ++ static void releaseExtent(bool destroying, void *block, size_t size, MemPool* pool) noexcept; + + // pass desired size, return actual extent size + template +- void newExtent(size_t& size, Extent** linkedList) FB_THROW (OOM_EXCEPTION); ++ void newExtent(size_t& size, Extent** linkedList); + + private: + #ifdef USE_VALGRIND +@@ -1830,9 +1830,9 @@ class MemPool + + public: + static void deletePool(MemPool* pool); +- static void globalFree(void* block) FB_NOTHROW; ++ static void globalFree(void* block) noexcept; + +- static void deallocate(void* block) FB_NOTHROW; ++ static void deallocate(void* block) noexcept; + bool validate(char* buf, FB_SIZE_T size); + + // Create memory pool instance +@@ -1840,7 +1840,7 @@ class MemPool + + // Set statistics group for pool. Usage counters will be decremented from + // previously set group and added to new +- void setStatsGroup(MemoryStats& stats) FB_NOTHROW; ++ void setStatsGroup(MemoryStats& stats) noexcept; + + // Initialize and finalize global memory pool + static MemPool* init() +@@ -1893,25 +1893,25 @@ class MemPool + } + + // Statistics +- void increment_usage(size_t size) FB_NOTHROW ++ void increment_usage(size_t size) noexcept + { + stats->increment_usage(size); + used_memory += size; + } + +- void decrement_usage(size_t size) FB_NOTHROW ++ void decrement_usage(size_t size) noexcept + { + stats->decrement_usage(size); + used_memory -= size; + } + +- void increment_mapping(size_t size) FB_NOTHROW ++ void increment_mapping(size_t size) noexcept + { + stats->increment_mapping(size); + mapped_memory += size; + } + +- void decrement_mapping(size_t size) FB_NOTHROW ++ void decrement_mapping(size_t size) noexcept + { + stats->decrement_mapping(size); + mapped_memory -= size; +@@ -1919,9 +1919,9 @@ class MemPool + + #ifdef MEM_DEBUG + // Print out pool contents. This is debugging routine +- void print_contents(FILE*, unsigned flags, const char* filter_path) FB_NOTHROW; ++ void print_contents(FILE*, unsigned flags, const char* filter_path) noexcept; + // The same routine, but more easily callable from the debugger +- void print_contents(const char* filename, unsigned flags, const char* filter_path) FB_NOTHROW; ++ void print_contents(const char* filename, unsigned flags, const char* filter_path) noexcept; + + private: + MemPool* next; +@@ -1961,7 +1961,7 @@ void DoubleLinkedList::decrUsage(MemMediumHunk* hunk, MemPool* pool) + + + template +-MemBlock* FreeObjects::newBlock(MemPool* pool, unsigned slot) FB_THROW (OOM_EXCEPTION) ++MemBlock* FreeObjects::newBlock(MemPool* pool, unsigned slot) + { + size_t size = Limits::getSize(slot); + +@@ -2170,7 +2170,7 @@ MemPool::~MemPool(void) + } + + template +-void MemPool::newExtent(size_t& size, Extent** linkedList) FB_THROW(OOM_EXCEPTION) ++void MemPool::newExtent(size_t& size, Extent** linkedList) + { + // No large enough block found. We need to extend the pool + void* memory = NULL; +@@ -2214,7 +2214,7 @@ MemoryPool* MemoryPool::createPool(MemoryPool* parentPool, MemoryStats& stats) + return FB_NEW_POOL(*parentPool) MemoryPool(p); + } + +-void MemPool::setStatsGroup(MemoryStats& newStats) FB_NOTHROW ++void MemPool::setStatsGroup(MemoryStats& newStats) noexcept + { + MutexLockGuard guard(mutex, "MemPool::setStatsGroup"); + +@@ -2230,12 +2230,12 @@ void MemPool::setStatsGroup(MemoryStats& newStats) FB_NOTHROW + stats->increment_usage(sav_used_memory); + } + +-void MemoryPool::setStatsGroup(MemoryStats& newStats) FB_NOTHROW ++void MemoryPool::setStatsGroup(MemoryStats& newStats) noexcept + { + pool->setStatsGroup(newStats); + } + +-MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) FB_THROW (OOM_EXCEPTION) ++MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) + { + MutexEnsureUnlock guard(mutex, "MemPool::alloc"); + guard.enter(); +@@ -2294,7 +2294,7 @@ MemBlock* MemPool::allocate2(size_t from, size_t& size + #ifdef DEBUG_GDS_ALLOC + , const char* fileName, int line + #endif +-) FB_THROW (OOM_EXCEPTION) ++) + { + size_t length = from ? size : ROUNDUP(size + VALGRIND_REDZONE, roundingSize) + GUARD_BYTES; + MemBlock* memory = alloc(from, length, true); +@@ -2324,7 +2324,7 @@ MemBlock* MemPool::allocate2(size_t from, size_t& size + } + + +-void* MemPool::allocate(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++void* MemPool::allocate(size_t size ALLOC_PARAMS) + { + #ifdef VALIDATE_POOL + MutexLockGuard guard(mutex, "MemPool::allocate"); +@@ -2339,7 +2339,7 @@ void* MemPool::allocate(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) + } + + +-void MemPool::releaseMemory(void* object, bool flagExtent) FB_NOTHROW ++void MemPool::releaseMemory(void* object, bool flagExtent) noexcept + { + if (object) + { +@@ -2403,7 +2403,7 @@ void MemPool::releaseMemory(void* object, bool flagExtent) FB_NOTHROW + } + } + +-void MemPool::releaseBlock(MemBlock* block, bool decrUsage) FB_NOTHROW ++void MemPool::releaseBlock(MemBlock* block, bool decrUsage) noexcept + { + if (block->pool != this) + corrupt("bad block released"); +@@ -2464,12 +2464,12 @@ void MemPool::releaseBlock(MemBlock* block, bool decrUsage) FB_NOTHROW + releaseRaw(pool_destroying, hunk, hunk->length, false); + } + +-void MemPool::memoryIsExhausted(void) FB_THROW (OOM_EXCEPTION) ++void MemPool::memoryIsExhausted(void) + { + Firebird::BadAlloc::raise(); + } + +-void* MemPool::allocRaw(size_t size) FB_THROW (OOM_EXCEPTION) ++void* MemPool::allocRaw(size_t size) + { + #ifndef USE_VALGRIND + if (size == DEFAULT_ALLOCATION) +@@ -2549,7 +2549,7 @@ void* MemPool::allocRaw(size_t size) FB_THROW (OOM_EXCEPTION) + } + + +-void* MemPool::getExtent(size_t from, size_t& to) FB_THROW(OOM_EXCEPTION) // pass desired minimum size, return actual extent size ++void* MemPool::getExtent(size_t from, size_t& to) // pass desired minimum size, return actual extent size + { + #ifdef VALIDATE_POOL + MutexLockGuard guard(mutex, "MemPool::getExtent"); +@@ -2560,7 +2560,7 @@ void* MemPool::getExtent(size_t from, size_t& to) FB_THROW(OOM_EXCEPTION) // pa + } + + +-void MemPool::releaseExtent(bool destroying, void* block, size_t size, MemPool* pool) FB_NOTHROW ++void MemPool::releaseExtent(bool destroying, void* block, size_t size, MemPool* pool) noexcept + { + if (size < DEFAULT_ALLOCATION) + releaseMemory(block, true); +@@ -2573,7 +2573,7 @@ void MemPool::releaseExtent(bool destroying, void* block, size_t size, MemPool* + } + + +-void MemPool::releaseRaw(bool destroying, void* block, size_t size, bool use_cache) FB_NOTHROW ++void MemPool::releaseRaw(bool destroying, void* block, size_t size, bool use_cache) noexcept + { + #ifndef USE_VALGRIND + if (use_cache && (size == DEFAULT_ALLOCATION)) +@@ -2666,19 +2666,19 @@ void MemPool::releaseRaw(bool destroying, void* block, size_t size, bool use_cac + } + } + +-void MemPool::globalFree(void* block) FB_NOTHROW ++void MemPool::globalFree(void* block) noexcept + { + deallocate(block); + } + +-void* MemoryPool::calloc(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++void* MemoryPool::calloc(size_t size ALLOC_PARAMS) + { + void* block = allocate(size ALLOC_PASS_ARGS); + memset(block, 0, size); + return block; + } + +-void MemPool::deallocate(void* block) FB_NOTHROW ++void MemPool::deallocate(void* block) noexcept + { + releaseMemory(block, false); + } +@@ -2720,7 +2720,7 @@ bool MemPool::validate(char* buf, FB_SIZE_T size) + } + + #ifdef MEM_DEBUG +-void MemPool::print_contents(const char* filename, unsigned flags, const char* filter_path) FB_NOTHROW ++void MemPool::print_contents(const char* filename, unsigned flags, const char* filter_path) noexcept + { + FILE* out = os_utils::fopen(filename, "w"); + if (!out) +@@ -2731,7 +2731,7 @@ void MemPool::print_contents(const char* filename, unsigned flags, const char* f + } + + // This member function can't be const because there are calls to the mutex. +-void MemPool::print_contents(FILE* file, unsigned flags, const char* filter_path) FB_NOTHROW ++void MemPool::print_contents(FILE* file, unsigned flags, const char* filter_path) noexcept + { + bool used_only = flags & MemoryPool::PRINT_USED_ONLY; + +@@ -2818,7 +2818,7 @@ MemoryPool& AutoStorage::getAutoMemoryPool() + } + + #ifdef LIBC_CALLS_NEW +-void* MemoryPool::globalAlloc(size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++void* MemoryPool::globalAlloc(size_t s ALLOC_PARAMS) + { + if (!defaultMemoryManager) + { +@@ -2831,17 +2831,17 @@ void* MemoryPool::globalAlloc(size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) + } + #endif // LIBC_CALLS_NEW + +-void MemoryPool::globalFree(void* block) FB_NOTHROW ++void MemoryPool::globalFree(void* block) noexcept + { + MemPool::globalFree(block); + } + +-void* MemoryPool::allocate(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++void* MemoryPool::allocate(size_t size ALLOC_PARAMS) + { + return pool->allocate(size ALLOC_PASS_ARGS); + } + +-void MemoryPool::deallocate(void* block) FB_NOTHROW ++void MemoryPool::deallocate(void* block) noexcept + { + pool->deallocate(block); + } +@@ -2870,14 +2870,14 @@ void MemoryPool::deletePool(MemoryPool* pool) + delete pool; + } + +-void MemoryPool::print_contents(FILE* file, unsigned flags, const char* filter_path) FB_NOTHROW ++void MemoryPool::print_contents(FILE* file, unsigned flags, const char* filter_path) noexcept + { + #ifdef MEM_DEBUG + pool->print_contents(file, flags, filter_path); + #endif + } + +-void MemoryPool::print_contents(const char* filename, unsigned flags, const char* filter_path) FB_NOTHROW ++void MemoryPool::print_contents(const char* filename, unsigned flags, const char* filter_path) noexcept + { + #ifdef MEM_DEBUG + pool->print_contents(filename, flags, filter_path); +@@ -2950,21 +2950,21 @@ void AutoStorage::ProbeStack() const + // in a case when we actually need "new" only with file/line information + // this version should be also present as a pair for "delete". + #ifdef DEBUG_GDS_ALLOC +-void* operator new(size_t s) FB_THROW (OOM_EXCEPTION) ++void* operator new(size_t s) + { + return MemoryPool::globalAlloc(s ALLOC_ARGS); + } +-void* operator new[](size_t s) FB_THROW (OOM_EXCEPTION) ++void* operator new[](size_t s) + { + return MemoryPool::globalAlloc(s ALLOC_ARGS); + } + +-void operator delete(void* mem) FB_NOTHROW ++void operator delete(void* mem) noexcept + { + MemoryPool::globalFree(mem); + } + +-void operator delete[](void* mem) FB_NOTHROW ++void operator delete[](void* mem) noexcept + { + MemoryPool::globalFree(mem); + } +diff --git a/src/common/classes/alloc.h b/src/common/classes/alloc.h +index 65f9afbb8a9..44d9e0ea462 100644 +--- a/src/common/classes/alloc.h ++++ b/src/common/classes/alloc.h +@@ -58,20 +58,6 @@ + + #include + +-#define OOM_EXCEPTION std::bad_alloc +- +-#if __cplusplus >= 201103L +-#define FB_NO_THROW_SPECIFIER +-#endif +- +-#ifdef FB_NO_THROW_SPECIFIER +-#define FB_THROW(x) +-#define FB_NOTHROW noexcept +-#else +-#define FB_THROW(x) throw(x) +-#define FB_NOTHROW throw() +-#endif +- + #ifdef DEBUG_GDS_ALLOC + #define FB_NEW new(__FILE__, __LINE__) + #define FB_NEW_POOL(pool) new(pool, __FILE__, __LINE__) +@@ -106,10 +92,10 @@ class MemoryStats + ~MemoryStats() + {} + +- size_t getCurrentUsage() const FB_NOTHROW { return mst_usage.value(); } +- size_t getMaximumUsage() const FB_NOTHROW { return mst_max_usage; } +- size_t getCurrentMapping() const FB_NOTHROW { return mst_mapped.value(); } +- size_t getMaximumMapping() const FB_NOTHROW { return mst_max_mapped; } ++ size_t getCurrentUsage() const noexcept { return mst_usage.value(); } ++ size_t getMaximumUsage() const noexcept { return mst_max_usage; } ++ size_t getCurrentMapping() const noexcept { return mst_mapped.value(); } ++ size_t getMaximumMapping() const noexcept { return mst_max_mapped; } + + private: + // Forbid copying/assignment +@@ -131,7 +117,7 @@ class MemoryStats + size_t mst_max_mapped; + + // These methods are thread-safe due to usage of atomic counters only +- void increment_usage(size_t size) FB_NOTHROW ++ void increment_usage(size_t size) noexcept + { + for (MemoryStats* statistics = this; statistics; statistics = statistics->mst_parent) + { +@@ -141,7 +127,7 @@ class MemoryStats + } + } + +- void decrement_usage(size_t size) FB_NOTHROW ++ void decrement_usage(size_t size) noexcept + { + for (MemoryStats* statistics = this; statistics; statistics = statistics->mst_parent) + { +@@ -149,7 +135,7 @@ class MemoryStats + } + } + +- void increment_mapping(size_t size) FB_NOTHROW ++ void increment_mapping(size_t size) noexcept + { + for (MemoryStats* statistics = this; statistics; statistics = statistics->mst_parent) + { +@@ -159,7 +145,7 @@ class MemoryStats + } + } + +- void decrement_mapping(size_t size) FB_NOTHROW ++ void decrement_mapping(size_t size) noexcept + { + for (MemoryStats* statistics = this; statistics; statistics = statistics->mst_parent) + { +@@ -205,21 +191,21 @@ class MemoryPool + #define ALLOC_PASS_ARGS + #endif // DEBUG_GDS_ALLOC + +- void* calloc(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); ++ void* calloc(size_t size ALLOC_PARAMS); + + #ifdef LIBC_CALLS_NEW +- static void* globalAlloc(size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); ++ static void* globalAlloc(size_t s ALLOC_PARAMS); + #else +- static void* globalAlloc(size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++ static void* globalAlloc(size_t s ALLOC_PARAMS) + { + return defaultMemoryManager->allocate(s ALLOC_PASS_ARGS); + } + #endif // LIBC_CALLS_NEW + +- void* allocate(size_t size ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); ++ void* allocate(size_t size ALLOC_PARAMS); + +- static void globalFree(void* mem) FB_NOTHROW; +- void deallocate(void* mem) FB_NOTHROW; ++ static void globalFree(void* mem) noexcept; ++ void deallocate(void* mem) noexcept; + + // Set context pool for current thread of execution + static MemoryPool* setContextPool(MemoryPool* newPool); +@@ -229,7 +215,7 @@ class MemoryPool + + // Set statistics group for pool. Usage counters will be decremented from + // previously set group and added to new +- void setStatsGroup(MemoryStats& stats) FB_NOTHROW; ++ void setStatsGroup(MemoryStats& stats) noexcept; + + // Initialize and finalize global memory pool + static void init(); +@@ -241,9 +227,9 @@ class MemoryPool + // Print out pool contents. This is debugging routine + static const unsigned PRINT_USED_ONLY = 0x01; + static const unsigned PRINT_RECURSIVE = 0x02; +- void print_contents(FILE*, unsigned flags = 0, const char* filter_path = 0) FB_NOTHROW; ++ void print_contents(FILE*, unsigned flags = 0, const char* filter_path = 0) noexcept; + // The same routine, but more easily callable from the debugger +- void print_contents(const char* filename, unsigned flags = 0, const char* filter_path = 0) FB_NOTHROW; ++ void print_contents(const char* filename, unsigned flags = 0, const char* filter_path = 0) noexcept; + + public: + struct Finalizer +@@ -298,7 +284,7 @@ class MemoryPool + + } // namespace Firebird + +-static inline Firebird::MemoryPool* getDefaultMemoryPool() FB_NOTHROW ++static inline Firebird::MemoryPool* getDefaultMemoryPool() noexcept + { + fb_assert(Firebird::MemoryPool::defaultMemoryManager); + return Firebird::MemoryPool::defaultMemoryManager; +@@ -355,36 +341,36 @@ class SubsystemContextPoolHolder : public ContextPoolHolder + using Firebird::MemoryPool; + + // operators new and delete +-extern void* operator new(size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); +-extern void* operator new[](size_t s ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION); +-extern void operator delete(void* mem ALLOC_PARAMS) FB_NOTHROW; +-extern void operator delete[](void* mem ALLOC_PARAMS) FB_NOTHROW; ++extern void* operator new(size_t s ALLOC_PARAMS); ++extern void* operator new[](size_t s ALLOC_PARAMS); ++extern void operator delete(void* mem ALLOC_PARAMS) noexcept; ++extern void operator delete[](void* mem ALLOC_PARAMS) noexcept; + + +-inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) + { + return pool.allocate(s ALLOC_PASS_ARGS); + } +-inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) FB_THROW (OOM_EXCEPTION) ++inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) + { + return pool.allocate(s ALLOC_PASS_ARGS); + } + +-inline void operator delete(void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) FB_NOTHROW ++inline void operator delete(void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) noexcept + { + MemoryPool::globalFree(mem); + } +-inline void operator delete[](void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) FB_NOTHROW ++inline void operator delete[](void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) noexcept + { + MemoryPool::globalFree(mem); + } + + #if __cplusplus >= 201402L +-inline void operator delete(void* mem, std::size_t s ALLOC_PARAMS) FB_NOTHROW ++inline void operator delete(void* mem, std::size_t s ALLOC_PARAMS) noexcept + { + MemoryPool::globalFree(mem); + } +-inline void operator delete[](void* mem, std::size_t s ALLOC_PARAMS) FB_NOTHROW ++inline void operator delete[](void* mem, std::size_t s ALLOC_PARAMS) noexcept + { + MemoryPool::globalFree(mem); + } +@@ -392,8 +378,8 @@ inline void operator delete[](void* mem, std::size_t s ALLOC_PARAMS) FB_NOTHROW + + #ifdef DEBUG_GDS_ALLOC + +-extern void operator delete(void* mem) FB_NOTHROW; +-extern void operator delete[](void* mem) FB_NOTHROW; ++extern void operator delete(void* mem) noexcept; ++extern void operator delete[](void* mem) noexcept; + + #endif // DEBUG_GDS_ALLOC + diff --git a/SOURCES/ttmath-abseil.4.0.0.patch b/SOURCES/ttmath-abseil.4.0.0.patch deleted file mode 100644 index ee98e95..0000000 --- a/SOURCES/ttmath-abseil.4.0.0.patch +++ /dev/null @@ -1,21255 +0,0 @@ -diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in -index bb4ceb12fb..dcd2b173ae 100644 ---- a/builds/posix/Makefile.in -+++ b/builds/posix/Makefile.in -@@ -170,6 +170,9 @@ external: - $(MAKE) -C $(ROOT)/extern/decNumber - ln -sf $(ROOT)/extern/decNumber/libdecFloat.a $(LIB) - -+ $(MAKE) -C $(ROOT)/extern/int128/absl/numeric -+ ln -sf $(ROOT)/extern/int128/absl/numeric/libi128.a $(LIB) -+ - CXXFLAGS="-O3 -g -fPIC" $(MAKE) -C $(ROOT)/extern/re2 - ln -sf $(ROOT)/extern/re2/obj/libre2.a $(LIB) - -@@ -328,6 +331,8 @@ cross2: - $(MAKE) re2 - $(MAKE) -C $(ROOT)/extern/decNumber - ln -sf $(ROOT)/extern/decNumber/libdecFloat$(CROSS).a $(LIB) -+ $(MAKE) -C $(ROOT)/extern/int128/absl/numeric -+ ln -sf $(ROOT)/extern/int128/absl/numeric/libi128$(CROSS).a $(LIB) - $(MAKE) yvalve - $(MAKE) engine - $(MAKE) fbintl -@@ -738,12 +743,12 @@ install install-embedded silent_install package packages dist: - # - .PHONY: clean clean_objects clean_dependancies clean_extern_objects clean_build \ - clean_gpre_gen clean_icu clean_dbs clean_examples clean_makefiles \ -- clean_editline clean_all clean_decfloat clean_vers clean_misc -+ clean_editline clean_all clean_decfloat clean_int128 clean_vers clean_misc - - - clean: clean_objects clean_dependancies clean_extern_objects clean_build \ - clean_yacc_gen clean_gpre_gen clean_dbs clean_examples clean_tommath \ -- clean_tomcrypt clean_decfloat clean_vers clean_misc -+ clean_tomcrypt clean_decfloat clean_int128 clean_vers clean_misc - - clean_vers: - $(RM) *.vers -@@ -797,6 +802,9 @@ clean_tomcrypt: - clean_decfloat: - -$(MAKE) -C $(ROOT)/extern/decNumber clean - -+clean_int128: -+ -$(MAKE) -C $(ROOT)/extern/int128/absl/numeric clean -+ - clean_objects: - $(RM) `find $(TMP_ROOT)/ -type f -name '*.o' -print` - $(RM) `find $(TMP_ROOT)/ -type f -name '*.a' -print` -diff --git a/builds/posix/make.android.arm64 b/builds/posix/make.android.arm64 -index 79fbb90c2e..ff0d8d85ff 100644 ---- a/builds/posix/make.android.arm64 -+++ b/builds/posix/make.android.arm64 -@@ -41,7 +41,7 @@ DEV_FLAGS=$(COMMON_FLAGS) $(WARN_FLAGS) - CROSS_CONFIG=android.arm64 - - LDFLAGS += --sysroot=$(CROSS_SYSROOT) -static-libstdc++ --DroidLibs := -lm -ldl $(DECLIB) $(RE2LIB) -+DroidLibs := -lm -ldl $(DECLIB) $(RE2LIB) $(I128LIB) - - LINK_LIBS = $(DroidLibs) - STATICLINK_LIBS = $(DroidLibs) -diff --git a/builds/posix/make.android.arme b/builds/posix/make.android.arme -index c7233d0191..b6ae33587d 100644 ---- a/builds/posix/make.android.arme -+++ b/builds/posix/make.android.arme -@@ -40,7 +40,7 @@ DEV_FLAGS=$(COMMON_FLAGS) $(WARN_FLAGS) - CROSS_CONFIG=android.arme - - LDFLAGS += --sysroot=$(CROSS_PLATFORM) -static-libstdc++ --DroidLibs := -lm -ldl $(DECLIB) $(RE2LIB) -+DroidLibs := -lm -ldl $(DECLIB) $(RE2LIB) $(I128LIB) - UDR_SUPPORT_LIBS := - - LINK_LIBS = $(DroidLibs) -diff --git a/builds/posix/make.defaults b/builds/posix/make.defaults -index 6dfd3ab118..9421947a59 100755 ---- a/builds/posix/make.defaults -+++ b/builds/posix/make.defaults -@@ -134,6 +134,7 @@ CAS_OPTIONS=@CAS_OPTIONS@ - # multiple-precision integer library - MATHLIB=@MATHLIB@ - DECLIB=-ldecFloat$(CROSS) -+I128LIB=-li128$(CROSS) - RE2LIB=-lre2 - - # crypt library -@@ -190,8 +191,8 @@ endif - STATICLIB_LINK = $(AR) crus - STATICEXE_LINK = $(CXX) $(GLOB_OPTIONS) $(CXXFLAGS) -static-libstdc++ - --LINK_LIBS = @LIBS@ $(DECLIB) $(RE2LIB) --SO_LINK_LIBS = @LIBS@ $(DECLIB) $(RE2LIB) -+LINK_LIBS = @LIBS@ $(DECLIB) $(RE2LIB) $(I128LIB) -+SO_LINK_LIBS = @LIBS@ $(DECLIB) $(RE2LIB) $(I128LIB) - - # Default extensions - -diff --git a/builds/posix/make.rules b/builds/posix/make.rules -index 3afd891141..e725b93067 100644 ---- a/builds/posix/make.rules -+++ b/builds/posix/make.rules -@@ -32,7 +32,7 @@ - - - # Please don't use compiler/platform specific flags here - nmcc 02-Nov-2002 --WFLAGS =-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include -I$(ROOT)/extern/re2 $(CPPFLAGS) $(LTCSOURCE) -+WFLAGS =-I$(SRC_ROOT)/include/gen -I$(SRC_ROOT)/include -I$(ROOT)/extern/re2 -I$(ROOT)/extern/int128 $(CPPFLAGS) $(LTCSOURCE) - - ifeq ($(TOMMATH_BUILD_FLG),Y) - WFLAGS += -I$(TOMMATH_INC) -diff --git a/builds/posix/prefix.linux_s390x b/builds/posix/prefix.linux_s390x -index ccb2340123..cb0992bb41 100644 ---- a/builds/posix/prefix.linux_s390x -+++ b/builds/posix/prefix.linux_s390x -@@ -18,10 +18,10 @@ - # - # 2 Oct 2002, Nickolay Samofatov - Major cleanup - --COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -pipe -MMD -fPIC -fmessage-length=0 -fsigned-char -+COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -pipe -MMD -fPIC -fmessage-length=0 -fsigned-char -Wno-invalid-offsetof - OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer -fno-builtin - WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-non-virtual-dtor - - PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS) --DEV_FLAGS=-DUSE_VALGRIND -p $(COMMON_FLAGS) $(WARN_FLAGS) --#DEV_FLAGS=-p $(COMMON_FLAGS) $(WARN_FLAGS) -+#DEV_FLAGS=-DUSE_VALGRIND -p $(COMMON_FLAGS) $(WARN_FLAGS) -+DEV_FLAGS=-p $(COMMON_FLAGS) $(WARN_FLAGS) -diff --git a/extern/int128/absl/base/attributes.h b/extern/int128/absl/base/attributes.h -new file mode 100644 -index 0000000000..52139556f2 ---- /dev/null -+++ b/extern/int128/absl/base/attributes.h -@@ -0,0 +1,721 @@ -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// This header file defines macros for declaring attributes for functions, -+// types, and variables. -+// -+// These macros are used within Abseil and allow the compiler to optimize, where -+// applicable, certain function calls. -+// -+// Most macros here are exposing GCC or Clang features, and are stubbed out for -+// other compilers. -+// -+// GCC attributes documentation: -+// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html -+// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html -+// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html -+// -+// Most attributes in this file are already supported by GCC 4.7. However, some -+// of them are not supported in older version of Clang. Thus, we check -+// `__has_attribute()` first. If the check fails, we check if we are on GCC and -+// assume the attribute exists on GCC (which is verified on GCC 4.7). -+ -+#ifndef ABSL_BASE_ATTRIBUTES_H_ -+#define ABSL_BASE_ATTRIBUTES_H_ -+ -+#include "absl/base/config.h" -+ -+// ABSL_HAVE_ATTRIBUTE -+// -+// A function-like feature checking macro that is a wrapper around -+// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a -+// nonzero constant integer if the attribute is supported or 0 if not. -+// -+// It evaluates to zero if `__has_attribute` is not defined by the compiler. -+// -+// GCC: https://gcc.gnu.org/gcc-5/changes.html -+// Clang: https://clang.llvm.org/docs/LanguageExtensions.html -+#ifdef __has_attribute -+#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) -+#else -+#define ABSL_HAVE_ATTRIBUTE(x) 0 -+#endif -+ -+// ABSL_HAVE_CPP_ATTRIBUTE -+// -+// A function-like feature checking macro that accepts C++11 style attributes. -+// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 -+// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't -+// find `__has_cpp_attribute`, will evaluate to 0. -+#if defined(__cplusplus) && defined(__has_cpp_attribute) -+// NOTE: requiring __cplusplus above should not be necessary, but -+// works around https://bugs.llvm.org/show_bug.cgi?id=23435. -+#define ABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -+#else -+#define ABSL_HAVE_CPP_ATTRIBUTE(x) 0 -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Function Attributes -+// ----------------------------------------------------------------------------- -+// -+// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html -+// Clang: https://clang.llvm.org/docs/AttributeReference.html -+ -+// ABSL_PRINTF_ATTRIBUTE -+// ABSL_SCANF_ATTRIBUTE -+// -+// Tells the compiler to perform `printf` format string checking if the -+// compiler supports it; see the 'format' attribute in -+// . -+// -+// Note: As the GCC manual states, "[s]ince non-static C++ methods -+// have an implicit 'this' argument, the arguments of such methods -+// should be counted from two, not one." -+#if ABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ -+ __attribute__((__format__(__printf__, string_index, first_to_check))) -+#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ -+ __attribute__((__format__(__scanf__, string_index, first_to_check))) -+#else -+#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) -+#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) -+#endif -+ -+// ABSL_ATTRIBUTE_ALWAYS_INLINE -+// ABSL_ATTRIBUTE_NOINLINE -+// -+// Forces functions to either inline or not inline. Introduced in gcc 3.1. -+#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ -+ (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) -+#define ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 -+#else -+#define ABSL_ATTRIBUTE_ALWAYS_INLINE -+#endif -+ -+#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) -+#define ABSL_HAVE_ATTRIBUTE_NOINLINE 1 -+#else -+#define ABSL_ATTRIBUTE_NOINLINE -+#endif -+ -+// ABSL_ATTRIBUTE_NO_TAIL_CALL -+// -+// Prevents the compiler from optimizing away stack frames for functions which -+// end in a call to another function. -+#if ABSL_HAVE_ATTRIBUTE(disable_tail_calls) -+#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 -+#define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) -+#elif defined(__GNUC__) && !defined(__clang__) && !defined(__e2k__) -+#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 -+#define ABSL_ATTRIBUTE_NO_TAIL_CALL \ -+ __attribute__((optimize("no-optimize-sibling-calls"))) -+#else -+#define ABSL_ATTRIBUTE_NO_TAIL_CALL -+#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 -+#endif -+ -+// ABSL_ATTRIBUTE_WEAK -+// -+// Tags a function as weak for the purposes of compilation and linking. -+// Weak attributes did not work properly in LLVM's Windows backend before -+// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 -+// for further information. -+// The MinGW compiler doesn't complain about the weak attribute until the link -+// step, presumably because Windows doesn't use ELF binaries. -+#if (ABSL_HAVE_ATTRIBUTE(weak) || \ -+ (defined(__GNUC__) && !defined(__clang__))) && \ -+ (!defined(_WIN32) || __clang_major__ < 9) && !defined(__MINGW32__) -+#undef ABSL_ATTRIBUTE_WEAK -+#define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) -+#define ABSL_HAVE_ATTRIBUTE_WEAK 1 -+#else -+#define ABSL_ATTRIBUTE_WEAK -+#define ABSL_HAVE_ATTRIBUTE_WEAK 0 -+#endif -+ -+// ABSL_ATTRIBUTE_NONNULL -+// -+// Tells the compiler either (a) that a particular function parameter -+// should be a non-null pointer, or (b) that all pointer arguments should -+// be non-null. -+// -+// Note: As the GCC manual states, "[s]ince non-static C++ methods -+// have an implicit 'this' argument, the arguments of such methods -+// should be counted from two, not one." -+// -+// Args are indexed starting at 1. -+// -+// For non-static class member functions, the implicit `this` argument -+// is arg 1, and the first explicit argument is arg 2. For static class member -+// functions, there is no implicit `this`, and the first explicit argument is -+// arg 1. -+// -+// Example: -+// -+// /* arg_a cannot be null, but arg_b can */ -+// void Function(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(1); -+// -+// class C { -+// /* arg_a cannot be null, but arg_b can */ -+// void Method(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(2); -+// -+// /* arg_a cannot be null, but arg_b can */ -+// static void StaticMethod(void* arg_a, void* arg_b) -+// ABSL_ATTRIBUTE_NONNULL(1); -+// }; -+// -+// If no arguments are provided, then all pointer arguments should be non-null. -+// -+// /* No pointer arguments may be null. */ -+// void Function(void* arg_a, void* arg_b, int arg_c) ABSL_ATTRIBUTE_NONNULL(); -+// -+// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but -+// ABSL_ATTRIBUTE_NONNULL does not. -+#if ABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) -+#else -+#define ABSL_ATTRIBUTE_NONNULL(...) -+#endif -+ -+// ABSL_ATTRIBUTE_NORETURN -+// -+// Tells the compiler that a given function never returns. -+#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) -+#elif defined(_MSC_VER) -+#define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn) -+#else -+#define ABSL_ATTRIBUTE_NORETURN -+#endif -+ -+// ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS -+// -+// Tells the AddressSanitizer (or other memory testing tools) to ignore a given -+// function. Useful for cases when a function reads random locations on stack, -+// calls _exit from a cloned subprocess, deliberately accesses buffer -+// out of bounds or does other scary things with memory. -+// NOTE: GCC supports AddressSanitizer(asan) since 4.8. -+// https://gcc.gnu.org/gcc-4.8/changes.html -+#if ABSL_HAVE_ATTRIBUTE(no_sanitize_address) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) -+#else -+#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS -+#endif -+ -+// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY -+// -+// Tells the MemorySanitizer to relax the handling of a given function. All "Use -+// of uninitialized value" warnings from such functions will be suppressed, and -+// all values loaded from memory will be considered fully initialized. This -+// attribute is similar to the ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute -+// above, but deals with initialized-ness rather than addressability issues. -+// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. -+#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) -+#else -+#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY -+#endif -+ -+// ABSL_ATTRIBUTE_NO_SANITIZE_THREAD -+// -+// Tells the ThreadSanitizer to not instrument a given function. -+// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. -+// https://gcc.gnu.org/gcc-4.8/changes.html -+#if ABSL_HAVE_ATTRIBUTE(no_sanitize_thread) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -+#else -+#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD -+#endif -+ -+// ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED -+// -+// Tells the UndefinedSanitizer to ignore a given function. Useful for cases -+// where certain behavior (eg. division by zero) is being used intentionally. -+// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. -+// https://gcc.gnu.org/gcc-4.9/changes.html -+#if ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ -+ __attribute__((no_sanitize_undefined)) -+#elif ABSL_HAVE_ATTRIBUTE(no_sanitize) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ -+ __attribute__((no_sanitize("undefined"))) -+#else -+#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED -+#endif -+ -+// ABSL_ATTRIBUTE_NO_SANITIZE_CFI -+// -+// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. -+// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. -+#if ABSL_HAVE_ATTRIBUTE(no_sanitize) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) -+#else -+#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI -+#endif -+ -+// ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK -+// -+// Tells the SafeStack to not instrument a given function. -+// See https://clang.llvm.org/docs/SafeStack.html for details. -+#if ABSL_HAVE_ATTRIBUTE(no_sanitize) -+#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \ -+ __attribute__((no_sanitize("safe-stack"))) -+#else -+#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK -+#endif -+ -+// ABSL_ATTRIBUTE_RETURNS_NONNULL -+// -+// Tells the compiler that a particular function never returns a null pointer. -+#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) -+#define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) -+#else -+#define ABSL_ATTRIBUTE_RETURNS_NONNULL -+#endif -+ -+// ABSL_HAVE_ATTRIBUTE_SECTION -+// -+// Indicates whether labeled sections are supported. Weak symbol support is -+// a prerequisite. Labeled sections are not supported on Darwin/iOS. -+#ifdef ABSL_HAVE_ATTRIBUTE_SECTION -+#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set -+#elif (ABSL_HAVE_ATTRIBUTE(section) || \ -+ (defined(__GNUC__) && !defined(__clang__))) && \ -+ !defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK -+#define ABSL_HAVE_ATTRIBUTE_SECTION 1 -+ -+// ABSL_ATTRIBUTE_SECTION -+// -+// Tells the compiler/linker to put a given function into a section and define -+// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. -+// This functionality is supported by GNU linker. Any function annotated with -+// `ABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into -+// whatever section its caller is placed into. -+// -+#ifndef ABSL_ATTRIBUTE_SECTION -+#define ABSL_ATTRIBUTE_SECTION(name) \ -+ __attribute__((section(#name))) __attribute__((noinline)) -+#endif -+ -+ -+// ABSL_ATTRIBUTE_SECTION_VARIABLE -+// -+// Tells the compiler/linker to put a given variable into a section and define -+// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. -+// This functionality is supported by GNU linker. -+#ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE -+#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) -+#endif -+ -+// ABSL_DECLARE_ATTRIBUTE_SECTION_VARS -+// -+// A weak section declaration to be used as a global declaration -+// for ABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link -+// even without functions with ABSL_ATTRIBUTE_SECTION(name). -+// ABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's -+// a no-op on ELF but not on Mach-O. -+// -+#ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS -+#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ -+ extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \ -+ extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK -+#endif -+#ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS -+#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) -+#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) -+#endif -+ -+// ABSL_ATTRIBUTE_SECTION_START -+// -+// Returns `void*` pointers to start/end of a section of code with -+// functions having ABSL_ATTRIBUTE_SECTION(name). -+// Returns 0 if no such functions exist. -+// One must ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and -+// link. -+// -+#define ABSL_ATTRIBUTE_SECTION_START(name) \ -+ (reinterpret_cast(__start_##name)) -+#define ABSL_ATTRIBUTE_SECTION_STOP(name) \ -+ (reinterpret_cast(__stop_##name)) -+ -+#else // !ABSL_HAVE_ATTRIBUTE_SECTION -+ -+#define ABSL_HAVE_ATTRIBUTE_SECTION 0 -+ -+// provide dummy definitions -+#define ABSL_ATTRIBUTE_SECTION(name) -+#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) -+#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) -+#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) -+#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) -+#define ABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) -+#define ABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) -+ -+#endif // ABSL_ATTRIBUTE_SECTION -+ -+// ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -+// -+// Support for aligning the stack on 32-bit x86. -+#if ABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ -+ (defined(__GNUC__) && !defined(__clang__)) -+#if defined(__i386__) -+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ -+ __attribute__((force_align_arg_pointer)) -+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -+#elif defined(__x86_64__) -+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) -+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -+#else // !__i386__ && !__x86_64 -+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -+#endif // __i386__ -+#else -+#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -+#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -+#endif -+ -+// ABSL_MUST_USE_RESULT -+// -+// Tells the compiler to warn about unused results. -+// -+// When annotating a function, it must appear as the first part of the -+// declaration or definition. The compiler will warn if the return value from -+// such a function is unused: -+// -+// ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); -+// AllocateSprocket(); // Triggers a warning. -+// -+// When annotating a class, it is equivalent to annotating every function which -+// returns an instance. -+// -+// class ABSL_MUST_USE_RESULT Sprocket {}; -+// Sprocket(); // Triggers a warning. -+// -+// Sprocket MakeSprocket(); -+// MakeSprocket(); // Triggers a warning. -+// -+// Note that references and pointers are not instances: -+// -+// Sprocket* SprocketPointer(); -+// SprocketPointer(); // Does *not* trigger a warning. -+// -+// ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result -+// warning. For that, warn_unused_result is used only for clang but not for gcc. -+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 -+// -+// Note: past advice was to place the macro after the argument list. -+#if ABSL_HAVE_ATTRIBUTE(nodiscard) -+#define ABSL_MUST_USE_RESULT [[nodiscard]] -+#elif defined(__clang__) && ABSL_HAVE_ATTRIBUTE(warn_unused_result) -+#define ABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) -+#else -+#define ABSL_MUST_USE_RESULT -+#endif -+ -+// ABSL_ATTRIBUTE_HOT, ABSL_ATTRIBUTE_COLD -+// -+// Tells GCC that a function is hot or cold. GCC can use this information to -+// improve static analysis, i.e. a conditional branch to a cold function -+// is likely to be not-taken. -+// This annotation is used for function declarations. -+// -+// Example: -+// -+// int foo() ABSL_ATTRIBUTE_HOT; -+#if ABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_HOT __attribute__((hot)) -+#else -+#define ABSL_ATTRIBUTE_HOT -+#endif -+ -+#if ABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_COLD __attribute__((cold)) -+#else -+#define ABSL_ATTRIBUTE_COLD -+#endif -+ -+// ABSL_XRAY_ALWAYS_INSTRUMENT, ABSL_XRAY_NEVER_INSTRUMENT, ABSL_XRAY_LOG_ARGS -+// -+// We define the ABSL_XRAY_ALWAYS_INSTRUMENT and ABSL_XRAY_NEVER_INSTRUMENT -+// macro used as an attribute to mark functions that must always or never be -+// instrumented by XRay. Currently, this is only supported in Clang/LLVM. -+// -+// For reference on the LLVM XRay instrumentation, see -+// http://llvm.org/docs/XRay.html. -+// -+// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration -+// will always get the XRay instrumentation sleds. These sleds may introduce -+// some binary size and runtime overhead and must be used sparingly. -+// -+// These attributes only take effect when the following conditions are met: -+// -+// * The file/target is built in at least C++11 mode, with a Clang compiler -+// that supports XRay attributes. -+// * The file/target is built with the -fxray-instrument flag set for the -+// Clang/LLVM compiler. -+// * The function is defined in the translation unit (the compiler honors the -+// attribute in either the definition or the declaration, and must match). -+// -+// There are cases when, even when building with XRay instrumentation, users -+// might want to control specifically which functions are instrumented for a -+// particular build using special-case lists provided to the compiler. These -+// special case lists are provided to Clang via the -+// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The -+// attributes in source take precedence over these special-case lists. -+// -+// To disable the XRay attributes at build-time, users may define -+// ABSL_NO_XRAY_ATTRIBUTES. Do NOT define ABSL_NO_XRAY_ATTRIBUTES on specific -+// packages/targets, as this may lead to conflicting definitions of functions at -+// link-time. -+// -+// XRay isn't currently supported on Android: -+// https://github.com/android/ndk/issues/368 -+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ -+ !defined(ABSL_NO_XRAY_ATTRIBUTES) && !defined(__ANDROID__) -+#define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] -+#define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] -+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) -+#define ABSL_XRAY_LOG_ARGS(N) \ -+ [[clang::xray_always_instrument, clang::xray_log_args(N)]] -+#else -+#define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] -+#endif -+#else -+#define ABSL_XRAY_ALWAYS_INSTRUMENT -+#define ABSL_XRAY_NEVER_INSTRUMENT -+#define ABSL_XRAY_LOG_ARGS(N) -+#endif -+ -+// ABSL_ATTRIBUTE_REINITIALIZES -+// -+// Indicates that a member function reinitializes the entire object to a known -+// state, independent of the previous state of the object. -+// -+// The clang-tidy check bugprone-use-after-move allows member functions marked -+// with this attribute to be called on objects that have been moved from; -+// without the attribute, this would result in a use-after-move warning. -+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes) -+#define ABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] -+#else -+#define ABSL_ATTRIBUTE_REINITIALIZES -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Variable Attributes -+// ----------------------------------------------------------------------------- -+ -+// ABSL_ATTRIBUTE_UNUSED -+// -+// Prevents the compiler from complaining about variables that appear unused. -+// -+// For code or headers that are assured to only build with C++17 and up, prefer -+// just using the standard '[[maybe_unused]]' directly over this macro. -+// -+// Due to differences in positioning requirements between the old, compiler -+// specific __attribute__ syntax and the now standard [[maybe_unused]], this -+// macro does not attempt to take advantage of '[[maybe_unused]]'. -+#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) -+#undef ABSL_ATTRIBUTE_UNUSED -+#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) -+#else -+#define ABSL_ATTRIBUTE_UNUSED -+#endif -+ -+// ABSL_ATTRIBUTE_INITIAL_EXEC -+// -+// Tells the compiler to use "initial-exec" mode for a thread-local variable. -+// See http://people.redhat.com/drepper/tls.pdf for the gory details. -+#if ABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) -+#else -+#define ABSL_ATTRIBUTE_INITIAL_EXEC -+#endif -+ -+// ABSL_ATTRIBUTE_PACKED -+// -+// Instructs the compiler not to use natural alignment for a tagged data -+// structure, but instead to reduce its alignment to 1. This attribute can -+// either be applied to members of a structure or to a structure in its -+// entirety. Applying this attribute (judiciously) to a structure in its -+// entirety to optimize the memory footprint of very commonly-used structs is -+// fine. Do not apply this attribute to a structure in its entirety if the -+// purpose is to control the offsets of the members in the structure. Instead, -+// apply this attribute only to structure members that need it. -+// -+// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the -+// natural alignment of structure members not annotated is preserved. Aligned -+// member accesses are faster than non-aligned member accesses even if the -+// targeted microprocessor supports non-aligned accesses. -+#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) -+#else -+#define ABSL_ATTRIBUTE_PACKED -+#endif -+ -+// ABSL_ATTRIBUTE_FUNC_ALIGN -+// -+// Tells the compiler to align the function start at least to certain -+// alignment boundary -+#if ABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) -+#else -+#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) -+#endif -+ -+// ABSL_FALLTHROUGH_INTENDED -+// -+// Annotates implicit fall-through between switch labels, allowing a case to -+// indicate intentional fallthrough and turn off warnings about any lack of a -+// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by -+// a semicolon and can be used in most places where `break` can, provided that -+// no statements exist between it and the next switch label. -+// -+// Example: -+// -+// switch (x) { -+// case 40: -+// case 41: -+// if (truth_is_out_there) { -+// ++x; -+// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations -+// // in comments -+// } else { -+// return x; -+// } -+// case 42: -+// ... -+// -+// Notes: When supported, GCC and Clang can issue a warning on switch labels -+// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See -+// clang documentation on language extensions for details: -+// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough -+// -+// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has -+// no effect on diagnostics. In any case this macro has no effect on runtime -+// behavior and performance of code. -+ -+#ifdef ABSL_FALLTHROUGH_INTENDED -+#error "ABSL_FALLTHROUGH_INTENDED should not be defined." -+#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) -+#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] -+#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) -+#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] -+#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) -+#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -+#else -+#define ABSL_FALLTHROUGH_INTENDED \ -+ do { \ -+ } while (0) -+#endif -+ -+// ABSL_DEPRECATED() -+// -+// Marks a deprecated class, struct, enum, function, method and variable -+// declarations. The macro argument is used as a custom diagnostic message (e.g. -+// suggestion of a better alternative). -+// -+// Examples: -+// -+// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; -+// -+// ABSL_DEPRECATED("Use Baz() instead") void Bar() {...} -+// -+// template -+// ABSL_DEPRECATED("Use DoThat() instead") -+// void DoThis(); -+// -+// Every usage of a deprecated entity will trigger a warning when compiled with -+// clang's `-Wdeprecated-declarations` option. This option is turned off by -+// default, but the warnings will be reported by clang-tidy. -+#if defined(__clang__) && defined(__cplusplus) && __cplusplus >= 201103L -+#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) -+#endif -+ -+#ifndef ABSL_DEPRECATED -+#define ABSL_DEPRECATED(message) -+#endif -+ -+// ABSL_CONST_INIT -+// -+// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will -+// not compile (on supported platforms) unless the variable has a constant -+// initializer. This is useful for variables with static and thread storage -+// duration, because it guarantees that they will not suffer from the so-called -+// "static init order fiasco". Prefer to put this attribute on the most visible -+// declaration of the variable, if there's more than one, because code that -+// accesses the variable can then use the attribute for optimization. -+// -+// Example: -+// -+// class MyClass { -+// public: -+// ABSL_CONST_INIT static MyType my_var; -+// }; -+// -+// MyType MyClass::my_var = MakeMyType(...); -+// -+// Note that this attribute is redundant if the variable is declared constexpr. -+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) -+#define ABSL_CONST_INIT [[clang::require_constant_initialization]] -+#else -+#define ABSL_CONST_INIT -+#endif // ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) -+ -+// ABSL_ATTRIBUTE_PURE_FUNCTION -+// -+// ABSL_ATTRIBUTE_PURE_FUNCTION is used to annotate declarations of "pure" -+// functions. A function is pure if its return value is only a function of its -+// arguments. The pure attribute prohibits a function from modifying the state -+// of the program that is observable by means other than inspecting the -+// function's return value. Declaring such functions with the pure attribute -+// allows the compiler to avoid emitting some calls in repeated invocations of -+// the function with the same argument values. -+// -+// Example: -+// -+// ABSL_ATTRIBUTE_PURE_FUNCTION int64_t ToInt64Milliseconds(Duration d); -+#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::pure) -+#define ABSL_ATTRIBUTE_PURE_FUNCTION [[gnu::pure]] -+#elif ABSL_HAVE_ATTRIBUTE(pure) -+#define ABSL_ATTRIBUTE_PURE_FUNCTION __attribute__((pure)) -+#else -+#define ABSL_ATTRIBUTE_PURE_FUNCTION -+#endif -+ -+// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function -+// parameter or implicit object parameter is retained by the return value of the -+// annotated function (or, for a parameter of a constructor, in the value of the -+// constructed object). This attribute causes warnings to be produced if a -+// temporary object does not live long enough. -+// -+// When applied to a reference parameter, the referenced object is assumed to be -+// retained by the return value of the function. When applied to a non-reference -+// parameter (for example, a pointer or a class type), all temporaries -+// referenced by the parameter are assumed to be retained by the return value of -+// the function. -+// -+// See also the upstream documentation: -+// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound -+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) -+#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] -+#elif ABSL_HAVE_ATTRIBUTE(lifetimebound) -+#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) -+#else -+#define ABSL_ATTRIBUTE_LIFETIME_BOUND -+#endif -+ -+#endif // ABSL_BASE_ATTRIBUTES_H_ -diff --git a/extern/int128/absl/base/config.h b/extern/int128/absl/base/config.h -new file mode 100644 -index 0000000000..a6e7c86a0c ---- /dev/null -+++ b/extern/int128/absl/base/config.h -@@ -0,0 +1,745 @@ -+// -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: config.h -+// ----------------------------------------------------------------------------- -+// -+// This header file defines a set of macros for checking the presence of -+// important compiler and platform features. Such macros can be used to -+// produce portable code by parameterizing compilation based on the presence or -+// lack of a given feature. -+// -+// We define a "feature" as some interface we wish to program to: for example, -+// a library function or system call. A value of `1` indicates support for -+// that feature; any other value indicates the feature support is undefined. -+// -+// Example: -+// -+// Suppose a programmer wants to write a program that uses the 'mmap()' system -+// call. The Abseil macro for that feature (`ABSL_HAVE_MMAP`) allows you to -+// selectively include the `mmap.h` header and bracket code using that feature -+// in the macro: -+// -+// #include "absl/base/config.h" -+// -+// #ifdef ABSL_HAVE_MMAP -+// #include "sys/mman.h" -+// #endif //ABSL_HAVE_MMAP -+// -+// ... -+// #ifdef ABSL_HAVE_MMAP -+// void *ptr = mmap(...); -+// ... -+// #endif // ABSL_HAVE_MMAP -+ -+#ifndef ABSL_BASE_CONFIG_H_ -+#define ABSL_BASE_CONFIG_H_ -+ -+// Included for the __GLIBC__ macro (or similar macros on other systems). -+#include -+ -+#ifdef __cplusplus -+// Included for __GLIBCXX__, _LIBCPP_VERSION -+#include -+#endif // __cplusplus -+ -+#if defined(__APPLE__) -+// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED, -+// __IPHONE_8_0. -+#include -+#include -+#endif -+ -+#include "absl/base/options.h" -+#include "absl/base/policy_checks.h" -+ -+// Helper macro to convert a CPP variable to a string literal. -+#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x -+#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) -+ -+// ----------------------------------------------------------------------------- -+// Abseil namespace annotations -+// ----------------------------------------------------------------------------- -+ -+// ABSL_NAMESPACE_BEGIN/ABSL_NAMESPACE_END -+// -+// An annotation placed at the beginning/end of each `namespace absl` scope. -+// This is used to inject an inline namespace. -+// -+// The proper way to write Abseil code in the `absl` namespace is: -+// -+// namespace absl { -+// ABSL_NAMESPACE_BEGIN -+// -+// void Foo(); // absl::Foo(). -+// -+// ABSL_NAMESPACE_END -+// } // namespace absl -+// -+// Users of Abseil should not use these macros, because users of Abseil should -+// not write `namespace absl {` in their own code for any reason. (Abseil does -+// not support forward declarations of its own types, nor does it support -+// user-provided specialization of Abseil templates. Code that violates these -+// rules may be broken without warning.) -+#if !defined(ABSL_OPTION_USE_INLINE_NAMESPACE) || \ -+ !defined(ABSL_OPTION_INLINE_NAMESPACE_NAME) -+#error options.h is misconfigured. -+#endif -+ -+// Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor "" -+#if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1 -+ -+#define ABSL_INTERNAL_INLINE_NAMESPACE_STR \ -+ ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) -+ -+static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0', -+ "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " -+ "not be empty."); -+static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || -+ ABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' || -+ ABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' || -+ ABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' || -+ ABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0', -+ "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " -+ "be changed to a new, unique identifier name."); -+ -+#endif -+ -+#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 -+#define ABSL_NAMESPACE_BEGIN -+#define ABSL_NAMESPACE_END -+#define ABSL_INTERNAL_C_SYMBOL(x) x -+#elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1 -+#define ABSL_NAMESPACE_BEGIN \ -+ inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME { -+#define ABSL_NAMESPACE_END } -+#define ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) x##_##v -+#define ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, v) \ -+ ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) -+#define ABSL_INTERNAL_C_SYMBOL(x) \ -+ ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, ABSL_OPTION_INLINE_NAMESPACE_NAME) -+#else -+#error options.h is misconfigured. -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Compiler Feature Checks -+// ----------------------------------------------------------------------------- -+ -+// ABSL_HAVE_BUILTIN() -+// -+// Checks whether the compiler supports a Clang Feature Checking Macro, and if -+// so, checks whether it supports the provided builtin function "x" where x -+// is one of the functions noted in -+// https://clang.llvm.org/docs/LanguageExtensions.html -+// -+// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. -+// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html -+#ifdef __has_builtin -+#define ABSL_HAVE_BUILTIN(x) __has_builtin(x) -+#else -+#define ABSL_HAVE_BUILTIN(x) 0 -+#endif -+ -+#if defined(__is_identifier) -+#define ABSL_INTERNAL_HAS_KEYWORD(x) !(__is_identifier(x)) -+#else -+#define ABSL_INTERNAL_HAS_KEYWORD(x) 0 -+#endif -+ -+#ifdef __has_feature -+#define ABSL_HAVE_FEATURE(f) __has_feature(f) -+#else -+#define ABSL_HAVE_FEATURE(f) 0 -+#endif -+ -+// Portable check for GCC minimum version: -+// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html -+#if defined(__GNUC__) && defined(__GNUC_MINOR__) -+#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) \ -+ (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) -+#else -+#define ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(x, y) 0 -+#endif -+ -+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) -+#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) \ -+ (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) -+#else -+#define ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(x, y) 0 -+#endif -+ -+// ABSL_HAVE_TLS is defined to 1 when __thread should be supported. -+// We assume __thread is supported on Linux when compiled with Clang or compiled -+// against libstdc++ with _GLIBCXX_HAVE_TLS defined. -+#ifdef ABSL_HAVE_TLS -+#error ABSL_HAVE_TLS cannot be directly set -+#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) -+#define ABSL_HAVE_TLS 1 -+#endif -+ -+// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -+// -+// Checks whether `std::is_trivially_destructible` is supported. -+// -+// Notes: All supported compilers using libc++ support this feature, as does -+// gcc >= 4.8.1 using libstdc++, and Visual Studio. -+#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -+#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set -+#elif defined(_LIBCPP_VERSION) || defined(_MSC_VER) || \ -+ (!defined(__clang__) && defined(__GLIBCXX__) && \ -+ ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(4, 8)) -+#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 -+#endif -+ -+// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -+// -+// Checks whether `std::is_trivially_default_constructible` and -+// `std::is_trivially_copy_constructible` are supported. -+ -+// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE -+// -+// Checks whether `std::is_trivially_copy_assignable` is supported. -+ -+// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with -+// either libc++ or libstdc++, and Visual Studio (but not NVCC). -+#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) -+#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set -+#elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) -+#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set -+#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ -+ (!defined(__clang__) && ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(7, 4) && \ -+ (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ -+ (defined(_MSC_VER) && !defined(__NVCC__)) -+#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 -+#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 -+#endif -+ -+// ABSL_HAVE_SOURCE_LOCATION_CURRENT -+// -+// Indicates whether `absl::SourceLocation::current()` will return useful -+// information in some contexts. -+#ifndef ABSL_HAVE_SOURCE_LOCATION_CURRENT -+#if ABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ -+ ABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) -+#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 -+#elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) -+#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 -+#endif -+#endif -+ -+// ABSL_HAVE_THREAD_LOCAL -+// -+// Checks whether C++11's `thread_local` storage duration specifier is -+// supported. -+#ifdef ABSL_HAVE_THREAD_LOCAL -+#error ABSL_HAVE_THREAD_LOCAL cannot be directly set -+#elif defined(__APPLE__) -+// Notes: -+// * Xcode's clang did not support `thread_local` until version 8, and -+// even then not for all iOS < 9.0. -+// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator -+// targeting iOS 9.x. -+// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time -+// making ABSL_HAVE_FEATURE unreliable there. -+// -+#if ABSL_HAVE_FEATURE(cxx_thread_local) && \ -+ !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) -+#define ABSL_HAVE_THREAD_LOCAL 1 -+#endif -+#else // !defined(__APPLE__) -+#define ABSL_HAVE_THREAD_LOCAL 1 -+#endif -+ -+// There are platforms for which TLS should not be used even though the compiler -+// makes it seem like it's supported (Android NDK < r12b for example). -+// This is primarily because of linker problems and toolchain misconfiguration: -+// Abseil does not intend to support this indefinitely. Currently, the newest -+// toolchain that we intend to support that requires this behavior is the -+// r11 NDK - allowing for a 5 year support window on that means this option -+// is likely to be removed around June of 2021. -+// TLS isn't supported until NDK r12b per -+// https://developer.android.com/ndk/downloads/revision_history.html -+// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in -+// . For NDK < r16, users should define these macros, -+// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. -+#if defined(__ANDROID__) && defined(__clang__) -+#if __has_include() -+#include -+#endif // __has_include() -+#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \ -+ defined(__NDK_MINOR__) && \ -+ ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) -+#undef ABSL_HAVE_TLS -+#undef ABSL_HAVE_THREAD_LOCAL -+#endif -+#endif // defined(__ANDROID__) && defined(__clang__) -+ -+// ABSL_HAVE_INTRINSIC_INT128 -+// -+// Checks whether the __int128 compiler extension for a 128-bit integral type is -+// supported. -+// -+// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is -+// supported, but we avoid using it in certain cases: -+// * On Clang: -+// * Building using Clang for Windows, where the Clang runtime library has -+// 128-bit support only on LP64 architectures, but Windows is LLP64. -+// * On Nvidia's nvcc: -+// * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions -+// actually support __int128. -+ -+/* Unfortunately FB does not support alignment requirements (16) in ODS -+ -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+#error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set -+#elif defined(__SIZEOF_INT128__) -+#if (defined(__clang__) && !defined(_WIN32)) || \ -+ (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \ -+ (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) -+#define ABSL_HAVE_INTRINSIC_INT128 1 -+#elif defined(__CUDACC__) -+// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a -+// string explaining that it has been removed starting with CUDA 9. We use -+// nested #ifs because there is no short-circuiting in the preprocessor. -+// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined. -+#if __CUDACC_VER__ >= 70000 -+#define ABSL_HAVE_INTRINSIC_INT128 1 -+#endif // __CUDACC_VER__ >= 70000 -+#endif // defined(__CUDACC__) -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ */ -+#undef ABSL_HAVE_INTRINSIC_INT128 -+ -+// ABSL_HAVE_EXCEPTIONS -+// -+// Checks whether the compiler both supports and enables exceptions. Many -+// compilers support a "no exceptions" mode that disables exceptions. -+// -+// Generally, when ABSL_HAVE_EXCEPTIONS is not defined: -+// -+// * Code using `throw` and `try` may not compile. -+// * The `noexcept` specifier will still compile and behave as normal. -+// * The `noexcept` operator may still return `false`. -+// -+// For further details, consult the compiler's documentation. -+#ifdef ABSL_HAVE_EXCEPTIONS -+#error ABSL_HAVE_EXCEPTIONS cannot be directly set. -+#elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6) -+// Clang >= 3.6 -+#if ABSL_HAVE_FEATURE(cxx_exceptions) -+#define ABSL_HAVE_EXCEPTIONS 1 -+#endif // ABSL_HAVE_FEATURE(cxx_exceptions) -+#elif defined(__clang__) -+// Clang < 3.6 -+// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro -+#if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) -+#define ABSL_HAVE_EXCEPTIONS 1 -+#endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) -+// Handle remaining special cases and default to exceptions being supported. -+#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ -+ !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \ -+ !defined(__cpp_exceptions)) && \ -+ !(defined(_MSC_VER) && !defined(_CPPUNWIND)) -+#define ABSL_HAVE_EXCEPTIONS 1 -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Platform Feature Checks -+// ----------------------------------------------------------------------------- -+ -+// Currently supported operating systems and associated preprocessor -+// symbols: -+// -+// Linux and Linux-derived __linux__ -+// Android __ANDROID__ (implies __linux__) -+// Linux (non-Android) __linux__ && !__ANDROID__ -+// Darwin (macOS and iOS) __APPLE__ -+// Akaros (http://akaros.org) __ros__ -+// Windows _WIN32 -+// NaCL __native_client__ -+// AsmJS __asmjs__ -+// WebAssembly __wasm__ -+// Fuchsia __Fuchsia__ -+// -+// Note that since Android defines both __ANDROID__ and __linux__, one -+// may probe for either Linux or Android by simply testing for __linux__. -+ -+// ABSL_HAVE_MMAP -+// -+// Checks whether the platform has an mmap(2) implementation as defined in -+// POSIX.1-2001. -+#ifdef ABSL_HAVE_MMAP -+#error ABSL_HAVE_MMAP cannot be directly set -+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ -+ defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ -+ defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \ -+ defined(__ASYLO__) || defined(__myriad2__) -+#define ABSL_HAVE_MMAP 1 -+#endif -+ -+// ABSL_HAVE_PTHREAD_GETSCHEDPARAM -+// -+// Checks whether the platform implements the pthread_(get|set)schedparam(3) -+// functions as defined in POSIX.1-2001. -+#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM -+#error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set -+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ -+ defined(__ros__) -+#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 -+#endif -+ -+// ABSL_HAVE_SCHED_GETCPU -+// -+// Checks whether sched_getcpu is available. -+#ifdef ABSL_HAVE_SCHED_GETCPU -+#error ABSL_HAVE_SCHED_GETCPU cannot be directly set -+#elif defined(__linux__) -+#define ABSL_HAVE_SCHED_GETCPU 1 -+#endif -+ -+// ABSL_HAVE_SCHED_YIELD -+// -+// Checks whether the platform implements sched_yield(2) as defined in -+// POSIX.1-2001. -+#ifdef ABSL_HAVE_SCHED_YIELD -+#error ABSL_HAVE_SCHED_YIELD cannot be directly set -+#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) -+#define ABSL_HAVE_SCHED_YIELD 1 -+#endif -+ -+// ABSL_HAVE_SEMAPHORE_H -+// -+// Checks whether the platform supports the header and sem_init(3) -+// family of functions as standardized in POSIX.1-2001. -+// -+// Note: While Apple provides for both iOS and macOS, it is -+// explicitly deprecated and will cause build failures if enabled for those -+// platforms. We side-step the issue by not defining it here for Apple -+// platforms. -+#ifdef ABSL_HAVE_SEMAPHORE_H -+#error ABSL_HAVE_SEMAPHORE_H cannot be directly set -+#elif defined(__linux__) || defined(__ros__) -+#define ABSL_HAVE_SEMAPHORE_H 1 -+#endif -+ -+// ABSL_HAVE_ALARM -+// -+// Checks whether the platform supports the header and alarm(2) -+// function as standardized in POSIX.1-2001. -+#ifdef ABSL_HAVE_ALARM -+#error ABSL_HAVE_ALARM cannot be directly set -+#elif defined(__GOOGLE_GRTE_VERSION__) -+// feature tests for Google's GRTE -+#define ABSL_HAVE_ALARM 1 -+#elif defined(__GLIBC__) -+// feature test for glibc -+#define ABSL_HAVE_ALARM 1 -+#elif defined(_MSC_VER) -+// feature tests for Microsoft's library -+#elif defined(__MINGW32__) -+// mingw32 doesn't provide alarm(2): -+// https://osdn.net/projects/mingw/scm/git/mingw-org-wsl/blobs/5.2-trunk/mingwrt/include/unistd.h -+// mingw-w64 provides a no-op implementation: -+// https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/misc/alarm.c -+#elif defined(__EMSCRIPTEN__) -+// emscripten doesn't support signals -+#elif defined(__Fuchsia__) -+// Signals don't exist on fuchsia. -+#elif defined(__native_client__) -+#else -+// other standard libraries -+#define ABSL_HAVE_ALARM 1 -+#endif -+ -+// ABSL_IS_LITTLE_ENDIAN -+// ABSL_IS_BIG_ENDIAN -+// -+// Checks the endianness of the platform. -+// -+// Notes: uses the built in endian macros provided by GCC (since 4.6) and -+// Clang (since 3.2); see -+// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html. -+// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error. -+#if defined(ABSL_IS_BIG_ENDIAN) -+#error "ABSL_IS_BIG_ENDIAN cannot be directly set." -+#endif -+#if defined(ABSL_IS_LITTLE_ENDIAN) -+#error "ABSL_IS_LITTLE_ENDIAN cannot be directly set." -+#endif -+ -+#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ -+ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -+#define ABSL_IS_LITTLE_ENDIAN 1 -+#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ -+ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+#define ABSL_IS_BIG_ENDIAN 1 -+#elif defined(_WIN32) -+#define ABSL_IS_LITTLE_ENDIAN 1 -+#else -+#error "absl endian detection needs to be set up for your compiler" -+#endif -+ -+// macOS 10.13 and iOS 10.11 don't let you use , , or -+// even though the headers exist and are publicly noted to work. See -+// https://github.com/abseil/abseil-cpp/issues/207 and -+// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes -+// libc++ spells out the availability requirements in the file -+// llvm-project/libcxx/include/__config via the #define -+// _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS. -+#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ -+ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ -+ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400) || \ -+ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ -+ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ -+ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ -+ __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \ -+ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ -+ __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000)) -+#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 -+#else -+#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 -+#endif -+ -+// ABSL_HAVE_STD_ANY -+// -+// Checks whether C++17 std::any is available by checking whether exists. -+#ifdef ABSL_HAVE_STD_ANY -+#error "ABSL_HAVE_STD_ANY cannot be directly set." -+#endif -+ -+#ifdef __has_include -+#if __has_include() && defined(__cplusplus) && __cplusplus >= 201703L && \ -+ !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE -+#define ABSL_HAVE_STD_ANY 1 -+#endif -+#endif -+ -+// ABSL_HAVE_STD_OPTIONAL -+// -+// Checks whether C++17 std::optional is available. -+#ifdef ABSL_HAVE_STD_OPTIONAL -+#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set." -+#endif -+ -+#ifdef __has_include -+#if __has_include() && defined(__cplusplus) && \ -+ __cplusplus >= 201703L && !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE -+#define ABSL_HAVE_STD_OPTIONAL 1 -+#endif -+#endif -+ -+// ABSL_HAVE_STD_VARIANT -+// -+// Checks whether C++17 std::variant is available. -+#ifdef ABSL_HAVE_STD_VARIANT -+#error "ABSL_HAVE_STD_VARIANT cannot be directly set." -+#endif -+ -+#ifdef __has_include -+#if __has_include() && defined(__cplusplus) && \ -+ __cplusplus >= 201703L && !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE -+#define ABSL_HAVE_STD_VARIANT 1 -+#endif -+#endif -+ -+// ABSL_HAVE_STD_STRING_VIEW -+// -+// Checks whether C++17 std::string_view is available. -+#ifdef ABSL_HAVE_STD_STRING_VIEW -+#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set." -+#endif -+ -+#ifdef __has_include -+#if __has_include() && defined(__cplusplus) && \ -+ __cplusplus >= 201703L -+#define ABSL_HAVE_STD_STRING_VIEW 1 -+#endif -+#endif -+ -+// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than -+// the support for , , , . So we use -+// _MSC_VER to check whether we have VS 2017 RTM (when , , -+// , is implemented) or higher. Also, `__cplusplus` is -+// not correctly set by MSVC, so we use `_MSVC_LANG` to check the language -+// version. -+// TODO(zhangxy): fix tests before enabling aliasing for `std::any`. -+#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ -+ ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || \ -+ (defined(__cplusplus) && __cplusplus > 201402)) -+// #define ABSL_HAVE_STD_ANY 1 -+#define ABSL_HAVE_STD_OPTIONAL 1 -+#define ABSL_HAVE_STD_VARIANT 1 -+#define ABSL_HAVE_STD_STRING_VIEW 1 -+#endif -+ -+// ABSL_USES_STD_ANY -+// -+// Indicates whether absl::any is an alias for std::any. -+#if !defined(ABSL_OPTION_USE_STD_ANY) -+#error options.h is misconfigured. -+#elif ABSL_OPTION_USE_STD_ANY == 0 || \ -+ (ABSL_OPTION_USE_STD_ANY == 2 && !defined(ABSL_HAVE_STD_ANY)) -+#undef ABSL_USES_STD_ANY -+#elif ABSL_OPTION_USE_STD_ANY == 1 || \ -+ (ABSL_OPTION_USE_STD_ANY == 2 && defined(ABSL_HAVE_STD_ANY)) -+#define ABSL_USES_STD_ANY 1 -+#else -+#error options.h is misconfigured. -+#endif -+ -+// ABSL_USES_STD_OPTIONAL -+// -+// Indicates whether absl::optional is an alias for std::optional. -+#if !defined(ABSL_OPTION_USE_STD_OPTIONAL) -+#error options.h is misconfigured. -+#elif ABSL_OPTION_USE_STD_OPTIONAL == 0 || \ -+ (ABSL_OPTION_USE_STD_OPTIONAL == 2 && !defined(ABSL_HAVE_STD_OPTIONAL)) -+#undef ABSL_USES_STD_OPTIONAL -+#elif ABSL_OPTION_USE_STD_OPTIONAL == 1 || \ -+ (ABSL_OPTION_USE_STD_OPTIONAL == 2 && defined(ABSL_HAVE_STD_OPTIONAL)) -+#define ABSL_USES_STD_OPTIONAL 1 -+#else -+#error options.h is misconfigured. -+#endif -+ -+// ABSL_USES_STD_VARIANT -+// -+// Indicates whether absl::variant is an alias for std::variant. -+#if !defined(ABSL_OPTION_USE_STD_VARIANT) -+#error options.h is misconfigured. -+#elif ABSL_OPTION_USE_STD_VARIANT == 0 || \ -+ (ABSL_OPTION_USE_STD_VARIANT == 2 && !defined(ABSL_HAVE_STD_VARIANT)) -+#undef ABSL_USES_STD_VARIANT -+#elif ABSL_OPTION_USE_STD_VARIANT == 1 || \ -+ (ABSL_OPTION_USE_STD_VARIANT == 2 && defined(ABSL_HAVE_STD_VARIANT)) -+#define ABSL_USES_STD_VARIANT 1 -+#else -+#error options.h is misconfigured. -+#endif -+ -+// ABSL_USES_STD_STRING_VIEW -+// -+// Indicates whether absl::string_view is an alias for std::string_view. -+#if !defined(ABSL_OPTION_USE_STD_STRING_VIEW) -+#error options.h is misconfigured. -+#elif ABSL_OPTION_USE_STD_STRING_VIEW == 0 || \ -+ (ABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ -+ !defined(ABSL_HAVE_STD_STRING_VIEW)) -+#undef ABSL_USES_STD_STRING_VIEW -+#elif ABSL_OPTION_USE_STD_STRING_VIEW == 1 || \ -+ (ABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ -+ defined(ABSL_HAVE_STD_STRING_VIEW)) -+#define ABSL_USES_STD_STRING_VIEW 1 -+#else -+#error options.h is misconfigured. -+#endif -+ -+// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION -+// SEH exception from emplace for variant when constructing the -+// struct can throw. This defeats some of variant_test and -+// variant_exception_safety_test. -+#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG) -+#define ABSL_INTERNAL_MSVC_2017_DBG_MODE -+#endif -+ -+// ABSL_INTERNAL_MANGLED_NS -+// ABSL_INTERNAL_MANGLED_BACKREFERENCE -+// -+// Internal macros for building up mangled names in our internal fork of CCTZ. -+// This implementation detail is only needed and provided for the MSVC build. -+// -+// These macros both expand to string literals. ABSL_INTERNAL_MANGLED_NS is -+// the mangled spelling of the `absl` namespace, and -+// ABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing -+// the proper count to skip past the CCTZ fork namespace names. (This number -+// is one larger when there is an inline namespace name to skip.) -+#if defined(_MSC_VER) -+#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 -+#define ABSL_INTERNAL_MANGLED_NS "absl" -+#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "5" -+#else -+#define ABSL_INTERNAL_MANGLED_NS \ -+ ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) "@absl" -+#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "6" -+#endif -+#endif -+ -+#undef ABSL_INTERNAL_HAS_KEYWORD -+ -+// ABSL_DLL -+// -+// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)` -+// so we can annotate symbols appropriately as being exported. When used in -+// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so -+// that consumers know the symbol is defined inside the DLL. In all other cases, -+// the macro expands to nothing. -+#if defined(_MSC_VER) -+#if defined(ABSL_BUILD_DLL) -+#define ABSL_DLL __declspec(dllexport) -+#elif defined(ABSL_CONSUME_DLL) -+#define ABSL_DLL __declspec(dllimport) -+#else -+#define ABSL_DLL -+#endif -+#else -+#define ABSL_DLL -+#endif // defined(_MSC_VER) -+ -+// ABSL_HAVE_MEMORY_SANITIZER -+// -+// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of -+// a compiler instrumentation module and a run-time library. -+#ifdef ABSL_HAVE_MEMORY_SANITIZER -+#error "ABSL_HAVE_MEMORY_SANITIZER cannot be directly set." -+#elif defined(__SANITIZE_MEMORY__) -+#define ABSL_HAVE_MEMORY_SANITIZER 1 -+#elif !defined(__native_client__) && ABSL_HAVE_FEATURE(memory_sanitizer) -+#define ABSL_HAVE_MEMORY_SANITIZER 1 -+#endif -+ -+// ABSL_HAVE_THREAD_SANITIZER -+// -+// ThreadSanitizer (TSan) is a fast data race detector. -+#ifdef ABSL_HAVE_THREAD_SANITIZER -+#error "ABSL_HAVE_THREAD_SANITIZER cannot be directly set." -+#elif defined(__SANITIZE_THREAD__) -+#define ABSL_HAVE_THREAD_SANITIZER 1 -+#elif ABSL_HAVE_FEATURE(thread_sanitizer) -+#define ABSL_HAVE_THREAD_SANITIZER 1 -+#endif -+ -+// ABSL_HAVE_ADDRESS_SANITIZER -+// -+// AddressSanitizer (ASan) is a fast memory error detector. -+#ifdef ABSL_HAVE_ADDRESS_SANITIZER -+#error "ABSL_HAVE_ADDRESS_SANITIZER cannot be directly set." -+#elif defined(__SANITIZE_ADDRESS__) -+#define ABSL_HAVE_ADDRESS_SANITIZER 1 -+#elif ABSL_HAVE_FEATURE(address_sanitizer) -+#define ABSL_HAVE_ADDRESS_SANITIZER 1 -+#endif -+ -+// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION -+// -+// Class template argument deduction is a language feature added in C++17. -+#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION -+#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set." -+#elif defined(__cpp_deduction_guides) -+#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 -+#endif -+ -+#endif // ABSL_BASE_CONFIG_H_ -diff --git a/extern/int128/absl/base/macros.h b/extern/int128/absl/base/macros.h -new file mode 100644 -index 0000000000..3e085a916b ---- /dev/null -+++ b/extern/int128/absl/base/macros.h -@@ -0,0 +1,158 @@ -+// -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: macros.h -+// ----------------------------------------------------------------------------- -+// -+// This header file defines the set of language macros used within Abseil code. -+// For the set of macros used to determine supported compilers and platforms, -+// see absl/base/config.h instead. -+// -+// This code is compiled directly on many platforms, including client -+// platforms like Windows, Mac, and embedded systems. Before making -+// any changes here, make sure that you're not breaking any platforms. -+ -+#ifndef ABSL_BASE_MACROS_H_ -+#define ABSL_BASE_MACROS_H_ -+ -+#include -+#include -+ -+#include "absl/base/attributes.h" -+#include "absl/base/config.h" -+#include "absl/base/optimization.h" -+#include "absl/base/port.h" -+ -+// ABSL_ARRAYSIZE() -+// -+// Returns the number of elements in an array as a compile-time constant, which -+// can be used in defining new arrays. If you use this macro on a pointer by -+// mistake, you will get a compile-time error. -+#define ABSL_ARRAYSIZE(array) \ -+ (sizeof(::absl::macros_internal::ArraySizeHelper(array))) -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+namespace macros_internal { -+// Note: this internal template function declaration is used by ABSL_ARRAYSIZE. -+// The function doesn't need a definition, as we only use its type. -+template -+auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; -+} // namespace macros_internal -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+// ABSL_BAD_CALL_IF() -+// -+// Used on a function overload to trap bad calls: any call that matches the -+// overload will cause a compile-time error. This macro uses a clang-specific -+// "enable_if" attribute, as described at -+// https://clang.llvm.org/docs/AttributeReference.html#enable-if -+// -+// Overloads which use this macro should be bracketed by -+// `#ifdef ABSL_BAD_CALL_IF`. -+// -+// Example: -+// -+// int isdigit(int c); -+// #ifdef ABSL_BAD_CALL_IF -+// int isdigit(int c) -+// ABSL_BAD_CALL_IF(c <= -1 || c > 255, -+// "'c' must have the value of an unsigned char or EOF"); -+// #endif // ABSL_BAD_CALL_IF -+#if ABSL_HAVE_ATTRIBUTE(enable_if) -+#define ABSL_BAD_CALL_IF(expr, msg) \ -+ __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) -+#endif -+ -+// ABSL_ASSERT() -+// -+// In C++11, `assert` can't be used portably within constexpr functions. -+// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr -+// functions. Example: -+// -+// constexpr double Divide(double a, double b) { -+// return ABSL_ASSERT(b != 0), a / b; -+// } -+// -+// This macro is inspired by -+// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ -+#if defined(NDEBUG) -+#define ABSL_ASSERT(expr) \ -+ (false ? static_cast(expr) : static_cast(0)) -+#else -+#define ABSL_ASSERT(expr) \ -+ (ABSL_PREDICT_TRUE((expr)) ? static_cast(0) \ -+ : [] { assert(false && #expr); }()) // NOLINT -+#endif -+ -+// `ABSL_INTERNAL_HARDENING_ABORT()` controls how `ABSL_HARDENING_ASSERT()` -+// aborts the program in release mode (when NDEBUG is defined). The -+// implementation should abort the program as quickly as possible and ideally it -+// should not be possible to ignore the abort request. -+#if (ABSL_HAVE_BUILTIN(__builtin_trap) && \ -+ ABSL_HAVE_BUILTIN(__builtin_unreachable)) || \ -+ (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_INTERNAL_HARDENING_ABORT() \ -+ do { \ -+ __builtin_trap(); \ -+ __builtin_unreachable(); \ -+ } while (false) -+#else -+#define ABSL_INTERNAL_HARDENING_ABORT() abort() -+#endif -+ -+// ABSL_HARDENING_ASSERT() -+// -+// `ABSL_HARDENING_ASSERT()` is like `ABSL_ASSERT()`, but used to implement -+// runtime assertions that should be enabled in hardened builds even when -+// `NDEBUG` is defined. -+// -+// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT()` is identical to -+// `ABSL_ASSERT()`. -+// -+// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on -+// hardened mode. -+#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG) -+#define ABSL_HARDENING_ASSERT(expr) \ -+ (ABSL_PREDICT_TRUE((expr)) ? static_cast(0) \ -+ : [] { ABSL_INTERNAL_HARDENING_ABORT(); }()) -+#else -+#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr) -+#endif -+ -+#ifdef ABSL_HAVE_EXCEPTIONS -+#define ABSL_INTERNAL_TRY try -+#define ABSL_INTERNAL_CATCH_ANY catch (...) -+#define ABSL_INTERNAL_RETHROW do { throw; } while (false) -+#else // ABSL_HAVE_EXCEPTIONS -+#define ABSL_INTERNAL_TRY if (true) -+#define ABSL_INTERNAL_CATCH_ANY else if (false) -+#define ABSL_INTERNAL_RETHROW do {} while (false) -+#endif // ABSL_HAVE_EXCEPTIONS -+ -+// `ABSL_INTERNAL_UNREACHABLE` is an unreachable statement. A program which -+// reaches one has undefined behavior, and the compiler may optimize -+// accordingly. -+#if defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable) -+#define ABSL_INTERNAL_UNREACHABLE __builtin_unreachable() -+#elif defined(_MSC_VER) -+#define ABSL_INTERNAL_UNREACHABLE __assume(0) -+#else -+#define ABSL_INTERNAL_UNREACHABLE -+#endif -+ -+#endif // ABSL_BASE_MACROS_H_ -diff --git a/extern/int128/absl/base/optimization.h b/extern/int128/absl/base/optimization.h -new file mode 100644 -index 0000000000..d090be1286 ---- /dev/null -+++ b/extern/int128/absl/base/optimization.h -@@ -0,0 +1,244 @@ -+// -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: optimization.h -+// ----------------------------------------------------------------------------- -+// -+// This header file defines portable macros for performance optimization. -+ -+#ifndef ABSL_BASE_OPTIMIZATION_H_ -+#define ABSL_BASE_OPTIMIZATION_H_ -+ -+#include -+ -+#include "absl/base/config.h" -+ -+// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION -+// -+// Instructs the compiler to avoid optimizing tail-call recursion. This macro is -+// useful when you wish to preserve the existing function order within a stack -+// trace for logging, debugging, or profiling purposes. -+// -+// Example: -+// -+// int f() { -+// int result = g(); -+// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); -+// return result; -+// } -+#if defined(__pnacl__) -+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } -+#elif defined(__clang__) -+// Clang will not tail call given inline volatile assembly. -+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") -+#elif defined(__GNUC__) -+// GCC will not tail call given inline volatile assembly. -+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") -+#elif defined(_MSC_VER) -+#include -+// The __nop() intrinsic blocks the optimisation. -+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() -+#else -+#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } -+#endif -+ -+// ABSL_CACHELINE_SIZE -+// -+// Explicitly defines the size of the L1 cache for purposes of alignment. -+// Setting the cacheline size allows you to specify that certain objects be -+// aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations. -+// (See below.) -+// -+// NOTE: this macro should be replaced with the following C++17 features, when -+// those are generally available: -+// -+// * `std::hardware_constructive_interference_size` -+// * `std::hardware_destructive_interference_size` -+// -+// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html -+// for more information. -+#if defined(__GNUC__) -+// Cache line alignment -+#if defined(__i386__) || defined(__x86_64__) -+#define ABSL_CACHELINE_SIZE 64 -+#elif defined(__powerpc64__) -+#define ABSL_CACHELINE_SIZE 128 -+#elif defined(__aarch64__) -+// We would need to read special register ctr_el0 to find out L1 dcache size. -+// This value is a good estimate based on a real aarch64 machine. -+#define ABSL_CACHELINE_SIZE 64 -+#elif defined(__arm__) -+// Cache line sizes for ARM: These values are not strictly correct since -+// cache line sizes depend on implementations, not architectures. There -+// are even implementations with cache line sizes configurable at boot -+// time. -+#if defined(__ARM_ARCH_5T__) -+#define ABSL_CACHELINE_SIZE 32 -+#elif defined(__ARM_ARCH_7A__) -+#define ABSL_CACHELINE_SIZE 64 -+#endif -+#endif -+ -+#ifndef ABSL_CACHELINE_SIZE -+// A reasonable default guess. Note that overestimates tend to waste more -+// space, while underestimates tend to waste more time. -+#define ABSL_CACHELINE_SIZE 64 -+#endif -+ -+// ABSL_CACHELINE_ALIGNED -+// -+// Indicates that the declared object be cache aligned using -+// `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to -+// load a set of related objects in the L1 cache for performance improvements. -+// Cacheline aligning objects properly allows constructive memory sharing and -+// prevents destructive (or "false") memory sharing. -+// -+// NOTE: callers should replace uses of this macro with `alignas()` using -+// `std::hardware_constructive_interference_size` and/or -+// `std::hardware_destructive_interference_size` when C++17 becomes available to -+// them. -+// -+// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html -+// for more information. -+// -+// On some compilers, `ABSL_CACHELINE_ALIGNED` expands to an `__attribute__` -+// or `__declspec` attribute. For compilers where this is not known to work, -+// the macro expands to nothing. -+// -+// No further guarantees are made here. The result of applying the macro -+// to variables and types is always implementation-defined. -+// -+// WARNING: It is easy to use this attribute incorrectly, even to the point -+// of causing bugs that are difficult to diagnose, crash, etc. It does not -+// of itself guarantee that objects are aligned to a cache line. -+// -+// NOTE: Some compilers are picky about the locations of annotations such as -+// this attribute, so prefer to put it at the beginning of your declaration. -+// For example, -+// -+// ABSL_CACHELINE_ALIGNED static Foo* foo = ... -+// -+// class ABSL_CACHELINE_ALIGNED Bar { ... -+// -+// Recommendations: -+// -+// 1) Consult compiler documentation; this comment is not kept in sync as -+// toolchains evolve. -+// 2) Verify your use has the intended effect. This often requires inspecting -+// the generated machine code. -+// 3) Prefer applying this attribute to individual variables. Avoid -+// applying it to types. This tends to localize the effect. -+#define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE))) -+#elif defined(_MSC_VER) -+#define ABSL_CACHELINE_SIZE 64 -+#define ABSL_CACHELINE_ALIGNED __declspec(align(ABSL_CACHELINE_SIZE)) -+#else -+#define ABSL_CACHELINE_SIZE 64 -+#define ABSL_CACHELINE_ALIGNED -+#endif -+ -+// ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE -+// -+// Enables the compiler to prioritize compilation using static analysis for -+// likely paths within a boolean branch. -+// -+// Example: -+// -+// if (ABSL_PREDICT_TRUE(expression)) { -+// return result; // Faster if more likely -+// } else { -+// return 0; -+// } -+// -+// Compilers can use the information that a certain branch is not likely to be -+// taken (for instance, a CHECK failure) to optimize for the common case in -+// the absence of better information (ie. compiling gcc with `-fprofile-arcs`). -+// -+// Recommendation: Modern CPUs dynamically predict branch execution paths, -+// typically with accuracy greater than 97%. As a result, annotating every -+// branch in a codebase is likely counterproductive; however, annotating -+// specific branches that are both hot and consistently mispredicted is likely -+// to yield performance improvements. -+#if ABSL_HAVE_BUILTIN(__builtin_expect) || \ -+ (defined(__GNUC__) && !defined(__clang__)) -+#define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false)) -+#define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) -+#else -+#define ABSL_PREDICT_FALSE(x) (x) -+#define ABSL_PREDICT_TRUE(x) (x) -+#endif -+ -+// ABSL_INTERNAL_ASSUME(cond) -+// Informs the compiler that a condition is always true and that it can assume -+// it to be true for optimization purposes. The call has undefined behavior if -+// the condition is false. -+// In !NDEBUG mode, the condition is checked with an assert(). -+// NOTE: The expression must not have side effects, as it will only be evaluated -+// in some compilation modes and not others. -+// -+// Example: -+// -+// int x = ...; -+// ABSL_INTERNAL_ASSUME(x >= 0); -+// // The compiler can optimize the division to a simple right shift using the -+// // assumption specified above. -+// int y = x / 16; -+// -+#if !defined(NDEBUG) -+#define ABSL_INTERNAL_ASSUME(cond) assert(cond) -+#elif ABSL_HAVE_BUILTIN(__builtin_assume) -+#define ABSL_INTERNAL_ASSUME(cond) __builtin_assume(cond) -+#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable) -+#define ABSL_INTERNAL_ASSUME(cond) \ -+ do { \ -+ if (!(cond)) __builtin_unreachable(); \ -+ } while (0) -+#elif defined(_MSC_VER) -+#define ABSL_INTERNAL_ASSUME(cond) __assume(cond) -+#else -+#define ABSL_INTERNAL_ASSUME(cond) \ -+ do { \ -+ static_cast(false && (cond)); \ -+ } while (0) -+#endif -+ -+// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond) -+// This macro forces small unique name on a static file level symbols like -+// static local variables or static functions. This is intended to be used in -+// macro definitions to optimize the cost of generated code. Do NOT use it on -+// symbols exported from translation unit since it may cause a link time -+// conflict. -+// -+// Example: -+// -+// #define MY_MACRO(txt) -+// namespace { -+// char VeryVeryLongVarName[] ABSL_INTERNAL_UNIQUE_SMALL_NAME() = txt; -+// const char* VeryVeryLongFuncName() ABSL_INTERNAL_UNIQUE_SMALL_NAME(); -+// const char* VeryVeryLongFuncName() { return txt; } -+// } -+// -+ -+#if defined(__GNUC__) -+#define ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) #x -+#define ABSL_INTERNAL_UNIQUE_SMALL_NAME1(x) ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) -+#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() \ -+ asm(ABSL_INTERNAL_UNIQUE_SMALL_NAME1(.absl.__COUNTER__)) -+#else -+#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() -+#endif -+ -+#endif // ABSL_BASE_OPTIMIZATION_H_ -diff --git a/extern/int128/absl/base/options.h b/extern/int128/absl/base/options.h -new file mode 100644 -index 0000000000..230bf1eecc ---- /dev/null -+++ b/extern/int128/absl/base/options.h -@@ -0,0 +1,238 @@ -+// Copyright 2019 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: options.h -+// ----------------------------------------------------------------------------- -+// -+// This file contains Abseil configuration options for setting specific -+// implementations instead of letting Abseil determine which implementation to -+// use at compile-time. Setting these options may be useful for package or build -+// managers who wish to guarantee ABI stability within binary builds (which are -+// otherwise difficult to enforce). -+// -+// *** IMPORTANT NOTICE FOR PACKAGE MANAGERS: It is important that -+// maintainers of package managers who wish to package Abseil read and -+// understand this file! *** -+// -+// Abseil contains a number of possible configuration endpoints, based on -+// parameters such as the detected platform, language version, or command-line -+// flags used to invoke the underlying binary. As is the case with all -+// libraries, binaries which contain Abseil code must ensure that separate -+// packages use the same compiled copy of Abseil to avoid a diamond dependency -+// problem, which can occur if two packages built with different Abseil -+// configuration settings are linked together. Diamond dependency problems in -+// C++ may manifest as violations to the One Definition Rule (ODR) (resulting in -+// linker errors), or undefined behavior (resulting in crashes). -+// -+// Diamond dependency problems can be avoided if all packages utilize the same -+// exact version of Abseil. Building from source code with the same compilation -+// parameters is the easiest way to avoid such dependency problems. However, for -+// package managers who cannot control such compilation parameters, we are -+// providing the file to allow you to inject ABI (Application Binary Interface) -+// stability across builds. Settings options in this file will neither change -+// API nor ABI, providing a stable copy of Abseil between packages. -+// -+// Care must be taken to keep options within these configurations isolated -+// from any other dynamic settings, such as command-line flags which could alter -+// these options. This file is provided specifically to help build and package -+// managers provide a stable copy of Abseil within their libraries and binaries; -+// other developers should not have need to alter the contents of this file. -+// -+// ----------------------------------------------------------------------------- -+// Usage -+// ----------------------------------------------------------------------------- -+// -+// For any particular package release, set the appropriate definitions within -+// this file to whatever value makes the most sense for your package(s). Note -+// that, by default, most of these options, at the moment, affect the -+// implementation of types; future options may affect other implementation -+// details. -+// -+// NOTE: the defaults within this file all assume that Abseil can select the -+// proper Abseil implementation at compile-time, which will not be sufficient -+// to guarantee ABI stability to package managers. -+ -+#ifndef ABSL_BASE_OPTIONS_H_ -+#define ABSL_BASE_OPTIONS_H_ -+ -+// Include a standard library header to allow configuration based on the -+// standard library in use. -+#ifdef __cplusplus -+#include -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Type Compatibility Options -+// ----------------------------------------------------------------------------- -+// -+// ABSL_OPTION_USE_STD_ANY -+// -+// This option controls whether absl::any is implemented as an alias to -+// std::any, or as an independent implementation. -+// -+// A value of 0 means to use Abseil's implementation. This requires only C++11 -+// support, and is expected to work on every toolchain we support. -+// -+// A value of 1 means to use an alias to std::any. This requires that all code -+// using Abseil is built in C++17 mode or later. -+// -+// A value of 2 means to detect the C++ version being used to compile Abseil, -+// and use an alias only if a working std::any is available. This option is -+// useful when you are building your entire program, including all of its -+// dependencies, from source. It should not be used otherwise -- for example, -+// if you are distributing Abseil in a binary package manager -- since in -+// mode 2, absl::any will name a different type, with a different mangled name -+// and binary layout, depending on the compiler flags passed by the end user. -+// For more info, see https://abseil.io/about/design/dropin-types. -+// -+// User code should not inspect this macro. To check in the preprocessor if -+// absl::any is a typedef of std::any, use the feature macro ABSL_USES_STD_ANY. -+ -+#define ABSL_OPTION_USE_STD_ANY 2 -+ -+ -+// ABSL_OPTION_USE_STD_OPTIONAL -+// -+// This option controls whether absl::optional is implemented as an alias to -+// std::optional, or as an independent implementation. -+// -+// A value of 0 means to use Abseil's implementation. This requires only C++11 -+// support, and is expected to work on every toolchain we support. -+// -+// A value of 1 means to use an alias to std::optional. This requires that all -+// code using Abseil is built in C++17 mode or later. -+// -+// A value of 2 means to detect the C++ version being used to compile Abseil, -+// and use an alias only if a working std::optional is available. This option -+// is useful when you are building your program from source. It should not be -+// used otherwise -- for example, if you are distributing Abseil in a binary -+// package manager -- since in mode 2, absl::optional will name a different -+// type, with a different mangled name and binary layout, depending on the -+// compiler flags passed by the end user. For more info, see -+// https://abseil.io/about/design/dropin-types. -+ -+// User code should not inspect this macro. To check in the preprocessor if -+// absl::optional is a typedef of std::optional, use the feature macro -+// ABSL_USES_STD_OPTIONAL. -+ -+#define ABSL_OPTION_USE_STD_OPTIONAL 2 -+ -+ -+// ABSL_OPTION_USE_STD_STRING_VIEW -+// -+// This option controls whether absl::string_view is implemented as an alias to -+// std::string_view, or as an independent implementation. -+// -+// A value of 0 means to use Abseil's implementation. This requires only C++11 -+// support, and is expected to work on every toolchain we support. -+// -+// A value of 1 means to use an alias to std::string_view. This requires that -+// all code using Abseil is built in C++17 mode or later. -+// -+// A value of 2 means to detect the C++ version being used to compile Abseil, -+// and use an alias only if a working std::string_view is available. This -+// option is useful when you are building your program from source. It should -+// not be used otherwise -- for example, if you are distributing Abseil in a -+// binary package manager -- since in mode 2, absl::string_view will name a -+// different type, with a different mangled name and binary layout, depending on -+// the compiler flags passed by the end user. For more info, see -+// https://abseil.io/about/design/dropin-types. -+// -+// User code should not inspect this macro. To check in the preprocessor if -+// absl::string_view is a typedef of std::string_view, use the feature macro -+// ABSL_USES_STD_STRING_VIEW. -+ -+#define ABSL_OPTION_USE_STD_STRING_VIEW 2 -+ -+// ABSL_OPTION_USE_STD_VARIANT -+// -+// This option controls whether absl::variant is implemented as an alias to -+// std::variant, or as an independent implementation. -+// -+// A value of 0 means to use Abseil's implementation. This requires only C++11 -+// support, and is expected to work on every toolchain we support. -+// -+// A value of 1 means to use an alias to std::variant. This requires that all -+// code using Abseil is built in C++17 mode or later. -+// -+// A value of 2 means to detect the C++ version being used to compile Abseil, -+// and use an alias only if a working std::variant is available. This option -+// is useful when you are building your program from source. It should not be -+// used otherwise -- for example, if you are distributing Abseil in a binary -+// package manager -- since in mode 2, absl::variant will name a different -+// type, with a different mangled name and binary layout, depending on the -+// compiler flags passed by the end user. For more info, see -+// https://abseil.io/about/design/dropin-types. -+// -+// User code should not inspect this macro. To check in the preprocessor if -+// absl::variant is a typedef of std::variant, use the feature macro -+// ABSL_USES_STD_VARIANT. -+ -+#define ABSL_OPTION_USE_STD_VARIANT 2 -+ -+ -+// ABSL_OPTION_USE_INLINE_NAMESPACE -+// ABSL_OPTION_INLINE_NAMESPACE_NAME -+// -+// These options controls whether all entities in the absl namespace are -+// contained within an inner inline namespace. This does not affect the -+// user-visible API of Abseil, but it changes the mangled names of all symbols. -+// -+// This can be useful as a version tag if you are distributing Abseil in -+// precompiled form. This will prevent a binary library build of Abseil with -+// one inline namespace being used with headers configured with a different -+// inline namespace name. Binary packagers are reminded that Abseil does not -+// guarantee any ABI stability in Abseil, so any update of Abseil or -+// configuration change in such a binary package should be combined with a -+// new, unique value for the inline namespace name. -+// -+// A value of 0 means not to use inline namespaces. -+// -+// A value of 1 means to use an inline namespace with the given name inside -+// namespace absl. If this is set, ABSL_OPTION_INLINE_NAMESPACE_NAME must also -+// be changed to a new, unique identifier name. In particular "head" is not -+// allowed. -+ -+#define ABSL_OPTION_USE_INLINE_NAMESPACE 0 -+#define ABSL_OPTION_INLINE_NAMESPACE_NAME head -+ -+// ABSL_OPTION_HARDENED -+// -+// This option enables a "hardened" build in release mode (in this context, -+// release mode is defined as a build where the `NDEBUG` macro is defined). -+// -+// A value of 0 means that "hardened" mode is not enabled. -+// -+// A value of 1 means that "hardened" mode is enabled. -+// -+// Hardened builds have additional security checks enabled when `NDEBUG` is -+// defined. Defining `NDEBUG` is normally used to turn `assert()` macro into a -+// no-op, as well as disabling other bespoke program consistency checks. By -+// defining ABSL_OPTION_HARDENED to 1, a select set of checks remain enabled in -+// release mode. These checks guard against programming errors that may lead to -+// security vulnerabilities. In release mode, when one of these programming -+// errors is encountered, the program will immediately abort, possibly without -+// any attempt at logging. -+// -+// The checks enabled by this option are not free; they do incur runtime cost. -+// -+// The checks enabled by this option are always active when `NDEBUG` is not -+// defined, even in the case when ABSL_OPTION_HARDENED is defined to 0. The -+// checks enabled by this option may abort the program in a different way and -+// log additional information when `NDEBUG` is not defined. -+ -+#define ABSL_OPTION_HARDENED 0 -+ -+#endif // ABSL_BASE_OPTIONS_H_ -diff --git a/extern/int128/absl/base/policy_checks.h b/extern/int128/absl/base/policy_checks.h -new file mode 100644 -index 0000000000..06b3243916 ---- /dev/null -+++ b/extern/int128/absl/base/policy_checks.h -@@ -0,0 +1,111 @@ -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: policy_checks.h -+// ----------------------------------------------------------------------------- -+// -+// This header enforces a minimum set of policies at build time, such as the -+// supported compiler and library versions. Unsupported configurations are -+// reported with `#error`. This enforcement is best effort, so successfully -+// compiling this header does not guarantee a supported configuration. -+ -+#ifndef ABSL_BASE_POLICY_CHECKS_H_ -+#define ABSL_BASE_POLICY_CHECKS_H_ -+ -+// Included for the __GLIBC_PREREQ macro used below. -+#include -+ -+// Included for the _STLPORT_VERSION macro used below. -+#if defined(__cplusplus) -+#include -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Operating System Check -+// ----------------------------------------------------------------------------- -+ -+#if defined(__CYGWIN__) -+#error "Cygwin is not supported." -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Toolchain Check -+// ----------------------------------------------------------------------------- -+ -+// We support MSVC++ 14.0 update 2 and later. -+// This minimum will go up. -+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__) -+#error "This package requires Visual Studio 2015 Update 2 or higher." -+#endif -+ -+// We support gcc 4.7 and later. -+// This minimum will go up. -+#if defined(__GNUC__) && !defined(__clang__) -+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) -+#error "This package requires gcc 4.7 or higher." -+#endif -+#endif -+ -+// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later. -+// This corresponds to Apple Xcode version 4.5. -+// This minimum will go up. -+#if defined(__apple_build_version__) && __apple_build_version__ < 4211165 -+#error "This package requires __apple_build_version__ of 4211165 or higher." -+#endif -+ -+// ----------------------------------------------------------------------------- -+// C++ Version Check -+// ----------------------------------------------------------------------------- -+ -+// Enforce C++11 as the minimum. Note that Visual Studio has not -+// advanced __cplusplus despite being good enough for our purposes, so -+// so we exempt it from the check. -+#if defined(__cplusplus) && !defined(_MSC_VER) -+#if __cplusplus < 201103L -+#error "C++ versions less than C++11 are not supported." -+#endif -+#endif -+ -+// ----------------------------------------------------------------------------- -+// Standard Library Check -+// ----------------------------------------------------------------------------- -+ -+#if defined(_STLPORT_VERSION) -+#error "STLPort is not supported." -+#endif -+ -+// ----------------------------------------------------------------------------- -+// `char` Size Check -+// ----------------------------------------------------------------------------- -+ -+// Abseil currently assumes CHAR_BIT == 8. If you would like to use Abseil on a -+// platform where this is not the case, please provide us with the details about -+// your platform so we can consider relaxing this requirement. -+#if CHAR_BIT != 8 -+#error "Abseil assumes CHAR_BIT == 8." -+#endif -+ -+// ----------------------------------------------------------------------------- -+// `int` Size Check -+// ----------------------------------------------------------------------------- -+ -+// Abseil currently assumes that an int is 4 bytes. If you would like to use -+// Abseil on a platform where this is not the case, please provide us with the -+// details about your platform so we can consider relaxing this requirement. -+#if INT_MAX < 2147483647 -+#error "Abseil assumes that int is at least 4 bytes. " -+#endif -+ -+#endif // ABSL_BASE_POLICY_CHECKS_H_ -diff --git a/extern/int128/absl/base/port.h b/extern/int128/absl/base/port.h -new file mode 100644 -index 0000000000..5bc4d6cd95 ---- /dev/null -+++ b/extern/int128/absl/base/port.h -@@ -0,0 +1,25 @@ -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// This files is a forwarding header for other headers containing various -+// portability macros and functions. -+ -+#ifndef ABSL_BASE_PORT_H_ -+#define ABSL_BASE_PORT_H_ -+ -+#include "absl/base/attributes.h" -+#include "absl/base/config.h" -+#include "absl/base/optimization.h" -+ -+#endif // ABSL_BASE_PORT_H_ -diff --git a/extern/int128/absl/numeric/Makefile b/extern/int128/absl/numeric/Makefile -new file mode 100644 -index 0000000000..396e95d063 ---- /dev/null -+++ b/extern/int128/absl/numeric/Makefile -@@ -0,0 +1,11 @@ -+LIBRARY=libi128$(CROSS).a -+ -+$(LIBRARY): $(wildcard *.cc) $(wildcard *.h) $(wildcard internal/*.h) $(wildcard ../base/*.h) $(wildcard *.inc) Makefile -+ $(RM) -f *.o -+ $(CXX) $(CROSS_FLAGS) -I../.. -c -O3 -fPIC int128.cc -+ $(AR) crs $(LIBRARY) *.o -+ $(RM) -f *.o -+ -+.PHONY: clean -+clean: -+ $(RM) -f *.o *.a -diff --git a/extern/int128/absl/numeric/bits.h b/extern/int128/absl/numeric/bits.h -new file mode 100644 -index 0000000000..52013ad49b ---- /dev/null -+++ b/extern/int128/absl/numeric/bits.h -@@ -0,0 +1,177 @@ -+// Copyright 2020 The Abseil Authors -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: bits.h -+// ----------------------------------------------------------------------------- -+// -+// This file contains implementations of C++20's bitwise math functions, as -+// defined by: -+// -+// P0553R4: -+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html -+// P0556R3: -+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0556r3.html -+// P1355R2: -+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1355r2.html -+// P1956R1: -+// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1956r1.pdf -+// -+// When using a standard library that implements these functions, we use the -+// standard library's implementation. -+ -+#ifndef ABSL_NUMERIC_BITS_H_ -+#define ABSL_NUMERIC_BITS_H_ -+ -+#include -+#include -+#include -+ -+#if (defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L) || \ -+ (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) -+#include -+#endif -+ -+#include "absl/base/attributes.h" -+#include "absl/base/config.h" -+#include "absl/numeric/internal/bits.h" -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+ -+#if !(defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) -+// rotating -+template -+ABSL_MUST_USE_RESULT constexpr -+ typename std::enable_if::value, T>::type -+ rotl(T x, int s) noexcept { -+ return numeric_internal::RotateLeft(x, s); -+} -+ -+template -+ABSL_MUST_USE_RESULT constexpr -+ typename std::enable_if::value, T>::type -+ rotr(T x, int s) noexcept { -+ return numeric_internal::RotateRight(x, s); -+} -+ -+// Counting functions -+// -+// While these functions are typically constexpr, on some platforms, they may -+// not be marked as constexpr due to constraints of the compiler/available -+// intrinsics. -+template -+ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, int>::type -+ countl_zero(T x) noexcept { -+ return numeric_internal::CountLeadingZeroes(x); -+} -+ -+template -+ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, int>::type -+ countl_one(T x) noexcept { -+ // Avoid integer promotion to a wider type -+ return countl_zero(static_cast(~x)); -+} -+ -+template -+ABSL_INTERNAL_CONSTEXPR_CTZ inline -+ typename std::enable_if::value, int>::type -+ countr_zero(T x) noexcept { -+ return numeric_internal::CountTrailingZeroes(x); -+} -+ -+template -+ABSL_INTERNAL_CONSTEXPR_CTZ inline -+ typename std::enable_if::value, int>::type -+ countr_one(T x) noexcept { -+ // Avoid integer promotion to a wider type -+ return countr_zero(static_cast(~x)); -+} -+ -+template -+ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline -+ typename std::enable_if::value, int>::type -+ popcount(T x) noexcept { -+ return numeric_internal::Popcount(x); -+} -+#else // defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L -+ -+using std::countl_one; -+using std::countl_zero; -+using std::countr_one; -+using std::countr_zero; -+using std::popcount; -+using std::rotl; -+using std::rotr; -+ -+#endif -+ -+#if !(defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L) -+// Returns: true if x is an integral power of two; false otherwise. -+template -+constexpr inline typename std::enable_if::value, bool>::type -+has_single_bit(T x) noexcept { -+ return x != 0 && (x & (x - 1)) == 0; -+} -+ -+// Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any -+// fractional part discarded. -+template -+ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, T>::type -+ bit_width(T x) noexcept { -+ return std::numeric_limits::digits - countl_zero(x); -+} -+ -+// Returns: If x == 0, 0; otherwise the maximal value y such that -+// has_single_bit(y) is true and y <= x. -+template -+ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, T>::type -+ bit_floor(T x) noexcept { -+ return x == 0 ? 0 : T{1} << (bit_width(x) - 1); -+} -+ -+// Returns: N, where N is the smallest power of 2 greater than or equal to x. -+// -+// Preconditions: N is representable as a value of type T. -+template -+ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, T>::type -+ bit_ceil(T x) { -+ // If T is narrower than unsigned, T{1} << bit_width will be promoted. We -+ // want to force it to wraparound so that bit_ceil of an invalid value are not -+ // core constant expressions. -+ // -+ // BitCeilNonPowerOf2 triggers an overflow in constexpr contexts if we would -+ // undergo promotion to unsigned but not fit the result into T without -+ // truncation. -+ return has_single_bit(x) ? T{1} << (bit_width(x) - 1) -+ : numeric_internal::BitCeilNonPowerOf2(x); -+} -+#else // defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L -+ -+using std::bit_ceil; -+using std::bit_floor; -+using std::bit_width; -+using std::has_single_bit; -+ -+#endif -+ -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+#endif // ABSL_NUMERIC_BITS_H_ -diff --git a/extern/int128/absl/numeric/int128.cc b/extern/int128/absl/numeric/int128.cc -new file mode 100644 -index 0000000000..17d88744ae ---- /dev/null -+++ b/extern/int128/absl/numeric/int128.cc -@@ -0,0 +1,383 @@ -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+#include "absl/numeric/int128.h" -+ -+#include -+ -+#include -+#include -+#include // NOLINT(readability/streams) -+#include -+#include -+#include -+ -+#include "absl/base/optimization.h" -+#include "absl/numeric/bits.h" -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+ -+ABSL_DLL const uint128 kuint128max = MakeUint128( -+ std::numeric_limits::max(), std::numeric_limits::max()); -+ -+namespace { -+ -+// Returns the 0-based position of the last set bit (i.e., most significant bit) -+// in the given uint128. The argument is not 0. -+// -+// For example: -+// Given: 5 (decimal) == 101 (binary) -+// Returns: 2 -+inline ABSL_ATTRIBUTE_ALWAYS_INLINE int Fls128(uint128 n) { -+ if (uint64_t hi = Uint128High64(n)) { -+ ABSL_INTERNAL_ASSUME(hi != 0); -+ return 127 - countl_zero(hi); -+ } -+ const uint64_t low = Uint128Low64(n); -+ ABSL_INTERNAL_ASSUME(low != 0); -+ return 63 - countl_zero(low); -+} -+ -+// Long division/modulo for uint128 implemented using the shift-subtract -+// division algorithm adapted from: -+// https://stackoverflow.com/questions/5386377/division-without-using -+inline void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, -+ uint128* remainder_ret) { -+ assert(divisor != 0); -+ -+ if (divisor > dividend) { -+ *quotient_ret = 0; -+ *remainder_ret = dividend; -+ return; -+ } -+ -+ if (divisor == dividend) { -+ *quotient_ret = 1; -+ *remainder_ret = 0; -+ return; -+ } -+ -+ uint128 denominator = divisor; -+ uint128 quotient = 0; -+ -+ // Left aligns the MSB of the denominator and the dividend. -+ const int shift = Fls128(dividend) - Fls128(denominator); -+ denominator <<= shift; -+ -+ // Uses shift-subtract algorithm to divide dividend by denominator. The -+ // remainder will be left in dividend. -+ for (int i = 0; i <= shift; ++i) { -+ quotient <<= 1; -+ if (dividend >= denominator) { -+ dividend -= denominator; -+ quotient |= 1; -+ } -+ denominator >>= 1; -+ } -+ -+ *quotient_ret = quotient; -+ *remainder_ret = dividend; -+} -+ -+template -+uint128 MakeUint128FromFloat(T v) { -+ static_assert(std::is_floating_point::value, ""); -+ -+ // Rounding behavior is towards zero, same as for built-in types. -+ -+ // Undefined behavior if v is NaN or cannot fit into uint128. -+ assert(std::isfinite(v) && v > -1 && -+ (std::numeric_limits::max_exponent <= 128 || -+ v < std::ldexp(static_cast(1), 128))); -+ -+ if (v >= std::ldexp(static_cast(1), 64)) { -+ uint64_t hi = static_cast(std::ldexp(v, -64)); -+ uint64_t lo = static_cast(v - std::ldexp(static_cast(hi), 64)); -+ return MakeUint128(hi, lo); -+ } -+ -+ return MakeUint128(0, static_cast(v)); -+} -+ -+#if defined(__clang__) && !defined(__SSE3__) -+// Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289 -+// Casting from long double to uint64_t is miscompiled and drops bits. -+// It is more work, so only use when we need the workaround. -+uint128 MakeUint128FromFloat(long double v) { -+ // Go 50 bits at a time, that fits in a double -+ static_assert(std::numeric_limits::digits >= 50, ""); -+ static_assert(std::numeric_limits::digits <= 150, ""); -+ // Undefined behavior if v is not finite or cannot fit into uint128. -+ assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128)); -+ -+ v = std::ldexp(v, -100); -+ uint64_t w0 = static_cast(static_cast(std::trunc(v))); -+ v = std::ldexp(v - static_cast(w0), 50); -+ uint64_t w1 = static_cast(static_cast(std::trunc(v))); -+ v = std::ldexp(v - static_cast(w1), 50); -+ uint64_t w2 = static_cast(static_cast(std::trunc(v))); -+ return (static_cast(w0) << 100) | (static_cast(w1) << 50) | -+ static_cast(w2); -+} -+#endif // __clang__ && !__SSE3__ -+} // namespace -+ -+uint128::uint128(float v) : uint128(MakeUint128FromFloat(v)) {} -+uint128::uint128(double v) : uint128(MakeUint128FromFloat(v)) {} -+uint128::uint128(long double v) : uint128(MakeUint128FromFloat(v)) {} -+ -+#if !defined(ABSL_HAVE_INTRINSIC_INT128) -+uint128 operator/(uint128 lhs, uint128 rhs) { -+ uint128 quotient = 0; -+ uint128 remainder = 0; -+ DivModImpl(lhs, rhs, "ient, &remainder); -+ return quotient; -+} -+ -+uint128 operator%(uint128 lhs, uint128 rhs) { -+ uint128 quotient = 0; -+ uint128 remainder = 0; -+ DivModImpl(lhs, rhs, "ient, &remainder); -+ return remainder; -+} -+#endif // !defined(ABSL_HAVE_INTRINSIC_INT128) -+ -+namespace { -+ -+std::string Uint128ToFormattedString(uint128 v, std::ios_base::fmtflags flags) { -+ // Select a divisor which is the largest power of the base < 2^64. -+ uint128 div; -+ int div_base_log; -+ switch (flags & std::ios::basefield) { -+ case std::ios::hex: -+ div = 0x1000000000000000; // 16^15 -+ div_base_log = 15; -+ break; -+ case std::ios::oct: -+ div = 01000000000000000000000; // 8^21 -+ div_base_log = 21; -+ break; -+ default: // std::ios::dec -+ div = 10000000000000000000u; // 10^19 -+ div_base_log = 19; -+ break; -+ } -+ -+ // Now piece together the uint128 representation from three chunks of the -+ // original value, each less than "div" and therefore representable as a -+ // uint64_t. -+ std::ostringstream os; -+ std::ios_base::fmtflags copy_mask = -+ std::ios::basefield | std::ios::showbase | std::ios::uppercase; -+ os.setf(flags & copy_mask, copy_mask); -+ uint128 high = v; -+ uint128 low; -+ DivModImpl(high, div, &high, &low); -+ uint128 mid; -+ DivModImpl(high, div, &high, &mid); -+ if (Uint128Low64(high) != 0) { -+ os << Uint128Low64(high); -+ os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); -+ os << Uint128Low64(mid); -+ os << std::setw(div_base_log); -+ } else if (Uint128Low64(mid) != 0) { -+ os << Uint128Low64(mid); -+ os << std::noshowbase << std::setfill('0') << std::setw(div_base_log); -+ } -+ os << Uint128Low64(low); -+ return os.str(); -+} -+ -+} // namespace -+ -+std::ostream& operator<<(std::ostream& os, uint128 v) { -+ std::ios_base::fmtflags flags = os.flags(); -+ std::string rep = Uint128ToFormattedString(v, flags); -+ -+ // Add the requisite padding. -+ std::streamsize width = os.width(0); -+ if (static_cast(width) > rep.size()) { -+ std::ios::fmtflags adjustfield = flags & std::ios::adjustfield; -+ if (adjustfield == std::ios::left) { -+ rep.append(width - rep.size(), os.fill()); -+ } else if (adjustfield == std::ios::internal && -+ (flags & std::ios::showbase) && -+ (flags & std::ios::basefield) == std::ios::hex && v != 0) { -+ rep.insert(2, width - rep.size(), os.fill()); -+ } else { -+ rep.insert(0, width - rep.size(), os.fill()); -+ } -+ } -+ -+ return os << rep; -+} -+ -+namespace { -+ -+uint128 UnsignedAbsoluteValue(int128 v) { -+ // Cast to uint128 before possibly negating because -Int128Min() is undefined. -+ return Int128High64(v) < 0 ? -uint128(v) : uint128(v); -+} -+ -+} // namespace -+ -+#if !defined(ABSL_HAVE_INTRINSIC_INT128) -+namespace { -+ -+template -+int128 MakeInt128FromFloat(T v) { -+ // Conversion when v is NaN or cannot fit into int128 would be undefined -+ // behavior if using an intrinsic 128-bit integer. -+ assert(std::isfinite(v) && (std::numeric_limits::max_exponent <= 127 || -+ (v >= -std::ldexp(static_cast(1), 127) && -+ v < std::ldexp(static_cast(1), 127)))); -+ -+ // We must convert the absolute value and then negate as needed, because -+ // floating point types are typically sign-magnitude. Otherwise, the -+ // difference between the high and low 64 bits when interpreted as two's -+ // complement overwhelms the precision of the mantissa. -+ uint128 result = v < 0 ? -MakeUint128FromFloat(-v) : MakeUint128FromFloat(v); -+ return MakeInt128(int128_internal::BitCastToSigned(Uint128High64(result)), -+ Uint128Low64(result)); -+} -+ -+} // namespace -+ -+int128::int128(float v) : int128(MakeInt128FromFloat(v)) {} -+int128::int128(double v) : int128(MakeInt128FromFloat(v)) {} -+int128::int128(long double v) : int128(MakeInt128FromFloat(v)) {} -+ -+int128 operator/(int128 lhs, int128 rhs) { -+ assert(lhs != Int128Min() || rhs != -1); // UB on two's complement. -+ -+ uint128 quotient = 0; -+ uint128 remainder = 0; -+ DivModImpl(UnsignedAbsoluteValue(lhs), UnsignedAbsoluteValue(rhs), -+ "ient, &remainder); -+ if ((Int128High64(lhs) < 0) != (Int128High64(rhs) < 0)) quotient = -quotient; -+ return MakeInt128(int128_internal::BitCastToSigned(Uint128High64(quotient)), -+ Uint128Low64(quotient)); -+} -+ -+int128 operator%(int128 lhs, int128 rhs) { -+ assert(lhs != Int128Min() || rhs != -1); // UB on two's complement. -+ -+ uint128 quotient = 0; -+ uint128 remainder = 0; -+ DivModImpl(UnsignedAbsoluteValue(lhs), UnsignedAbsoluteValue(rhs), -+ "ient, &remainder); -+ if (Int128High64(lhs) < 0) remainder = -remainder; -+ return MakeInt128(int128_internal::BitCastToSigned(Uint128High64(remainder)), -+ Uint128Low64(remainder)); -+} -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+std::ostream& operator<<(std::ostream& os, int128 v) { -+ std::ios_base::fmtflags flags = os.flags(); -+ std::string rep; -+ -+ // Add the sign if needed. -+ bool print_as_decimal = -+ (flags & std::ios::basefield) == std::ios::dec || -+ (flags & std::ios::basefield) == std::ios_base::fmtflags(); -+ if (print_as_decimal) { -+ if (Int128High64(v) < 0) { -+ rep = "-"; -+ } else if (flags & std::ios::showpos) { -+ rep = "+"; -+ } -+ } -+ -+ rep.append(Uint128ToFormattedString( -+ print_as_decimal ? UnsignedAbsoluteValue(v) : uint128(v), os.flags())); -+ -+ // Add the requisite padding. -+ std::streamsize width = os.width(0); -+ if (static_cast(width) > rep.size()) { -+ switch (flags & std::ios::adjustfield) { -+ case std::ios::left: -+ rep.append(width - rep.size(), os.fill()); -+ break; -+ case std::ios::internal: -+ if (print_as_decimal && (rep[0] == '+' || rep[0] == '-')) { -+ rep.insert(1, width - rep.size(), os.fill()); -+ } else if ((flags & std::ios::basefield) == std::ios::hex && -+ (flags & std::ios::showbase) && v != 0) { -+ rep.insert(2, width - rep.size(), os.fill()); -+ } else { -+ rep.insert(0, width - rep.size(), os.fill()); -+ } -+ break; -+ default: // std::ios::right -+ rep.insert(0, width - rep.size(), os.fill()); -+ break; -+ } -+ } -+ -+ return os << rep; -+} -+ -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+namespace std { -+constexpr bool numeric_limits::is_specialized; -+constexpr bool numeric_limits::is_signed; -+constexpr bool numeric_limits::is_integer; -+constexpr bool numeric_limits::is_exact; -+constexpr bool numeric_limits::has_infinity; -+constexpr bool numeric_limits::has_quiet_NaN; -+constexpr bool numeric_limits::has_signaling_NaN; -+constexpr float_denorm_style numeric_limits::has_denorm; -+constexpr bool numeric_limits::has_denorm_loss; -+constexpr float_round_style numeric_limits::round_style; -+constexpr bool numeric_limits::is_iec559; -+constexpr bool numeric_limits::is_bounded; -+constexpr bool numeric_limits::is_modulo; -+constexpr int numeric_limits::digits; -+constexpr int numeric_limits::digits10; -+constexpr int numeric_limits::max_digits10; -+constexpr int numeric_limits::radix; -+constexpr int numeric_limits::min_exponent; -+constexpr int numeric_limits::min_exponent10; -+constexpr int numeric_limits::max_exponent; -+constexpr int numeric_limits::max_exponent10; -+constexpr bool numeric_limits::traps; -+constexpr bool numeric_limits::tinyness_before; -+ -+constexpr bool numeric_limits::is_specialized; -+constexpr bool numeric_limits::is_signed; -+constexpr bool numeric_limits::is_integer; -+constexpr bool numeric_limits::is_exact; -+constexpr bool numeric_limits::has_infinity; -+constexpr bool numeric_limits::has_quiet_NaN; -+constexpr bool numeric_limits::has_signaling_NaN; -+constexpr float_denorm_style numeric_limits::has_denorm; -+constexpr bool numeric_limits::has_denorm_loss; -+constexpr float_round_style numeric_limits::round_style; -+constexpr bool numeric_limits::is_iec559; -+constexpr bool numeric_limits::is_bounded; -+constexpr bool numeric_limits::is_modulo; -+constexpr int numeric_limits::digits; -+constexpr int numeric_limits::digits10; -+constexpr int numeric_limits::max_digits10; -+constexpr int numeric_limits::radix; -+constexpr int numeric_limits::min_exponent; -+constexpr int numeric_limits::min_exponent10; -+constexpr int numeric_limits::max_exponent; -+constexpr int numeric_limits::max_exponent10; -+constexpr bool numeric_limits::traps; -+constexpr bool numeric_limits::tinyness_before; -+} // namespace std -diff --git a/extern/int128/absl/numeric/int128.h b/extern/int128/absl/numeric/int128.h -new file mode 100644 -index 0000000000..a9cbe489dd ---- /dev/null -+++ b/extern/int128/absl/numeric/int128.h -@@ -0,0 +1,1155 @@ -+// -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+// -+// ----------------------------------------------------------------------------- -+// File: int128.h -+// ----------------------------------------------------------------------------- -+// -+// This header file defines 128-bit integer types, `uint128` and `int128`. -+// -+// TODO(absl-team): This module is inconsistent as many inline `uint128` methods -+// are defined in this file, while many inline `int128` methods are defined in -+// the `int128_*_intrinsic.inc` files. -+ -+#ifndef ABSL_NUMERIC_INT128_H_ -+#define ABSL_NUMERIC_INT128_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "absl/base/config.h" -+#include "absl/base/macros.h" -+#include "absl/base/port.h" -+ -+#if defined(_MSC_VER) -+// In very old versions of MSVC and when the /Zc:wchar_t flag is off, wchar_t is -+// a typedef for unsigned short. Otherwise wchar_t is mapped to the __wchar_t -+// builtin type. We need to make sure not to define operator wchar_t() -+// alongside operator unsigned short() in these instances. -+#define ABSL_INTERNAL_WCHAR_T __wchar_t -+#if defined(_M_X64) -+#include -+#pragma intrinsic(_umul128) -+#endif // defined(_M_X64) -+#else // defined(_MSC_VER) -+#define ABSL_INTERNAL_WCHAR_T wchar_t -+#endif // defined(_MSC_VER) -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+ -+class int128; -+ -+// uint128 -+// -+// An unsigned 128-bit integer type. The API is meant to mimic an intrinsic type -+// as closely as is practical, including exhibiting undefined behavior in -+// analogous cases (e.g. division by zero). This type is intended to be a -+// drop-in replacement once C++ supports an intrinsic `uint128_t` type; when -+// that occurs, existing well-behaved uses of `uint128` will continue to work -+// using that new type. -+// -+// Note: code written with this type will continue to compile once `uint128_t` -+// is introduced, provided the replacement helper functions -+// `Uint128(Low|High)64()` and `MakeUint128()` are made. -+// -+// A `uint128` supports the following: -+// -+// * Implicit construction from integral types -+// * Explicit conversion to integral types -+// -+// Additionally, if your compiler supports `__int128`, `uint128` is -+// interoperable with that type. (Abseil checks for this compatibility through -+// the `ABSL_HAVE_INTRINSIC_INT128` macro.) -+// -+// However, a `uint128` differs from intrinsic integral types in the following -+// ways: -+// -+// * Errors on implicit conversions that do not preserve value (such as -+// loss of precision when converting to float values). -+// * Requires explicit construction from and conversion to floating point -+// types. -+// * Conversion to integral types requires an explicit static_cast() to -+// mimic use of the `-Wnarrowing` compiler flag. -+// * The alignment requirement of `uint128` may differ from that of an -+// intrinsic 128-bit integer type depending on platform and build -+// configuration. -+// -+// Example: -+// -+// float y = absl::Uint128Max(); // Error. uint128 cannot be implicitly -+// // converted to float. -+// -+// absl::uint128 v; -+// uint64_t i = v; // Error -+// uint64_t i = static_cast(v); // OK -+// -+class -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ alignas(unsigned __int128) -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ uint128 { -+ public: -+ uint128() = default; -+ -+ // Constructors from arithmetic types -+ constexpr uint128(int v); // NOLINT(runtime/explicit) -+ constexpr uint128(unsigned int v); // NOLINT(runtime/explicit) -+ constexpr uint128(long v); // NOLINT(runtime/int) -+ constexpr uint128(unsigned long v); // NOLINT(runtime/int) -+ constexpr uint128(long long v); // NOLINT(runtime/int) -+ constexpr uint128(unsigned long long v); // NOLINT(runtime/int) -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ constexpr uint128(__int128 v); // NOLINT(runtime/explicit) -+ constexpr uint128(unsigned __int128 v); // NOLINT(runtime/explicit) -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ constexpr uint128(int128 v); // NOLINT(runtime/explicit) -+ explicit uint128(float v); -+ explicit uint128(double v); -+ explicit uint128(long double v); -+ -+ // Assignment operators from arithmetic types -+ uint128& operator=(int v); -+ uint128& operator=(unsigned int v); -+ uint128& operator=(long v); // NOLINT(runtime/int) -+ uint128& operator=(unsigned long v); // NOLINT(runtime/int) -+ uint128& operator=(long long v); // NOLINT(runtime/int) -+ uint128& operator=(unsigned long long v); // NOLINT(runtime/int) -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ uint128& operator=(__int128 v); -+ uint128& operator=(unsigned __int128 v); -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ uint128& operator=(int128 v); -+ -+ // Conversion operators to other arithmetic types -+ constexpr explicit operator bool() const; -+ constexpr explicit operator char() const; -+ constexpr explicit operator signed char() const; -+ constexpr explicit operator unsigned char() const; -+ constexpr explicit operator char16_t() const; -+ constexpr explicit operator char32_t() const; -+ constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const; -+ constexpr explicit operator short() const; // NOLINT(runtime/int) -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator unsigned short() const; -+ constexpr explicit operator int() const; -+ constexpr explicit operator unsigned int() const; -+ constexpr explicit operator long() const; // NOLINT(runtime/int) -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator unsigned long() const; -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator long long() const; -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator unsigned long long() const; -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ constexpr explicit operator __int128() const; -+ constexpr explicit operator unsigned __int128() const; -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ explicit operator float() const; -+ explicit operator double() const; -+ explicit operator long double() const; -+ -+ // Trivial copy constructor, assignment operator and destructor. -+ -+ // Arithmetic operators. -+ uint128& operator+=(uint128 other); -+ uint128& operator-=(uint128 other); -+ uint128& operator*=(uint128 other); -+ // Long division/modulo for uint128. -+ uint128& operator/=(uint128 other); -+ uint128& operator%=(uint128 other); -+ uint128 operator++(int); -+ uint128 operator--(int); -+ uint128& operator<<=(int); -+ uint128& operator>>=(int); -+ uint128& operator&=(uint128 other); -+ uint128& operator|=(uint128 other); -+ uint128& operator^=(uint128 other); -+ uint128& operator++(); -+ uint128& operator--(); -+ -+ // Uint128Low64() -+ // -+ // Returns the lower 64-bit value of a `uint128` value. -+ friend constexpr uint64_t Uint128Low64(uint128 v); -+ -+ // Uint128High64() -+ // -+ // Returns the higher 64-bit value of a `uint128` value. -+ friend constexpr uint64_t Uint128High64(uint128 v); -+ -+ // MakeUInt128() -+ // -+ // Constructs a `uint128` numeric value from two 64-bit unsigned integers. -+ // Note that this factory function is the only way to construct a `uint128` -+ // from integer values greater than 2^64. -+ // -+ // Example: -+ // -+ // absl::uint128 big = absl::MakeUint128(1, 0); -+ friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low); -+ -+ // Uint128Max() -+ // -+ // Returns the highest value for a 128-bit unsigned integer. -+ friend constexpr uint128 Uint128Max(); -+ -+ // Support for absl::Hash. -+ template -+ friend H AbslHashValue(H h, uint128 v) { -+ return H::combine(std::move(h), Uint128High64(v), Uint128Low64(v)); -+ } -+ -+ private: -+ constexpr uint128(uint64_t high, uint64_t low); -+ -+ // TODO(strel) Update implementation to use __int128 once all users of -+ // uint128 are fixed to not depend on alignof(uint128) == 8. Also add -+ // alignas(16) to class definition to keep alignment consistent across -+ // platforms. -+#if defined(ABSL_IS_LITTLE_ENDIAN) -+ uint64_t lo_; -+ uint64_t hi_; -+#elif defined(ABSL_IS_BIG_ENDIAN) -+ uint64_t hi_; -+ uint64_t lo_; -+#else // byte order -+#error "Unsupported byte order: must be little-endian or big-endian." -+#endif // byte order -+}; -+ -+// Prefer to use the constexpr `Uint128Max()`. -+// -+// TODO(absl-team) deprecate kuint128max once migration tool is released. -+ABSL_DLL extern const uint128 kuint128max; -+ -+// allow uint128 to be logged -+std::ostream& operator<<(std::ostream& os, uint128 v); -+ -+// TODO(strel) add operator>>(std::istream&, uint128) -+ -+constexpr uint128 Uint128Max() { -+ return uint128((std::numeric_limits::max)(), -+ (std::numeric_limits::max)()); -+} -+ -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+// Specialized numeric_limits for uint128. -+namespace std { -+template <> -+class numeric_limits { -+ public: -+ static constexpr bool is_specialized = true; -+ static constexpr bool is_signed = false; -+ static constexpr bool is_integer = true; -+ static constexpr bool is_exact = true; -+ static constexpr bool has_infinity = false; -+ static constexpr bool has_quiet_NaN = false; -+ static constexpr bool has_signaling_NaN = false; -+ static constexpr float_denorm_style has_denorm = denorm_absent; -+ static constexpr bool has_denorm_loss = false; -+ static constexpr float_round_style round_style = round_toward_zero; -+ static constexpr bool is_iec559 = false; -+ static constexpr bool is_bounded = true; -+ static constexpr bool is_modulo = true; -+ static constexpr int digits = 128; -+ static constexpr int digits10 = 38; -+ static constexpr int max_digits10 = 0; -+ static constexpr int radix = 2; -+ static constexpr int min_exponent = 0; -+ static constexpr int min_exponent10 = 0; -+ static constexpr int max_exponent = 0; -+ static constexpr int max_exponent10 = 0; -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ static constexpr bool traps = numeric_limits::traps; -+#else // ABSL_HAVE_INTRINSIC_INT128 -+ static constexpr bool traps = numeric_limits::traps; -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ static constexpr bool tinyness_before = false; -+ -+ static constexpr absl::uint128 (min)() { return 0; } -+ static constexpr absl::uint128 lowest() { return 0; } -+ static constexpr absl::uint128 (max)() { return absl::Uint128Max(); } -+ static constexpr absl::uint128 epsilon() { return 0; } -+ static constexpr absl::uint128 round_error() { return 0; } -+ static constexpr absl::uint128 infinity() { return 0; } -+ static constexpr absl::uint128 quiet_NaN() { return 0; } -+ static constexpr absl::uint128 signaling_NaN() { return 0; } -+ static constexpr absl::uint128 denorm_min() { return 0; } -+}; -+} // namespace std -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+ -+// int128 -+// -+// A signed 128-bit integer type. The API is meant to mimic an intrinsic -+// integral type as closely as is practical, including exhibiting undefined -+// behavior in analogous cases (e.g. division by zero). -+// -+// An `int128` supports the following: -+// -+// * Implicit construction from integral types -+// * Explicit conversion to integral types -+// -+// However, an `int128` differs from intrinsic integral types in the following -+// ways: -+// -+// * It is not implicitly convertible to other integral types. -+// * Requires explicit construction from and conversion to floating point -+// types. -+ -+// Additionally, if your compiler supports `__int128`, `int128` is -+// interoperable with that type. (Abseil checks for this compatibility through -+// the `ABSL_HAVE_INTRINSIC_INT128` macro.) -+// -+// The design goal for `int128` is that it will be compatible with a future -+// `int128_t`, if that type becomes a part of the standard. -+// -+// Example: -+// -+// float y = absl::int128(17); // Error. int128 cannot be implicitly -+// // converted to float. -+// -+// absl::int128 v; -+// int64_t i = v; // Error -+// int64_t i = static_cast(v); // OK -+// -+class int128 { -+ public: -+ int128() = default; -+ -+ // Constructors from arithmetic types -+ constexpr int128(int v); // NOLINT(runtime/explicit) -+ constexpr int128(unsigned int v); // NOLINT(runtime/explicit) -+ constexpr int128(long v); // NOLINT(runtime/int) -+ constexpr int128(unsigned long v); // NOLINT(runtime/int) -+ constexpr int128(long long v); // NOLINT(runtime/int) -+ constexpr int128(unsigned long long v); // NOLINT(runtime/int) -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ constexpr int128(__int128 v); // NOLINT(runtime/explicit) -+ constexpr explicit int128(unsigned __int128 v); -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ constexpr explicit int128(uint128 v); -+ explicit int128(float v); -+ explicit int128(double v); -+ explicit int128(long double v); -+ -+ // Assignment operators from arithmetic types -+ int128& operator=(int v); -+ int128& operator=(unsigned int v); -+ int128& operator=(long v); // NOLINT(runtime/int) -+ int128& operator=(unsigned long v); // NOLINT(runtime/int) -+ int128& operator=(long long v); // NOLINT(runtime/int) -+ int128& operator=(unsigned long long v); // NOLINT(runtime/int) -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ int128& operator=(__int128 v); -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+ // Conversion operators to other arithmetic types -+ constexpr explicit operator bool() const; -+ constexpr explicit operator char() const; -+ constexpr explicit operator signed char() const; -+ constexpr explicit operator unsigned char() const; -+ constexpr explicit operator char16_t() const; -+ constexpr explicit operator char32_t() const; -+ constexpr explicit operator ABSL_INTERNAL_WCHAR_T() const; -+ constexpr explicit operator short() const; // NOLINT(runtime/int) -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator unsigned short() const; -+ constexpr explicit operator int() const; -+ constexpr explicit operator unsigned int() const; -+ constexpr explicit operator long() const; // NOLINT(runtime/int) -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator unsigned long() const; -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator long long() const; -+ // NOLINTNEXTLINE(runtime/int) -+ constexpr explicit operator unsigned long long() const; -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ constexpr explicit operator __int128() const; -+ constexpr explicit operator unsigned __int128() const; -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ explicit operator float() const; -+ explicit operator double() const; -+ explicit operator long double() const; -+ -+ // Trivial copy constructor, assignment operator and destructor. -+ -+ // Arithmetic operators -+ int128& operator+=(int128 other); -+ int128& operator-=(int128 other); -+ int128& operator*=(int128 other); -+ int128& operator/=(int128 other); -+ int128& operator%=(int128 other); -+ int128 operator++(int); // postfix increment: i++ -+ int128 operator--(int); // postfix decrement: i-- -+ int128& operator++(); // prefix increment: ++i -+ int128& operator--(); // prefix decrement: --i -+ int128& operator&=(int128 other); -+ int128& operator|=(int128 other); -+ int128& operator^=(int128 other); -+ int128& operator<<=(int amount); -+ int128& operator>>=(int amount); -+ -+ // Int128Low64() -+ // -+ // Returns the lower 64-bit value of a `int128` value. -+ friend constexpr uint64_t Int128Low64(int128 v); -+ -+ // Int128High64() -+ // -+ // Returns the higher 64-bit value of a `int128` value. -+ friend constexpr int64_t Int128High64(int128 v); -+ -+ // MakeInt128() -+ // -+ // Constructs a `int128` numeric value from two 64-bit integers. Note that -+ // signedness is conveyed in the upper `high` value. -+ // -+ // (absl::int128(1) << 64) * high + low -+ // -+ // Note that this factory function is the only way to construct a `int128` -+ // from integer values greater than 2^64 or less than -2^64. -+ // -+ // Example: -+ // -+ // absl::int128 big = absl::MakeInt128(1, 0); -+ // absl::int128 big_n = absl::MakeInt128(-1, 0); -+ friend constexpr int128 MakeInt128(int64_t high, uint64_t low); -+ -+ // Int128Max() -+ // -+ // Returns the maximum value for a 128-bit signed integer. -+ friend constexpr int128 Int128Max(); -+ -+ // Int128Min() -+ // -+ // Returns the minimum value for a 128-bit signed integer. -+ friend constexpr int128 Int128Min(); -+ -+ // Support for absl::Hash. -+ template -+ friend H AbslHashValue(H h, int128 v) { -+ return H::combine(std::move(h), Int128High64(v), Int128Low64(v)); -+ } -+ -+ private: -+ constexpr int128(int64_t high, uint64_t low); -+ -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ __int128 v_; -+#else // ABSL_HAVE_INTRINSIC_INT128 -+#if defined(ABSL_IS_LITTLE_ENDIAN) -+ uint64_t lo_; -+ int64_t hi_; -+#elif defined(ABSL_IS_BIG_ENDIAN) -+ int64_t hi_; -+ uint64_t lo_; -+#else // byte order -+#error "Unsupported byte order: must be little-endian or big-endian." -+#endif // byte order -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+}; -+ -+std::ostream& operator<<(std::ostream& os, int128 v); -+ -+// TODO(absl-team) add operator>>(std::istream&, int128) -+ -+constexpr int128 Int128Max() { -+ return int128((std::numeric_limits::max)(), -+ (std::numeric_limits::max)()); -+} -+ -+constexpr int128 Int128Min() { -+ return int128((std::numeric_limits::min)(), 0); -+} -+ -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+// Specialized numeric_limits for int128. -+namespace std { -+template <> -+class numeric_limits { -+ public: -+ static constexpr bool is_specialized = true; -+ static constexpr bool is_signed = true; -+ static constexpr bool is_integer = true; -+ static constexpr bool is_exact = true; -+ static constexpr bool has_infinity = false; -+ static constexpr bool has_quiet_NaN = false; -+ static constexpr bool has_signaling_NaN = false; -+ static constexpr float_denorm_style has_denorm = denorm_absent; -+ static constexpr bool has_denorm_loss = false; -+ static constexpr float_round_style round_style = round_toward_zero; -+ static constexpr bool is_iec559 = false; -+ static constexpr bool is_bounded = true; -+ static constexpr bool is_modulo = false; -+ static constexpr int digits = 127; -+ static constexpr int digits10 = 38; -+ static constexpr int max_digits10 = 0; -+ static constexpr int radix = 2; -+ static constexpr int min_exponent = 0; -+ static constexpr int min_exponent10 = 0; -+ static constexpr int max_exponent = 0; -+ static constexpr int max_exponent10 = 0; -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ static constexpr bool traps = numeric_limits<__int128>::traps; -+#else // ABSL_HAVE_INTRINSIC_INT128 -+ static constexpr bool traps = numeric_limits::traps; -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ static constexpr bool tinyness_before = false; -+ -+ static constexpr absl::int128 (min)() { return absl::Int128Min(); } -+ static constexpr absl::int128 lowest() { return absl::Int128Min(); } -+ static constexpr absl::int128 (max)() { return absl::Int128Max(); } -+ static constexpr absl::int128 epsilon() { return 0; } -+ static constexpr absl::int128 round_error() { return 0; } -+ static constexpr absl::int128 infinity() { return 0; } -+ static constexpr absl::int128 quiet_NaN() { return 0; } -+ static constexpr absl::int128 signaling_NaN() { return 0; } -+ static constexpr absl::int128 denorm_min() { return 0; } -+}; -+} // namespace std -+ -+// -------------------------------------------------------------------------- -+// Implementation details follow -+// -------------------------------------------------------------------------- -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+ -+constexpr uint128 MakeUint128(uint64_t high, uint64_t low) { -+ return uint128(high, low); -+} -+ -+// Assignment from integer types. -+ -+inline uint128& uint128::operator=(int v) { return *this = uint128(v); } -+ -+inline uint128& uint128::operator=(unsigned int v) { -+ return *this = uint128(v); -+} -+ -+inline uint128& uint128::operator=(long v) { // NOLINT(runtime/int) -+ return *this = uint128(v); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+inline uint128& uint128::operator=(unsigned long v) { -+ return *this = uint128(v); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+inline uint128& uint128::operator=(long long v) { -+ return *this = uint128(v); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+inline uint128& uint128::operator=(unsigned long long v) { -+ return *this = uint128(v); -+} -+ -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+inline uint128& uint128::operator=(__int128 v) { -+ return *this = uint128(v); -+} -+ -+inline uint128& uint128::operator=(unsigned __int128 v) { -+ return *this = uint128(v); -+} -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+inline uint128& uint128::operator=(int128 v) { -+ return *this = uint128(v); -+} -+ -+// Arithmetic operators. -+ -+uint128 operator<<(uint128 lhs, int amount); -+uint128 operator>>(uint128 lhs, int amount); -+uint128 operator+(uint128 lhs, uint128 rhs); -+uint128 operator-(uint128 lhs, uint128 rhs); -+uint128 operator*(uint128 lhs, uint128 rhs); -+uint128 operator/(uint128 lhs, uint128 rhs); -+uint128 operator%(uint128 lhs, uint128 rhs); -+ -+inline uint128& uint128::operator<<=(int amount) { -+ *this = *this << amount; -+ return *this; -+} -+ -+inline uint128& uint128::operator>>=(int amount) { -+ *this = *this >> amount; -+ return *this; -+} -+ -+inline uint128& uint128::operator+=(uint128 other) { -+ *this = *this + other; -+ return *this; -+} -+ -+inline uint128& uint128::operator-=(uint128 other) { -+ *this = *this - other; -+ return *this; -+} -+ -+inline uint128& uint128::operator*=(uint128 other) { -+ *this = *this * other; -+ return *this; -+} -+ -+inline uint128& uint128::operator/=(uint128 other) { -+ *this = *this / other; -+ return *this; -+} -+ -+inline uint128& uint128::operator%=(uint128 other) { -+ *this = *this % other; -+ return *this; -+} -+ -+constexpr uint64_t Uint128Low64(uint128 v) { return v.lo_; } -+ -+constexpr uint64_t Uint128High64(uint128 v) { return v.hi_; } -+ -+// Constructors from integer types. -+ -+#if defined(ABSL_IS_LITTLE_ENDIAN) -+ -+constexpr uint128::uint128(uint64_t high, uint64_t low) -+ : lo_{low}, hi_{high} {} -+ -+constexpr uint128::uint128(int v) -+ : lo_{static_cast(v)}, -+ hi_{v < 0 ? (std::numeric_limits::max)() : 0} {} -+constexpr uint128::uint128(long v) // NOLINT(runtime/int) -+ : lo_{static_cast(v)}, -+ hi_{v < 0 ? (std::numeric_limits::max)() : 0} {} -+constexpr uint128::uint128(long long v) // NOLINT(runtime/int) -+ : lo_{static_cast(v)}, -+ hi_{v < 0 ? (std::numeric_limits::max)() : 0} {} -+ -+constexpr uint128::uint128(unsigned int v) : lo_{v}, hi_{0} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr uint128::uint128(unsigned long v) : lo_{v}, hi_{0} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr uint128::uint128(unsigned long long v) : lo_{v}, hi_{0} {} -+ -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+constexpr uint128::uint128(__int128 v) -+ : lo_{static_cast(v & ~uint64_t{0})}, -+ hi_{static_cast(static_cast(v) >> 64)} {} -+constexpr uint128::uint128(unsigned __int128 v) -+ : lo_{static_cast(v & ~uint64_t{0})}, -+ hi_{static_cast(v >> 64)} {} -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+constexpr uint128::uint128(int128 v) -+ : lo_{Int128Low64(v)}, hi_{static_cast(Int128High64(v))} {} -+ -+#elif defined(ABSL_IS_BIG_ENDIAN) -+ -+constexpr uint128::uint128(uint64_t high, uint64_t low) -+ : hi_{high}, lo_{low} {} -+ -+constexpr uint128::uint128(int v) -+ : hi_{v < 0 ? (std::numeric_limits::max)() : 0}, -+ lo_{static_cast(v)} {} -+constexpr uint128::uint128(long v) // NOLINT(runtime/int) -+ : hi_{v < 0 ? (std::numeric_limits::max)() : 0}, -+ lo_{static_cast(v)} {} -+constexpr uint128::uint128(long long v) // NOLINT(runtime/int) -+ : hi_{v < 0 ? (std::numeric_limits::max)() : 0}, -+ lo_{static_cast(v)} {} -+ -+constexpr uint128::uint128(unsigned int v) : hi_{0}, lo_{v} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr uint128::uint128(unsigned long v) : hi_{0}, lo_{v} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr uint128::uint128(unsigned long long v) : hi_{0}, lo_{v} {} -+ -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+constexpr uint128::uint128(__int128 v) -+ : hi_{static_cast(static_cast(v) >> 64)}, -+ lo_{static_cast(v & ~uint64_t{0})} {} -+constexpr uint128::uint128(unsigned __int128 v) -+ : hi_{static_cast(v >> 64)}, -+ lo_{static_cast(v & ~uint64_t{0})} {} -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+constexpr uint128::uint128(int128 v) -+ : hi_{static_cast(Int128High64(v))}, lo_{Int128Low64(v)} {} -+ -+#else // byte order -+#error "Unsupported byte order: must be little-endian or big-endian." -+#endif // byte order -+ -+// Conversion operators to integer types. -+ -+constexpr uint128::operator bool() const { return lo_ || hi_; } -+ -+constexpr uint128::operator char() const { return static_cast(lo_); } -+ -+constexpr uint128::operator signed char() const { -+ return static_cast(lo_); -+} -+ -+constexpr uint128::operator unsigned char() const { -+ return static_cast(lo_); -+} -+ -+constexpr uint128::operator char16_t() const { -+ return static_cast(lo_); -+} -+ -+constexpr uint128::operator char32_t() const { -+ return static_cast(lo_); -+} -+ -+constexpr uint128::operator ABSL_INTERNAL_WCHAR_T() const { -+ return static_cast(lo_); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+constexpr uint128::operator short() const { return static_cast(lo_); } -+ -+constexpr uint128::operator unsigned short() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+constexpr uint128::operator int() const { return static_cast(lo_); } -+ -+constexpr uint128::operator unsigned int() const { -+ return static_cast(lo_); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+constexpr uint128::operator long() const { return static_cast(lo_); } -+ -+constexpr uint128::operator unsigned long() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+constexpr uint128::operator long long() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+constexpr uint128::operator unsigned long long() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+constexpr uint128::operator __int128() const { -+ return (static_cast<__int128>(hi_) << 64) + lo_; -+} -+ -+constexpr uint128::operator unsigned __int128() const { -+ return (static_cast(hi_) << 64) + lo_; -+} -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+// Conversion operators to floating point types. -+ -+inline uint128::operator float() const { -+ return static_cast(lo_) + std::ldexp(static_cast(hi_), 64); -+} -+ -+inline uint128::operator double() const { -+ return static_cast(lo_) + std::ldexp(static_cast(hi_), 64); -+} -+ -+inline uint128::operator long double() const { -+ return static_cast(lo_) + -+ std::ldexp(static_cast(hi_), 64); -+} -+ -+// Comparison operators. -+ -+inline bool operator==(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return static_cast(lhs) == -+ static_cast(rhs); -+#else -+ return (Uint128Low64(lhs) == Uint128Low64(rhs) && -+ Uint128High64(lhs) == Uint128High64(rhs)); -+#endif -+} -+ -+inline bool operator!=(uint128 lhs, uint128 rhs) { -+ return !(lhs == rhs); -+} -+ -+inline bool operator<(uint128 lhs, uint128 rhs) { -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ return static_cast(lhs) < -+ static_cast(rhs); -+#else -+ return (Uint128High64(lhs) == Uint128High64(rhs)) -+ ? (Uint128Low64(lhs) < Uint128Low64(rhs)) -+ : (Uint128High64(lhs) < Uint128High64(rhs)); -+#endif -+} -+ -+inline bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } -+ -+inline bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); } -+ -+inline bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); } -+ -+// Unary operators. -+ -+constexpr inline uint128 operator+(uint128 val) { -+ return val; -+} -+ -+constexpr inline int128 operator+(int128 val) { -+ return val; -+} -+ -+inline uint128 operator-(uint128 val) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return -static_cast(val); -+#else -+ uint64_t hi = ~Uint128High64(val); -+ uint64_t lo = ~Uint128Low64(val) + 1; -+ if (lo == 0) ++hi; // carry -+ return MakeUint128(hi, lo); -+#endif -+} -+ -+constexpr inline bool operator!(uint128 val) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return !static_cast(val); -+#else -+ return !Uint128High64(val) && !Uint128Low64(val); -+#endif -+} -+ -+// Logical operators. -+ -+constexpr inline uint128 operator~(uint128 val) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return ~static_cast(val); -+#else -+ return MakeUint128(~Uint128High64(val), ~Uint128Low64(val)); -+#endif -+} -+ -+constexpr inline uint128 operator|(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return static_cast(lhs) | -+ static_cast(rhs); -+#else -+ return MakeUint128(Uint128High64(lhs) | Uint128High64(rhs), -+ Uint128Low64(lhs) | Uint128Low64(rhs)); -+#endif -+} -+ -+constexpr inline uint128 operator&(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return static_cast(lhs) & -+ static_cast(rhs); -+#else -+ return MakeUint128(Uint128High64(lhs) & Uint128High64(rhs), -+ Uint128Low64(lhs) & Uint128Low64(rhs)); -+#endif -+} -+ -+constexpr inline uint128 operator^(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return static_cast(lhs) ^ -+ static_cast(rhs); -+#else -+ return MakeUint128(Uint128High64(lhs) ^ Uint128High64(rhs), -+ Uint128Low64(lhs) ^ Uint128Low64(rhs)); -+#endif -+} -+ -+inline uint128& uint128::operator|=(uint128 other) { -+ *this = *this | other; -+ return *this; -+} -+ -+inline uint128& uint128::operator&=(uint128 other) { -+ *this = *this & other; -+ return *this; -+} -+ -+inline uint128& uint128::operator^=(uint128 other) { -+ *this = *this ^ other; -+ return *this; -+} -+ -+// Arithmetic operators. -+ -+inline uint128 operator<<(uint128 lhs, int amount) { -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ return static_cast(lhs) << amount; -+#else -+ // uint64_t shifts of >= 64 are undefined, so we will need some -+ // special-casing. -+ if (amount < 64) { -+ if (amount != 0) { -+ return MakeUint128( -+ (Uint128High64(lhs) << amount) | (Uint128Low64(lhs) >> (64 - amount)), -+ Uint128Low64(lhs) << amount); -+ } -+ return lhs; -+ } -+ return MakeUint128(Uint128Low64(lhs) << (amount - 64), 0); -+#endif -+} -+ -+inline uint128 operator>>(uint128 lhs, int amount) { -+#ifdef ABSL_HAVE_INTRINSIC_INT128 -+ return static_cast(lhs) >> amount; -+#else -+ // uint64_t shifts of >= 64 are undefined, so we will need some -+ // special-casing. -+ if (amount < 64) { -+ if (amount != 0) { -+ return MakeUint128(Uint128High64(lhs) >> amount, -+ (Uint128Low64(lhs) >> amount) | -+ (Uint128High64(lhs) << (64 - amount))); -+ } -+ return lhs; -+ } -+ return MakeUint128(0, Uint128High64(lhs) >> (amount - 64)); -+#endif -+} -+ -+inline uint128 operator+(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return static_cast(lhs) + -+ static_cast(rhs); -+#else -+ uint128 result = MakeUint128(Uint128High64(lhs) + Uint128High64(rhs), -+ Uint128Low64(lhs) + Uint128Low64(rhs)); -+ if (Uint128Low64(result) < Uint128Low64(lhs)) { // check for carry -+ return MakeUint128(Uint128High64(result) + 1, Uint128Low64(result)); -+ } -+ return result; -+#endif -+} -+ -+inline uint128 operator-(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ return static_cast(lhs) - -+ static_cast(rhs); -+#else -+ uint128 result = MakeUint128(Uint128High64(lhs) - Uint128High64(rhs), -+ Uint128Low64(lhs) - Uint128Low64(rhs)); -+ if (Uint128Low64(lhs) < Uint128Low64(rhs)) { // check for carry -+ return MakeUint128(Uint128High64(result) - 1, Uint128Low64(result)); -+ } -+ return result; -+#endif -+} -+ -+inline uint128 operator*(uint128 lhs, uint128 rhs) { -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+ // TODO(strel) Remove once alignment issues are resolved and unsigned __int128 -+ // can be used for uint128 storage. -+ return static_cast(lhs) * -+ static_cast(rhs); -+#elif defined(_MSC_VER) && defined(_M_X64) -+ uint64_t carry; -+ uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry); -+ return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) + -+ Uint128High64(lhs) * Uint128Low64(rhs) + carry, -+ low); -+#else // ABSL_HAVE_INTRINSIC128 -+ uint64_t a32 = Uint128Low64(lhs) >> 32; -+ uint64_t a00 = Uint128Low64(lhs) & 0xffffffff; -+ uint64_t b32 = Uint128Low64(rhs) >> 32; -+ uint64_t b00 = Uint128Low64(rhs) & 0xffffffff; -+ uint128 result = -+ MakeUint128(Uint128High64(lhs) * Uint128Low64(rhs) + -+ Uint128Low64(lhs) * Uint128High64(rhs) + a32 * b32, -+ a00 * b00); -+ result += uint128(a32 * b00) << 32; -+ result += uint128(a00 * b32) << 32; -+ return result; -+#endif // ABSL_HAVE_INTRINSIC128 -+} -+ -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+inline uint128 operator/(uint128 lhs, uint128 rhs) { -+ return static_cast(lhs) / -+ static_cast(rhs); -+} -+ -+inline uint128 operator%(uint128 lhs, uint128 rhs) { -+ return static_cast(lhs) % -+ static_cast(rhs); -+} -+#endif -+ -+// Increment/decrement operators. -+ -+inline uint128 uint128::operator++(int) { -+ uint128 tmp(*this); -+ *this += 1; -+ return tmp; -+} -+ -+inline uint128 uint128::operator--(int) { -+ uint128 tmp(*this); -+ *this -= 1; -+ return tmp; -+} -+ -+inline uint128& uint128::operator++() { -+ *this += 1; -+ return *this; -+} -+ -+inline uint128& uint128::operator--() { -+ *this -= 1; -+ return *this; -+} -+ -+constexpr int128 MakeInt128(int64_t high, uint64_t low) { -+ return int128(high, low); -+} -+ -+// Assignment from integer types. -+inline int128& int128::operator=(int v) { -+ return *this = int128(v); -+} -+ -+inline int128& int128::operator=(unsigned int v) { -+ return *this = int128(v); -+} -+ -+inline int128& int128::operator=(long v) { // NOLINT(runtime/int) -+ return *this = int128(v); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+inline int128& int128::operator=(unsigned long v) { -+ return *this = int128(v); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+inline int128& int128::operator=(long long v) { -+ return *this = int128(v); -+} -+ -+// NOLINTNEXTLINE(runtime/int) -+inline int128& int128::operator=(unsigned long long v) { -+ return *this = int128(v); -+} -+ -+// Arithmetic operators. -+ -+int128 operator+(int128 lhs, int128 rhs); -+int128 operator-(int128 lhs, int128 rhs); -+int128 operator*(int128 lhs, int128 rhs); -+int128 operator/(int128 lhs, int128 rhs); -+int128 operator%(int128 lhs, int128 rhs); -+int128 operator|(int128 lhs, int128 rhs); -+int128 operator&(int128 lhs, int128 rhs); -+int128 operator^(int128 lhs, int128 rhs); -+int128 operator<<(int128 lhs, int amount); -+int128 operator>>(int128 lhs, int amount); -+ -+inline int128& int128::operator+=(int128 other) { -+ *this = *this + other; -+ return *this; -+} -+ -+inline int128& int128::operator-=(int128 other) { -+ *this = *this - other; -+ return *this; -+} -+ -+inline int128& int128::operator*=(int128 other) { -+ *this = *this * other; -+ return *this; -+} -+ -+inline int128& int128::operator/=(int128 other) { -+ *this = *this / other; -+ return *this; -+} -+ -+inline int128& int128::operator%=(int128 other) { -+ *this = *this % other; -+ return *this; -+} -+ -+inline int128& int128::operator|=(int128 other) { -+ *this = *this | other; -+ return *this; -+} -+ -+inline int128& int128::operator&=(int128 other) { -+ *this = *this & other; -+ return *this; -+} -+ -+inline int128& int128::operator^=(int128 other) { -+ *this = *this ^ other; -+ return *this; -+} -+ -+inline int128& int128::operator<<=(int amount) { -+ *this = *this << amount; -+ return *this; -+} -+ -+inline int128& int128::operator>>=(int amount) { -+ *this = *this >> amount; -+ return *this; -+} -+ -+namespace int128_internal { -+ -+// Casts from unsigned to signed while preserving the underlying binary -+// representation. -+constexpr int64_t BitCastToSigned(uint64_t v) { -+ // Casting an unsigned integer to a signed integer of the same -+ // width is implementation defined behavior if the source value would not fit -+ // in the destination type. We step around it with a roundtrip bitwise not -+ // operation to make sure this function remains constexpr. Clang, GCC, and -+ // MSVC optimize this to a no-op on x86-64. -+ return v & (uint64_t{1} << 63) ? ~static_cast(~v) -+ : static_cast(v); -+} -+ -+} // namespace int128_internal -+ -+#if defined(ABSL_HAVE_INTRINSIC_INT128) -+#include "absl/numeric/int128_have_intrinsic.inc" // IWYU pragma: export -+#else // ABSL_HAVE_INTRINSIC_INT128 -+#include "absl/numeric/int128_no_intrinsic.inc" // IWYU pragma: export -+#endif // ABSL_HAVE_INTRINSIC_INT128 -+ -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+#undef ABSL_INTERNAL_WCHAR_T -+ -+#endif // ABSL_NUMERIC_INT128_H_ -diff --git a/extern/int128/absl/numeric/int128_have_intrinsic.inc b/extern/int128/absl/numeric/int128_have_intrinsic.inc -new file mode 100644 -index 0000000000..d6c76dd320 ---- /dev/null -+++ b/extern/int128/absl/numeric/int128_have_intrinsic.inc -@@ -0,0 +1,302 @@ -+// -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+// This file contains :int128 implementation details that depend on internal -+// representation when ABSL_HAVE_INTRINSIC_INT128 is defined. This file is -+// included by int128.h and relies on ABSL_INTERNAL_WCHAR_T being defined. -+ -+namespace int128_internal { -+ -+// Casts from unsigned to signed while preserving the underlying binary -+// representation. -+constexpr __int128 BitCastToSigned(unsigned __int128 v) { -+ // Casting an unsigned integer to a signed integer of the same -+ // width is implementation defined behavior if the source value would not fit -+ // in the destination type. We step around it with a roundtrip bitwise not -+ // operation to make sure this function remains constexpr. Clang and GCC -+ // optimize this to a no-op on x86-64. -+ return v & (static_cast(1) << 127) -+ ? ~static_cast<__int128>(~v) -+ : static_cast<__int128>(v); -+} -+ -+} // namespace int128_internal -+ -+inline int128& int128::operator=(__int128 v) { -+ v_ = v; -+ return *this; -+} -+ -+constexpr uint64_t Int128Low64(int128 v) { -+ return static_cast(v.v_ & ~uint64_t{0}); -+} -+ -+constexpr int64_t Int128High64(int128 v) { -+ // Initially cast to unsigned to prevent a right shift on a negative value. -+ return int128_internal::BitCastToSigned( -+ static_cast(static_cast(v.v_) >> 64)); -+} -+ -+constexpr int128::int128(int64_t high, uint64_t low) -+ // Initially cast to unsigned to prevent a left shift that overflows. -+ : v_(int128_internal::BitCastToSigned(static_cast(high) -+ << 64) | -+ low) {} -+ -+ -+constexpr int128::int128(int v) : v_{v} {} -+ -+constexpr int128::int128(long v) : v_{v} {} // NOLINT(runtime/int) -+ -+constexpr int128::int128(long long v) : v_{v} {} // NOLINT(runtime/int) -+ -+constexpr int128::int128(__int128 v) : v_{v} {} -+ -+constexpr int128::int128(unsigned int v) : v_{v} {} -+ -+constexpr int128::int128(unsigned long v) : v_{v} {} // NOLINT(runtime/int) -+ -+// NOLINTNEXTLINE(runtime/int) -+constexpr int128::int128(unsigned long long v) : v_{v} {} -+ -+constexpr int128::int128(unsigned __int128 v) : v_{static_cast<__int128>(v)} {} -+ -+inline int128::int128(float v) { -+ v_ = static_cast<__int128>(v); -+} -+ -+inline int128::int128(double v) { -+ v_ = static_cast<__int128>(v); -+} -+ -+inline int128::int128(long double v) { -+ v_ = static_cast<__int128>(v); -+} -+ -+constexpr int128::int128(uint128 v) : v_{static_cast<__int128>(v)} {} -+ -+constexpr int128::operator bool() const { return static_cast(v_); } -+ -+constexpr int128::operator char() const { return static_cast(v_); } -+ -+constexpr int128::operator signed char() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator unsigned char() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator char16_t() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator char32_t() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator ABSL_INTERNAL_WCHAR_T() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator short() const { // NOLINT(runtime/int) -+ return static_cast(v_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator unsigned short() const { // NOLINT(runtime/int) -+ return static_cast(v_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator int() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator unsigned int() const { -+ return static_cast(v_); -+} -+ -+constexpr int128::operator long() const { // NOLINT(runtime/int) -+ return static_cast(v_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator unsigned long() const { // NOLINT(runtime/int) -+ return static_cast(v_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator long long() const { // NOLINT(runtime/int) -+ return static_cast(v_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator unsigned long long() const { // NOLINT(runtime/int) -+ return static_cast(v_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator __int128() const { return v_; } -+ -+constexpr int128::operator unsigned __int128() const { -+ return static_cast(v_); -+} -+ -+// Clang on PowerPC sometimes produces incorrect __int128 to floating point -+// conversions. In that case, we do the conversion with a similar implementation -+// to the conversion operators in int128_no_intrinsic.inc. -+#if defined(__clang__) && !defined(__ppc64__) -+inline int128::operator float() const { return static_cast(v_); } -+ -+inline int128::operator double () const { return static_cast(v_); } -+ -+inline int128::operator long double() const { -+ return static_cast(v_); -+} -+ -+#else // Clang on PowerPC -+// Forward declaration for conversion operators to floating point types. -+int128 operator-(int128 v); -+bool operator!=(int128 lhs, int128 rhs); -+ -+inline int128::operator float() const { -+ // We must convert the absolute value and then negate as needed, because -+ // floating point types are typically sign-magnitude. Otherwise, the -+ // difference between the high and low 64 bits when interpreted as two's -+ // complement overwhelms the precision of the mantissa. -+ // -+ // Also check to make sure we don't negate Int128Min() -+ return v_ < 0 && *this != Int128Min() -+ ? -static_cast(-*this) -+ : static_cast(Int128Low64(*this)) + -+ std::ldexp(static_cast(Int128High64(*this)), 64); -+} -+ -+inline int128::operator double() const { -+ // See comment in int128::operator float() above. -+ return v_ < 0 && *this != Int128Min() -+ ? -static_cast(-*this) -+ : static_cast(Int128Low64(*this)) + -+ std::ldexp(static_cast(Int128High64(*this)), 64); -+} -+ -+inline int128::operator long double() const { -+ // See comment in int128::operator float() above. -+ return v_ < 0 && *this != Int128Min() -+ ? -static_cast(-*this) -+ : static_cast(Int128Low64(*this)) + -+ std::ldexp(static_cast(Int128High64(*this)), -+ 64); -+} -+#endif // Clang on PowerPC -+ -+// Comparison operators. -+ -+inline bool operator==(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) == static_cast<__int128>(rhs); -+} -+ -+inline bool operator!=(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) != static_cast<__int128>(rhs); -+} -+ -+inline bool operator<(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) < static_cast<__int128>(rhs); -+} -+ -+inline bool operator>(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) > static_cast<__int128>(rhs); -+} -+ -+inline bool operator<=(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) <= static_cast<__int128>(rhs); -+} -+ -+inline bool operator>=(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) >= static_cast<__int128>(rhs); -+} -+ -+// Unary operators. -+ -+inline int128 operator-(int128 v) { -+ return -static_cast<__int128>(v); -+} -+ -+inline bool operator!(int128 v) { -+ return !static_cast<__int128>(v); -+} -+ -+inline int128 operator~(int128 val) { -+ return ~static_cast<__int128>(val); -+} -+ -+// Arithmetic operators. -+ -+inline int128 operator+(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) + static_cast<__int128>(rhs); -+} -+ -+inline int128 operator-(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) - static_cast<__int128>(rhs); -+} -+ -+inline int128 operator*(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) * static_cast<__int128>(rhs); -+} -+ -+inline int128 operator/(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) / static_cast<__int128>(rhs); -+} -+ -+inline int128 operator%(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) % static_cast<__int128>(rhs); -+} -+ -+inline int128 int128::operator++(int) { -+ int128 tmp(*this); -+ ++v_; -+ return tmp; -+} -+ -+inline int128 int128::operator--(int) { -+ int128 tmp(*this); -+ --v_; -+ return tmp; -+} -+ -+inline int128& int128::operator++() { -+ ++v_; -+ return *this; -+} -+ -+inline int128& int128::operator--() { -+ --v_; -+ return *this; -+} -+ -+inline int128 operator|(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) | static_cast<__int128>(rhs); -+} -+ -+inline int128 operator&(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) & static_cast<__int128>(rhs); -+} -+ -+inline int128 operator^(int128 lhs, int128 rhs) { -+ return static_cast<__int128>(lhs) ^ static_cast<__int128>(rhs); -+} -+ -+inline int128 operator<<(int128 lhs, int amount) { -+ return static_cast<__int128>(lhs) << amount; -+} -+ -+inline int128 operator>>(int128 lhs, int amount) { -+ return static_cast<__int128>(lhs) >> amount; -+} -diff --git a/extern/int128/absl/numeric/int128_no_intrinsic.inc b/extern/int128/absl/numeric/int128_no_intrinsic.inc -new file mode 100644 -index 0000000000..c753771ae7 ---- /dev/null -+++ b/extern/int128/absl/numeric/int128_no_intrinsic.inc -@@ -0,0 +1,308 @@ -+// -+// Copyright 2017 The Abseil Authors. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+// This file contains :int128 implementation details that depend on internal -+// representation when ABSL_HAVE_INTRINSIC_INT128 is *not* defined. This file -+// is included by int128.h and relies on ABSL_INTERNAL_WCHAR_T being defined. -+ -+constexpr uint64_t Int128Low64(int128 v) { return v.lo_; } -+ -+constexpr int64_t Int128High64(int128 v) { return v.hi_; } -+ -+#if defined(ABSL_IS_LITTLE_ENDIAN) -+ -+constexpr int128::int128(int64_t high, uint64_t low) : -+ lo_(low), hi_(high) {} -+ -+constexpr int128::int128(int v) -+ : lo_{static_cast(v)}, hi_{v < 0 ? ~int64_t{0} : 0} {} -+constexpr int128::int128(long v) // NOLINT(runtime/int) -+ : lo_{static_cast(v)}, hi_{v < 0 ? ~int64_t{0} : 0} {} -+constexpr int128::int128(long long v) // NOLINT(runtime/int) -+ : lo_{static_cast(v)}, hi_{v < 0 ? ~int64_t{0} : 0} {} -+ -+constexpr int128::int128(unsigned int v) : lo_{v}, hi_{0} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr int128::int128(unsigned long v) : lo_{v}, hi_{0} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr int128::int128(unsigned long long v) : lo_{v}, hi_{0} {} -+ -+constexpr int128::int128(uint128 v) -+ : lo_{Uint128Low64(v)}, hi_{static_cast(Uint128High64(v))} {} -+ -+#elif defined(ABSL_IS_BIG_ENDIAN) -+ -+constexpr int128::int128(int64_t high, uint64_t low) : -+ hi_{high}, lo_{low} {} -+ -+constexpr int128::int128(int v) -+ : hi_{v < 0 ? ~int64_t{0} : 0}, lo_{static_cast(v)} {} -+constexpr int128::int128(long v) // NOLINT(runtime/int) -+ : hi_{v < 0 ? ~int64_t{0} : 0}, lo_{static_cast(v)} {} -+constexpr int128::int128(long long v) // NOLINT(runtime/int) -+ : hi_{v < 0 ? ~int64_t{0} : 0}, lo_{static_cast(v)} {} -+ -+constexpr int128::int128(unsigned int v) : hi_{0}, lo_{v} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr int128::int128(unsigned long v) : hi_{0}, lo_{v} {} -+// NOLINTNEXTLINE(runtime/int) -+constexpr int128::int128(unsigned long long v) : hi_{0}, lo_{v} {} -+ -+constexpr int128::int128(uint128 v) -+ : hi_{static_cast(Uint128High64(v))}, lo_{Uint128Low64(v)} {} -+ -+#else // byte order -+#error "Unsupported byte order: must be little-endian or big-endian." -+#endif // byte order -+ -+constexpr int128::operator bool() const { return lo_ || hi_; } -+ -+constexpr int128::operator char() const { -+ // NOLINTNEXTLINE(runtime/int) -+ return static_cast(static_cast(*this)); -+} -+ -+constexpr int128::operator signed char() const { -+ // NOLINTNEXTLINE(runtime/int) -+ return static_cast(static_cast(*this)); -+} -+ -+constexpr int128::operator unsigned char() const { -+ return static_cast(lo_); -+} -+ -+constexpr int128::operator char16_t() const { -+ return static_cast(lo_); -+} -+ -+constexpr int128::operator char32_t() const { -+ return static_cast(lo_); -+} -+ -+constexpr int128::operator ABSL_INTERNAL_WCHAR_T() const { -+ // NOLINTNEXTLINE(runtime/int) -+ return static_cast(static_cast(*this)); -+} -+ -+constexpr int128::operator short() const { // NOLINT(runtime/int) -+ // NOLINTNEXTLINE(runtime/int) -+ return static_cast(static_cast(*this)); -+} -+ -+constexpr int128::operator unsigned short() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator int() const { -+ // NOLINTNEXTLINE(runtime/int) -+ return static_cast(static_cast(*this)); -+} -+ -+constexpr int128::operator unsigned int() const { -+ return static_cast(lo_); -+} -+ -+constexpr int128::operator long() const { // NOLINT(runtime/int) -+ // NOLINTNEXTLINE(runtime/int) -+ return static_cast(static_cast(*this)); -+} -+ -+constexpr int128::operator unsigned long() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+constexpr int128::operator long long() const { // NOLINT(runtime/int) -+ // We don't bother checking the value of hi_. If *this < 0, lo_'s high bit -+ // must be set in order for the value to fit into a long long. Conversely, if -+ // lo_'s high bit is set, *this must be < 0 for the value to fit. -+ return int128_internal::BitCastToSigned(lo_); -+} -+ -+constexpr int128::operator unsigned long long() const { // NOLINT(runtime/int) -+ return static_cast(lo_); // NOLINT(runtime/int) -+} -+ -+// Forward declaration for conversion operators to floating point types. -+int128 operator-(int128 v); -+bool operator!=(int128 lhs, int128 rhs); -+ -+inline int128::operator float() const { -+ // We must convert the absolute value and then negate as needed, because -+ // floating point types are typically sign-magnitude. Otherwise, the -+ // difference between the high and low 64 bits when interpreted as two's -+ // complement overwhelms the precision of the mantissa. -+ // -+ // Also check to make sure we don't negate Int128Min() -+ return hi_ < 0 && *this != Int128Min() -+ ? -static_cast(-*this) -+ : static_cast(lo_) + -+ std::ldexp(static_cast(hi_), 64); -+} -+ -+inline int128::operator double() const { -+ // See comment in int128::operator float() above. -+ return hi_ < 0 && *this != Int128Min() -+ ? -static_cast(-*this) -+ : static_cast(lo_) + -+ std::ldexp(static_cast(hi_), 64); -+} -+ -+inline int128::operator long double() const { -+ // See comment in int128::operator float() above. -+ return hi_ < 0 && *this != Int128Min() -+ ? -static_cast(-*this) -+ : static_cast(lo_) + -+ std::ldexp(static_cast(hi_), 64); -+} -+ -+// Comparison operators. -+ -+inline bool operator==(int128 lhs, int128 rhs) { -+ return (Int128Low64(lhs) == Int128Low64(rhs) && -+ Int128High64(lhs) == Int128High64(rhs)); -+} -+ -+inline bool operator!=(int128 lhs, int128 rhs) { -+ return !(lhs == rhs); -+} -+ -+inline bool operator<(int128 lhs, int128 rhs) { -+ return (Int128High64(lhs) == Int128High64(rhs)) -+ ? (Int128Low64(lhs) < Int128Low64(rhs)) -+ : (Int128High64(lhs) < Int128High64(rhs)); -+} -+ -+inline bool operator>(int128 lhs, int128 rhs) { -+ return (Int128High64(lhs) == Int128High64(rhs)) -+ ? (Int128Low64(lhs) > Int128Low64(rhs)) -+ : (Int128High64(lhs) > Int128High64(rhs)); -+} -+ -+inline bool operator<=(int128 lhs, int128 rhs) { -+ return !(lhs > rhs); -+} -+ -+inline bool operator>=(int128 lhs, int128 rhs) { -+ return !(lhs < rhs); -+} -+ -+// Unary operators. -+ -+inline int128 operator-(int128 v) { -+ int64_t hi = ~Int128High64(v); -+ uint64_t lo = ~Int128Low64(v) + 1; -+ if (lo == 0) ++hi; // carry -+ return MakeInt128(hi, lo); -+} -+ -+inline bool operator!(int128 v) { -+ return !Int128Low64(v) && !Int128High64(v); -+} -+ -+inline int128 operator~(int128 val) { -+ return MakeInt128(~Int128High64(val), ~Int128Low64(val)); -+} -+ -+// Arithmetic operators. -+ -+inline int128 operator+(int128 lhs, int128 rhs) { -+ int128 result = MakeInt128(Int128High64(lhs) + Int128High64(rhs), -+ Int128Low64(lhs) + Int128Low64(rhs)); -+ if (Int128Low64(result) < Int128Low64(lhs)) { // check for carry -+ return MakeInt128(Int128High64(result) + 1, Int128Low64(result)); -+ } -+ return result; -+} -+ -+inline int128 operator-(int128 lhs, int128 rhs) { -+ int128 result = MakeInt128(Int128High64(lhs) - Int128High64(rhs), -+ Int128Low64(lhs) - Int128Low64(rhs)); -+ if (Int128Low64(lhs) < Int128Low64(rhs)) { // check for carry -+ return MakeInt128(Int128High64(result) - 1, Int128Low64(result)); -+ } -+ return result; -+} -+ -+inline int128 operator*(int128 lhs, int128 rhs) { -+ uint128 result = uint128(lhs) * rhs; -+ return MakeInt128(int128_internal::BitCastToSigned(Uint128High64(result)), -+ Uint128Low64(result)); -+} -+ -+inline int128 int128::operator++(int) { -+ int128 tmp(*this); -+ *this += 1; -+ return tmp; -+} -+ -+inline int128 int128::operator--(int) { -+ int128 tmp(*this); -+ *this -= 1; -+ return tmp; -+} -+ -+inline int128& int128::operator++() { -+ *this += 1; -+ return *this; -+} -+ -+inline int128& int128::operator--() { -+ *this -= 1; -+ return *this; -+} -+ -+inline int128 operator|(int128 lhs, int128 rhs) { -+ return MakeInt128(Int128High64(lhs) | Int128High64(rhs), -+ Int128Low64(lhs) | Int128Low64(rhs)); -+} -+ -+inline int128 operator&(int128 lhs, int128 rhs) { -+ return MakeInt128(Int128High64(lhs) & Int128High64(rhs), -+ Int128Low64(lhs) & Int128Low64(rhs)); -+} -+ -+inline int128 operator^(int128 lhs, int128 rhs) { -+ return MakeInt128(Int128High64(lhs) ^ Int128High64(rhs), -+ Int128Low64(lhs) ^ Int128Low64(rhs)); -+} -+ -+inline int128 operator<<(int128 lhs, int amount) { -+ // uint64_t shifts of >= 64 are undefined, so we need some special-casing. -+ if (amount < 64) { -+ if (amount != 0) { -+ return MakeInt128( -+ (Int128High64(lhs) << amount) | -+ static_cast(Int128Low64(lhs) >> (64 - amount)), -+ Int128Low64(lhs) << amount); -+ } -+ return lhs; -+ } -+ return MakeInt128(static_cast(Int128Low64(lhs) << (amount - 64)), 0); -+} -+ -+inline int128 operator>>(int128 lhs, int amount) { -+ // uint64_t shifts of >= 64 are undefined, so we need some special-casing. -+ if (amount < 64) { -+ if (amount != 0) { -+ return MakeInt128( -+ Int128High64(lhs) >> amount, -+ (Int128Low64(lhs) >> amount) | -+ (static_cast(Int128High64(lhs)) << (64 - amount))); -+ } -+ return lhs; -+ } -+ return MakeInt128(0, -+ static_cast(Int128High64(lhs) >> (amount - 64))); -+} -diff --git a/extern/int128/absl/numeric/internal/bits.h b/extern/int128/absl/numeric/internal/bits.h -new file mode 100644 -index 0000000000..bfef06bce1 ---- /dev/null -+++ b/extern/int128/absl/numeric/internal/bits.h -@@ -0,0 +1,358 @@ -+// Copyright 2020 The Abseil Authors -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+#ifndef ABSL_NUMERIC_INTERNAL_BITS_H_ -+#define ABSL_NUMERIC_INTERNAL_BITS_H_ -+ -+#include -+#include -+#include -+ -+// Clang on Windows has __builtin_clzll; otherwise we need to use the -+// windows intrinsic functions. -+#if defined(_MSC_VER) && !defined(__clang__) -+#include -+#endif -+ -+#include "absl/base/attributes.h" -+#include "absl/base/config.h" -+ -+#if defined(__GNUC__) && !defined(__clang__) -+// GCC -+#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) 1 -+#else -+#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) ABSL_HAVE_BUILTIN(x) -+#endif -+ -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountl) && \ -+ ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll) -+#define ABSL_INTERNAL_CONSTEXPR_POPCOUNT constexpr -+#define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 1 -+#else -+#define ABSL_INTERNAL_CONSTEXPR_POPCOUNT -+#define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 0 -+#endif -+ -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) && \ -+ ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll) -+#define ABSL_INTERNAL_CONSTEXPR_CLZ constexpr -+#define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 1 -+#else -+#define ABSL_INTERNAL_CONSTEXPR_CLZ -+#define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 0 -+#endif -+ -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) && \ -+ ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll) -+#define ABSL_INTERNAL_CONSTEXPR_CTZ constexpr -+#define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 1 -+#else -+#define ABSL_INTERNAL_CONSTEXPR_CTZ -+#define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 0 -+#endif -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+namespace numeric_internal { -+ -+constexpr bool IsPowerOf2(unsigned int x) noexcept { -+ return x != 0 && (x & (x - 1)) == 0; -+} -+ -+template -+ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateRight( -+ T x, int s) noexcept { -+ static_assert(std::is_unsigned::value, "T must be unsigned"); -+ static_assert(IsPowerOf2(std::numeric_limits::digits), -+ "T must have a power-of-2 size"); -+ -+ return static_cast(x >> (s & (std::numeric_limits::digits - 1))) | -+ static_cast(x << ((-s) & (std::numeric_limits::digits - 1))); -+} -+ -+template -+ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft( -+ T x, int s) noexcept { -+ static_assert(std::is_unsigned::value, "T must be unsigned"); -+ static_assert(IsPowerOf2(std::numeric_limits::digits), -+ "T must have a power-of-2 size"); -+ -+ return static_cast(x << (s & (std::numeric_limits::digits - 1))) | -+ static_cast(x >> ((-s) & (std::numeric_limits::digits - 1))); -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int -+Popcount32(uint32_t x) noexcept { -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcount) -+ static_assert(sizeof(unsigned int) == sizeof(x), -+ "__builtin_popcount does not take 32-bit arg"); -+ return __builtin_popcount(x); -+#else -+ x -= ((x >> 1) & 0x55555555); -+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333); -+ return static_cast((((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24); -+#endif -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int -+Popcount64(uint64_t x) noexcept { -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll) -+ static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) -+ "__builtin_popcount does not take 64-bit arg"); -+ return __builtin_popcountll(x); -+#else -+ x -= (x >> 1) & 0x5555555555555555ULL; -+ x = ((x >> 2) & 0x3333333333333333ULL) + (x & 0x3333333333333333ULL); -+ return static_cast( -+ (((x + (x >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56); -+#endif -+} -+ -+template -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int -+Popcount(T x) noexcept { -+ static_assert(std::is_unsigned::value, "T must be unsigned"); -+ static_assert(IsPowerOf2(std::numeric_limits::digits), -+ "T must have a power-of-2 size"); -+ static_assert(sizeof(x) <= sizeof(uint64_t), "T is too large"); -+ return sizeof(x) <= sizeof(uint32_t) ? Popcount32(x) : Popcount64(x); -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int -+CountLeadingZeroes32(uint32_t x) { -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) -+ // Use __builtin_clz, which uses the following instructions: -+ // x86: bsr, lzcnt -+ // ARM64: clz -+ // PPC: cntlzd -+ -+ static_assert(sizeof(unsigned int) == sizeof(x), -+ "__builtin_clz does not take 32-bit arg"); -+ // Handle 0 as a special case because __builtin_clz(0) is undefined. -+ return x == 0 ? 32 : __builtin_clz(x); -+#elif defined(_MSC_VER) && !defined(__clang__) -+ unsigned long result = 0; // NOLINT(runtime/int) -+ if (_BitScanReverse(&result, x)) { -+ return 31 - result; -+ } -+ return 32; -+#else -+ int zeroes = 28; -+ if (x >> 16) { -+ zeroes -= 16; -+ x >>= 16; -+ } -+ if (x >> 8) { -+ zeroes -= 8; -+ x >>= 8; -+ } -+ if (x >> 4) { -+ zeroes -= 4; -+ x >>= 4; -+ } -+ return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes; -+#endif -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int -+CountLeadingZeroes16(uint16_t x) { -+#if ABSL_HAVE_BUILTIN(__builtin_clzs) -+ static_assert(sizeof(unsigned short) == sizeof(x), // NOLINT(runtime/int) -+ "__builtin_clzs does not take 16-bit arg"); -+ return x == 0 ? 16 : __builtin_clzs(x); -+#else -+ return CountLeadingZeroes32(x) - 16; -+#endif -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int -+CountLeadingZeroes64(uint64_t x) { -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll) -+ // Use __builtin_clzll, which uses the following instructions: -+ // x86: bsr, lzcnt -+ // ARM64: clz -+ // PPC: cntlzd -+ static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) -+ "__builtin_clzll does not take 64-bit arg"); -+ -+ // Handle 0 as a special case because __builtin_clzll(0) is undefined. -+ return x == 0 ? 64 : __builtin_clzll(x); -+#elif defined(_MSC_VER) && !defined(__clang__) && \ -+ (defined(_M_X64) || defined(_M_ARM64)) -+ // MSVC does not have __buitin_clzll. Use _BitScanReverse64. -+ unsigned long result = 0; // NOLINT(runtime/int) -+ if (_BitScanReverse64(&result, x)) { -+ return 63 - result; -+ } -+ return 64; -+#elif defined(_MSC_VER) && !defined(__clang__) -+ // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse -+ unsigned long result = 0; // NOLINT(runtime/int) -+ if ((x >> 32) && -+ _BitScanReverse(&result, static_cast(x >> 32))) { -+ return 31 - result; -+ } -+ if (_BitScanReverse(&result, static_cast(x))) { -+ return 63 - result; -+ } -+ return 64; -+#else -+ int zeroes = 60; -+ if (x >> 32) { -+ zeroes -= 32; -+ x >>= 32; -+ } -+ if (x >> 16) { -+ zeroes -= 16; -+ x >>= 16; -+ } -+ if (x >> 8) { -+ zeroes -= 8; -+ x >>= 8; -+ } -+ if (x >> 4) { -+ zeroes -= 4; -+ x >>= 4; -+ } -+ return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes; -+#endif -+} -+ -+template -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int -+CountLeadingZeroes(T x) { -+ static_assert(std::is_unsigned::value, "T must be unsigned"); -+ static_assert(IsPowerOf2(std::numeric_limits::digits), -+ "T must have a power-of-2 size"); -+ static_assert(sizeof(T) <= sizeof(uint64_t), "T too large"); -+ return sizeof(T) <= sizeof(uint16_t) -+ ? CountLeadingZeroes16(static_cast(x)) - -+ (std::numeric_limits::digits - -+ std::numeric_limits::digits) -+ : (sizeof(T) <= sizeof(uint32_t) -+ ? CountLeadingZeroes32(static_cast(x)) - -+ (std::numeric_limits::digits - -+ std::numeric_limits::digits) -+ : CountLeadingZeroes64(x)); -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int -+CountTrailingZeroesNonzero32(uint32_t x) { -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) -+ static_assert(sizeof(unsigned int) == sizeof(x), -+ "__builtin_ctz does not take 32-bit arg"); -+ return __builtin_ctz(x); -+#elif defined(_MSC_VER) && !defined(__clang__) -+ unsigned long result = 0; // NOLINT(runtime/int) -+ _BitScanForward(&result, x); -+ return result; -+#else -+ int c = 31; -+ x &= ~x + 1; -+ if (x & 0x0000FFFF) c -= 16; -+ if (x & 0x00FF00FF) c -= 8; -+ if (x & 0x0F0F0F0F) c -= 4; -+ if (x & 0x33333333) c -= 2; -+ if (x & 0x55555555) c -= 1; -+ return c; -+#endif -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int -+CountTrailingZeroesNonzero64(uint64_t x) { -+#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll) -+ static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) -+ "__builtin_ctzll does not take 64-bit arg"); -+ return __builtin_ctzll(x); -+#elif defined(_MSC_VER) && !defined(__clang__) && \ -+ (defined(_M_X64) || defined(_M_ARM64)) -+ unsigned long result = 0; // NOLINT(runtime/int) -+ _BitScanForward64(&result, x); -+ return result; -+#elif defined(_MSC_VER) && !defined(__clang__) -+ unsigned long result = 0; // NOLINT(runtime/int) -+ if (static_cast(x) == 0) { -+ _BitScanForward(&result, static_cast(x >> 32)); -+ return result + 32; -+ } -+ _BitScanForward(&result, static_cast(x)); -+ return result; -+#else -+ int c = 63; -+ x &= ~x + 1; -+ if (x & 0x00000000FFFFFFFF) c -= 32; -+ if (x & 0x0000FFFF0000FFFF) c -= 16; -+ if (x & 0x00FF00FF00FF00FF) c -= 8; -+ if (x & 0x0F0F0F0F0F0F0F0F) c -= 4; -+ if (x & 0x3333333333333333) c -= 2; -+ if (x & 0x5555555555555555) c -= 1; -+ return c; -+#endif -+} -+ -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int -+CountTrailingZeroesNonzero16(uint16_t x) { -+#if ABSL_HAVE_BUILTIN(__builtin_ctzs) -+ static_assert(sizeof(unsigned short) == sizeof(x), // NOLINT(runtime/int) -+ "__builtin_ctzs does not take 16-bit arg"); -+ return __builtin_ctzs(x); -+#else -+ return CountTrailingZeroesNonzero32(x); -+#endif -+} -+ -+template -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int -+CountTrailingZeroes(T x) noexcept { -+ static_assert(std::is_unsigned::value, "T must be unsigned"); -+ static_assert(IsPowerOf2(std::numeric_limits::digits), -+ "T must have a power-of-2 size"); -+ static_assert(sizeof(T) <= sizeof(uint64_t), "T too large"); -+ return x == 0 ? std::numeric_limits::digits -+ : (sizeof(T) <= sizeof(uint16_t) -+ ? CountTrailingZeroesNonzero16(static_cast(x)) -+ : (sizeof(T) <= sizeof(uint32_t) -+ ? CountTrailingZeroesNonzero32( -+ static_cast(x)) -+ : CountTrailingZeroesNonzero64(x))); -+} -+ -+// If T is narrower than unsigned, T{1} << bit_width will be promoted. We -+// want to force it to wraparound so that bit_ceil of an invalid value are not -+// core constant expressions. -+template -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, T>::type -+ BitCeilPromotionHelper(T x, T promotion) { -+ return (T{1} << (x + promotion)) >> promotion; -+} -+ -+template -+ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline -+ typename std::enable_if::value, T>::type -+ BitCeilNonPowerOf2(T x) { -+ // If T is narrower than unsigned, it undergoes promotion to unsigned when we -+ // shift. We calculate the number of bits added by the wider type. -+ return BitCeilPromotionHelper( -+ static_cast(std::numeric_limits::digits - CountLeadingZeroes(x)), -+ T{sizeof(T) >= sizeof(unsigned) ? 0 -+ : std::numeric_limits::digits - -+ std::numeric_limits::digits}); -+} -+ -+} // namespace numeric_internal -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+#endif // ABSL_NUMERIC_INTERNAL_BITS_H_ -diff --git a/extern/int128/absl/numeric/internal/representation.h b/extern/int128/absl/numeric/internal/representation.h -new file mode 100644 -index 0000000000..82d332fdde ---- /dev/null -+++ b/extern/int128/absl/numeric/internal/representation.h -@@ -0,0 +1,55 @@ -+// Copyright 2021 The Abseil Authors -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// https://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+#ifndef ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_ -+#define ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_ -+ -+#include -+ -+#include "absl/base/config.h" -+ -+namespace absl { -+ABSL_NAMESPACE_BEGIN -+namespace numeric_internal { -+ -+// Returns true iff long double is represented as a pair of doubles added -+// together. -+inline constexpr bool IsDoubleDouble() { -+ // A double-double value always has exactly twice the precision of a double -+ // value--one double carries the high digits and one double carries the low -+ // digits. This property is not shared with any other common floating-point -+ // representation, so this test won't trigger false positives. For reference, -+ // this table gives the number of bits of precision of each common -+ // floating-point representation: -+ // -+ // type precision -+ // IEEE single 24 b -+ // IEEE double 53 -+ // x86 long double 64 -+ // double-double 106 -+ // IEEE quadruple 113 -+ // -+ // Note in particular that a quadruple-precision float has greater precision -+ // than a double-double float despite taking up the same amount of memory; the -+ // quad has more of its bits allocated to the mantissa than the double-double -+ // has. -+ return std::numeric_limits::digits == -+ 2 * std::numeric_limits::digits; -+} -+ -+} // namespace numeric_internal -+ABSL_NAMESPACE_END -+} // namespace absl -+ -+#endif // ABSL_NUMERIC_INTERNAL_REPRESENTATION_H_ -diff --git a/extern/ttmath/ttmath.h b/extern/ttmath/ttmath.h -deleted file mode 100644 -index 9b9e8ee6e5..0000000000 ---- a/extern/ttmath/ttmath.h -+++ /dev/null -@@ -1,2843 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2012, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- -- --#ifndef headerfilettmathmathtt --#define headerfilettmathmathtt -- --/*! -- \file ttmath.h -- \brief Mathematics functions. --*/ -- --#ifdef _MSC_VER --//warning C4127: conditional expression is constant --#pragma warning( disable: 4127 ) --//warning C4702: unreachable code --#pragma warning( disable: 4702 ) --//warning C4800: forcing value to bool 'true' or 'false' (performance warning) --#pragma warning( disable: 4800 ) --#endif -- --#define TTMATH_DONT_USE_WCHAR -- --#include "ttmathint.h" --#include "ttmathobjects.h" -- -- --namespace ttmath --{ -- /* -- * -- * functions defined here are used only with Big<> types -- * -- * -- */ -- -- -- /* -- * -- * functions for rounding -- * -- * -- */ -- -- -- /*! -- this function skips the fraction from x -- e.g 2.2 = 2 -- 2.7 = 2 -- -2.2 = 2 -- -2.7 = 2 -- */ -- template -- ValueType SkipFraction(const ValueType & x) -- { -- ValueType result( x ); -- result.SkipFraction(); -- -- return result; -- } -- -- -- /*! -- this function rounds to the nearest integer value -- e.g 2.2 = 2 -- 2.7 = 3 -- -2.2 = -2 -- -2.7 = -3 -- */ -- template -- ValueType Round(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType result( x ); -- uint c = result.Round(); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- -- /*! -- this function returns a value representing the smallest integer -- that is greater than or equal to x -- -- Ceil(-3.7) = -3 -- Ceil(-3.1) = -3 -- Ceil(-3.0) = -3 -- Ceil(4.0) = 4 -- Ceil(4.2) = 5 -- Ceil(4.8) = 5 -- */ -- template -- ValueType Ceil(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType result(x); -- uint c = 0; -- -- result.SkipFraction(); -- -- if( result != x ) -- { -- // x is with fraction -- // if x is negative we don't have to do anything -- if( !x.IsSign() ) -- { -- ValueType one; -- one.SetOne(); -- -- c += result.Add(one); -- } -- } -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- this function returns a value representing the largest integer -- that is less than or equal to x -- -- Floor(-3.6) = -4 -- Floor(-3.1) = -4 -- Floor(-3) = -3 -- Floor(2) = 2 -- Floor(2.3) = 2 -- Floor(2.8) = 2 -- */ -- template -- ValueType Floor(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType result(x); -- uint c = 0; -- -- result.SkipFraction(); -- -- if( result != x ) -- { -- // x is with fraction -- // if x is positive we don't have to do anything -- if( x.IsSign() ) -- { -- ValueType one; -- one.SetOne(); -- -- c += result.Sub(one); -- } -- } -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- -- /* -- * -- * logarithms and the exponent -- * -- * -- */ -- -- -- /*! -- this function calculates the natural logarithm (logarithm with the base 'e') -- */ -- template -- ValueType Ln(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType result; -- uint state = result.Ln(x); -- -- if( err ) -- { -- switch( state ) -- { -- case 0: -- *err = err_ok; -- break; -- case 1: -- *err = err_overflow; -- break; -- case 2: -- *err = err_improper_argument; -- break; -- default: -- *err = err_internal_error; -- break; -- } -- } -- -- -- return result; -- } -- -- -- /*! -- this function calculates the logarithm -- */ -- template -- ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) *err = err_improper_argument; -- return x; -- } -- -- if( base.IsNan() ) -- { -- if( err ) *err = err_improper_argument; -- return base; -- } -- -- ValueType result; -- uint state = result.Log(x, base); -- -- if( err ) -- { -- switch( state ) -- { -- case 0: -- *err = err_ok; -- break; -- case 1: -- *err = err_overflow; -- break; -- case 2: -- case 3: -- *err = err_improper_argument; -- break; -- default: -- *err = err_internal_error; -- break; -- } -- } -- -- return result; -- } -- -- -- /*! -- this function calculates the expression e^x -- */ -- template -- ValueType Exp(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType result; -- uint c = result.Exp(x); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- * -- * trigonometric functions -- * -- */ -- -- -- /* -- this namespace consists of auxiliary functions -- (something like 'private' in a class) -- */ -- namespace auxiliaryfunctions -- { -- -- /*! -- an auxiliary function for calculating the Sine -- (you don't have to call this function) -- */ -- template -- uint PrepareSin(ValueType & x, bool & change_sign) -- { -- ValueType temp; -- -- change_sign = false; -- -- if( x.IsSign() ) -- { -- // we're using the formula 'sin(-x) = -sin(x)' -- change_sign = !change_sign; -- x.ChangeSign(); -- } -- -- // we're reducing the period 2*PI -- // (for big values there'll always be zero) -- temp.Set2Pi(); -- -- if( x.Mod(temp) ) -- return 1; -- -- -- // we're setting 'x' as being in the range of <0, 0.5PI> -- -- temp.SetPi(); -- -- if( x > temp ) -- { -- // x is in (pi, 2*pi> -- x.Sub( temp ); -- change_sign = !change_sign; -- } -- -- temp.Set05Pi(); -- -- if( x > temp ) -- { -- // x is in (0.5pi, pi> -- x.Sub( temp ); -- x = temp - x; -- } -- -- return 0; -- } -- -- -- /*! -- an auxiliary function for calculating the Sine -- (you don't have to call this function) -- -- it returns Sin(x) where 'x' is from <0, PI/2> -- we're calculating the Sin with using Taylor series in zero or PI/2 -- (depending on which point of these two points is nearer to the 'x') -- -- Taylor series: -- sin(x) = sin(a) + cos(a)*(x-a)/(1!) -- - sin(a)*((x-a)^2)/(2!) - cos(a)*((x-a)^3)/(3!) -- + sin(a)*((x-a)^4)/(4!) + ... -- -- when a=0 it'll be: -- sin(x) = (x)/(1!) - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) + (x^9)/(9!) ... -- -- and when a=PI/2: -- sin(x) = 1 - ((x-PI/2)^2)/(2!) + ((x-PI/2)^4)/(4!) - ((x-PI/2)^6)/(6!) ... -- */ -- template -- ValueType Sin0pi05(const ValueType & x) -- { -- ValueType result; -- ValueType numerator, denominator; -- ValueType d_numerator, d_denominator; -- ValueType one, temp, old_result; -- -- // temp = pi/4 -- temp.Set05Pi(); -- temp.exponent.SubOne(); -- -- one.SetOne(); -- -- if( x < temp ) -- { -- // we're using the Taylor series with a=0 -- result = x; -- numerator = x; -- denominator = one; -- -- // d_numerator = x^2 -- d_numerator = x; -- d_numerator.Mul(x); -- -- d_denominator = 2; -- } -- else -- { -- // we're using the Taylor series with a=PI/2 -- result = one; -- numerator = one; -- denominator = one; -- -- // d_numerator = (x-pi/2)^2 -- ValueType pi05; -- pi05.Set05Pi(); -- -- temp = x; -- temp.Sub( pi05 ); -- d_numerator = temp; -- d_numerator.Mul( temp ); -- -- d_denominator = one; -- } -- -- uint c = 0; -- bool addition = false; -- -- old_result = result; -- for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i) -- { -- // we're starting from a second part of the formula -- c += numerator. Mul( d_numerator ); -- c += denominator. Mul( d_denominator ); -- c += d_denominator.Add( one ); -- c += denominator. Mul( d_denominator ); -- c += d_denominator.Add( one ); -- temp = numerator; -- c += temp.Div(denominator); -- -- if( c ) -- // Sin is from <-1,1> and cannot make an overflow -- // but the carry can be from the Taylor series -- // (then we only break our calculations) -- break; -- -- if( addition ) -- result.Add( temp ); -- else -- result.Sub( temp ); -- -- -- addition = !addition; -- -- // we're testing whether the result has changed after adding -- // the next part of the Taylor formula, if not we end the loop -- // (it means 'x' is zero or 'x' is PI/2 or this part of the formula -- // is too small) -- if( result == old_result ) -- break; -- -- old_result = result; -- } -- -- return result; -- } -- -- } // namespace auxiliaryfunctions -- -- -- -- /*! -- this function calculates the Sine -- */ -- template -- ValueType Sin(ValueType x, ErrorCode * err = 0) -- { -- using namespace auxiliaryfunctions; -- -- ValueType one, result; -- bool change_sign; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- if( err ) -- *err = err_ok; -- -- if( PrepareSin( x, change_sign ) ) -- { -- // x is too big, we cannnot reduce the 2*PI period -- // prior to version 0.8.5 the result was zero -- -- // result has NaN flag set by default -- -- if( err ) -- *err = err_overflow; // maybe another error code? err_improper_argument? -- -- return result; // NaN is set by default -- } -- -- result = Sin0pi05( x ); -- -- one.SetOne(); -- -- // after calculations there can be small distortions in the result -- if( result > one ) -- result = one; -- else -- if( result.IsSign() ) -- // we've calculated the sin from <0, pi/2> and the result -- // should be positive -- result.SetZero(); -- -- if( change_sign ) -- result.ChangeSign(); -- -- return result; -- } -- -- -- /*! -- this function calulates the Cosine -- we're using the formula cos(x) = sin(x + PI/2) -- */ -- template -- ValueType Cos(ValueType x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType pi05; -- pi05.Set05Pi(); -- -- uint c = x.Add( pi05 ); -- -- if( c ) -- { -- if( err ) -- *err = err_overflow; -- -- return ValueType(); // result is undefined (NaN is set by default) -- } -- -- return Sin(x, err); -- } -- -- -- /*! -- this function calulates the Tangent -- we're using the formula tan(x) = sin(x) / cos(x) -- -- it takes more time than calculating the Tan directly -- from for example Taylor series but should be a bit preciser -- because Tan receives its values from -infinity to +infinity -- and when we calculate it from any series then we can make -- a greater mistake than calculating 'sin/cos' -- */ -- template -- ValueType Tan(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result = Cos(x, err); -- -- if( err && *err != err_ok ) -- return result; -- -- if( result.IsZero() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- result.SetNan(); -- -- return result; -- } -- -- return Sin(x, err) / result; -- } -- -- -- /*! -- this function calulates the Tangent -- look at the description of Tan(...) -- -- (the abbreviation of Tangent can be 'tg' as well) -- */ -- template -- ValueType Tg(const ValueType & x, ErrorCode * err = 0) -- { -- return Tan(x, err); -- } -- -- -- /*! -- this function calulates the Cotangent -- we're using the formula tan(x) = cos(x) / sin(x) -- -- (why do we make it in this way? -- look at information in Tan() function) -- */ -- template -- ValueType Cot(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result = Sin(x, err); -- -- if( err && *err != err_ok ) -- return result; -- -- if( result.IsZero() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- result.SetNan(); -- -- return result; -- } -- -- return Cos(x, err) / result; -- } -- -- -- /*! -- this function calulates the Cotangent -- look at the description of Cot(...) -- -- (the abbreviation of Cotangent can be 'ctg' as well) -- */ -- template -- ValueType Ctg(const ValueType & x, ErrorCode * err = 0) -- { -- return Cot(x, err); -- } -- -- -- /* -- * -- * inverse trigonometric functions -- * -- * -- */ -- -- namespace auxiliaryfunctions -- { -- -- /*! -- an auxiliary function for calculating the Arc Sine -- -- we're calculating asin from the following formula: -- asin(x) = x + (1*x^3)/(2*3) + (1*3*x^5)/(2*4*5) + (1*3*5*x^7)/(2*4*6*7) + ... -- where abs(x) <= 1 -- -- we're using this formula when x is from <0, 1/2> -- */ -- template -- ValueType ASin_0(const ValueType & x) -- { -- ValueType nominator, denominator, nominator_add, nominator_x, denominator_add, denominator_x; -- ValueType two, result(x), x2(x); -- ValueType nominator_temp, denominator_temp, old_result = result; -- uint c = 0; -- -- x2.Mul(x); -- two = 2; -- -- nominator.SetOne(); -- denominator = two; -- nominator_add = nominator; -- denominator_add = denominator; -- nominator_x = x; -- denominator_x = 3; -- -- for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i) -- { -- c += nominator_x.Mul(x2); -- nominator_temp = nominator_x; -- c += nominator_temp.Mul(nominator); -- denominator_temp = denominator; -- c += denominator_temp.Mul(denominator_x); -- c += nominator_temp.Div(denominator_temp); -- -- // if there is a carry somewhere we only break the calculating -- // the result should be ok -- it's from <-pi/2, pi/2> -- if( c ) -- break; -- -- result.Add(nominator_temp); -- -- if( result == old_result ) -- // there's no sense to calculate more -- break; -- -- old_result = result; -- -- -- c += nominator_add.Add(two); -- c += denominator_add.Add(two); -- c += nominator.Mul(nominator_add); -- c += denominator.Mul(denominator_add); -- c += denominator_x.Add(two); -- } -- -- return result; -- } -- -- -- -- /*! -- an auxiliary function for calculating the Arc Sine -- -- we're calculating asin from the following formula: -- asin(x) = pi/2 - sqrt(2)*sqrt(1-x) * asin_temp -- asin_temp = 1 + (1*(1-x))/((2*3)*(2)) + (1*3*(1-x)^2)/((2*4*5)*(4)) + (1*3*5*(1-x)^3)/((2*4*6*7)*(8)) + ... -- -- where abs(x) <= 1 -- -- we're using this formula when x is from (1/2, 1> -- */ -- template -- ValueType ASin_1(const ValueType & x) -- { -- ValueType nominator, denominator, nominator_add, nominator_x, nominator_x_add, denominator_add, denominator_x; -- ValueType denominator2; -- ValueType one, two, result; -- ValueType nominator_temp, denominator_temp, old_result; -- uint c = 0; -- -- two = 2; -- -- one.SetOne(); -- nominator = one; -- result = one; -- old_result = result; -- denominator = two; -- nominator_add = nominator; -- denominator_add = denominator; -- nominator_x = one; -- nominator_x.Sub(x); -- nominator_x_add = nominator_x; -- denominator_x = 3; -- denominator2 = two; -- -- -- for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i) -- { -- nominator_temp = nominator_x; -- c += nominator_temp.Mul(nominator); -- denominator_temp = denominator; -- c += denominator_temp.Mul(denominator_x); -- c += denominator_temp.Mul(denominator2); -- c += nominator_temp.Div(denominator_temp); -- -- // if there is a carry somewhere we only break the calculating -- // the result should be ok -- it's from <-pi/2, pi/2> -- if( c ) -- break; -- -- result.Add(nominator_temp); -- -- if( result == old_result ) -- // there's no sense to calculate more -- break; -- -- old_result = result; -- -- c += nominator_x.Mul(nominator_x_add); -- c += nominator_add.Add(two); -- c += denominator_add.Add(two); -- c += nominator.Mul(nominator_add); -- c += denominator.Mul(denominator_add); -- c += denominator_x.Add(two); -- c += denominator2.Mul(two); -- } -- -- -- nominator_x_add.exponent.AddOne(); // *2 -- one.exponent.SubOne(); // =0.5 -- nominator_x_add.Pow(one); // =sqrt(nominator_x_add) -- result.Mul(nominator_x_add); -- -- one.Set05Pi(); -- one.Sub(result); -- -- return one; -- } -- -- -- } // namespace auxiliaryfunctions -- -- -- /*! -- this function calculates the Arc Sine -- x is from <-1,1> -- */ -- template -- ValueType ASin(ValueType x, ErrorCode * err = 0) -- { -- using namespace auxiliaryfunctions; -- -- ValueType result, one; -- one.SetOne(); -- bool change_sign = false; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- if( x.GreaterWithoutSignThan(one) ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return result; // NaN is set by default -- } -- -- if( x.IsSign() ) -- { -- change_sign = true; -- x.Abs(); -- } -- -- one.exponent.SubOne(); // =0.5 -- -- // asin(-x) = -asin(x) -- if( x.GreaterWithoutSignThan(one) ) -- result = ASin_1(x); -- else -- result = ASin_0(x); -- -- if( change_sign ) -- result.ChangeSign(); -- -- if( err ) -- *err = err_ok; -- -- return result; -- } -- -- -- /*! -- this function calculates the Arc Cosine -- -- we're using the formula: -- acos(x) = pi/2 - asin(x) -- */ -- template -- ValueType ACos(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType temp; -- -- temp.Set05Pi(); -- temp.Sub(ASin(x, err)); -- -- return temp; -- } -- -- -- -- namespace auxiliaryfunctions -- { -- -- /*! -- an auxiliary function for calculating the Arc Tangent -- -- arc tan (x) where x is in <0; 0.5) -- (x can be in (-0.5 ; 0.5) too) -- -- we're using the Taylor series expanded in zero: -- atan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ... -- */ -- template -- ValueType ATan0(const ValueType & x) -- { -- ValueType nominator, denominator, nominator_add, denominator_add, temp; -- ValueType result, old_result; -- bool adding = false; -- uint c = 0; -- -- result = x; -- old_result = result; -- nominator = x; -- nominator_add = x; -- nominator_add.Mul(x); -- -- denominator.SetOne(); -- denominator_add = 2; -- -- for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i) -- { -- c += nominator.Mul(nominator_add); -- c += denominator.Add(denominator_add); -- -- temp = nominator; -- c += temp.Div(denominator); -- -- if( c ) -- // the result should be ok -- break; -- -- if( adding ) -- result.Add(temp); -- else -- result.Sub(temp); -- -- if( result == old_result ) -- // there's no sense to calculate more -- break; -- -- old_result = result; -- adding = !adding; -- } -- -- return result; -- } -- -- -- /*! -- an auxiliary function for calculating the Arc Tangent -- -- where x is in <0 ; 1> -- */ -- template -- ValueType ATan01(const ValueType & x) -- { -- ValueType half; -- half.Set05(); -- -- /* -- it would be better if we chose about sqrt(2)-1=0.41... instead of 0.5 here -- -- because as you can see below: -- when x = sqrt(2)-1 -- abs(x) = abs( (x-1)/(1+x) ) -- so when we're calculating values around x -- then they will be better converged to each other -- -- for example if we have x=0.4999 then during calculating ATan0(0.4999) -- we have to make about 141 iterations but when we have x=0.5 -- then during calculating ATan0( (x-1)/(1+x) ) we have to make -- only about 89 iterations (both for Big<3,9>) -- -- in the future this 0.5 can be changed -- */ -- if( x.SmallerWithoutSignThan(half) ) -- return ATan0(x); -- -- -- /* -- x>=0.5 and x<=1 -- (x can be even smaller than 0.5) -- -- y = atac(x) -- x = tan(y) -- -- tan(y-b) = (tan(y)-tab(b)) / (1+tan(y)*tan(b)) -- y-b = atan( (tan(y)-tab(b)) / (1+tan(y)*tan(b)) ) -- y = b + atan( (x-tab(b)) / (1+x*tan(b)) ) -- -- let b = pi/4 -- tan(b) = tan(pi/4) = 1 -- y = pi/4 + atan( (x-1)/(1+x) ) -- -- so -- atac(x) = pi/4 + atan( (x-1)/(1+x) ) -- when x->1 (x converges to 1) the (x-1)/(1+x) -> 0 -- and we can use ATan0() function here -- */ -- -- ValueType n(x),d(x),one,result; -- -- one.SetOne(); -- n.Sub(one); -- d.Add(one); -- n.Div(d); -- -- result = ATan0(n); -- -- n.Set05Pi(); -- n.exponent.SubOne(); // =pi/4 -- result.Add(n); -- -- return result; -- } -- -- -- /*! -- an auxiliary function for calculating the Arc Tangent -- where x > 1 -- -- we're using the formula: -- atan(x) = pi/2 - atan(1/x) for x>0 -- */ -- template -- ValueType ATanGreaterThanPlusOne(const ValueType & x) -- { -- ValueType temp, atan; -- -- temp.SetOne(); -- -- if( temp.Div(x) ) -- { -- // if there was a carry here that means x is very big -- // and atan(1/x) fast converged to 0 -- atan.SetZero(); -- } -- else -- atan = ATan01(temp); -- -- temp.Set05Pi(); -- temp.Sub(atan); -- -- return temp; -- } -- -- } // namespace auxiliaryfunctions -- -- -- /*! -- this function calculates the Arc Tangent -- */ -- template -- ValueType ATan(ValueType x) -- { -- using namespace auxiliaryfunctions; -- -- ValueType one, result; -- one.SetOne(); -- bool change_sign = false; -- -- if( x.IsNan() ) -- return x; -- -- // if x is negative we're using the formula: -- // atan(-x) = -atan(x) -- if( x.IsSign() ) -- { -- change_sign = true; -- x.Abs(); -- } -- -- if( x.GreaterWithoutSignThan(one) ) -- result = ATanGreaterThanPlusOne(x); -- else -- result = ATan01(x); -- -- if( change_sign ) -- result.ChangeSign(); -- -- return result; -- } -- -- -- /*! -- this function calculates the Arc Tangent -- look at the description of ATan(...) -- -- (the abbreviation of Arc Tangent can be 'atg' as well) -- */ -- template -- ValueType ATg(const ValueType & x) -- { -- return ATan(x); -- } -- -- -- /*! -- this function calculates the Arc Cotangent -- -- we're using the formula: -- actan(x) = pi/2 - atan(x) -- */ -- template -- ValueType ACot(const ValueType & x) -- { -- ValueType result; -- -- result.Set05Pi(); -- result.Sub(ATan(x)); -- -- return result; -- } -- -- -- /*! -- this function calculates the Arc Cotangent -- look at the description of ACot(...) -- -- (the abbreviation of Arc Cotangent can be 'actg' as well) -- */ -- template -- ValueType ACtg(const ValueType & x) -- { -- return ACot(x); -- } -- -- -- /* -- * -- * hyperbolic functions -- * -- * -- */ -- -- -- /*! -- this function calculates the Hyperbolic Sine -- -- we're using the formula sinh(x)= ( e^x - e^(-x) ) / 2 -- */ -- template -- ValueType Sinh(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType ex, emx; -- uint c = 0; -- -- c += ex.Exp(x); -- c += emx.Exp(-x); -- -- c += ex.Sub(emx); -- c += ex.exponent.SubOne(); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return ex; -- } -- -- -- /*! -- this function calculates the Hyperbolic Cosine -- -- we're using the formula cosh(x)= ( e^x + e^(-x) ) / 2 -- */ -- template -- ValueType Cosh(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType ex, emx; -- uint c = 0; -- -- c += ex.Exp(x); -- c += emx.Exp(-x); -- -- c += ex.Add(emx); -- c += ex.exponent.SubOne(); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return ex; -- } -- -- -- /*! -- this function calculates the Hyperbolic Tangent -- -- we're using the formula tanh(x)= ( e^x - e^(-x) ) / ( e^x + e^(-x) ) -- */ -- template -- ValueType Tanh(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType ex, emx, nominator, denominator; -- uint c = 0; -- -- c += ex.Exp(x); -- c += emx.Exp(-x); -- -- nominator = ex; -- c += nominator.Sub(emx); -- denominator = ex; -- c += denominator.Add(emx); -- -- c += nominator.Div(denominator); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return nominator; -- } -- -- -- /*! -- this function calculates the Hyperbolic Tangent -- look at the description of Tanh(...) -- -- (the abbreviation of Hyperbolic Tangent can be 'tgh' as well) -- */ -- template -- ValueType Tgh(const ValueType & x, ErrorCode * err = 0) -- { -- return Tanh(x, err); -- } -- -- /*! -- this function calculates the Hyperbolic Cotangent -- -- we're using the formula coth(x)= ( e^x + e^(-x) ) / ( e^x - e^(-x) ) -- */ -- template -- ValueType Coth(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- if( x.IsZero() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return ValueType(); // NaN is set by default -- } -- -- ValueType ex, emx, nominator, denominator; -- uint c = 0; -- -- c += ex.Exp(x); -- c += emx.Exp(-x); -- -- nominator = ex; -- c += nominator.Add(emx); -- denominator = ex; -- c += denominator.Sub(emx); -- -- c += nominator.Div(denominator); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return nominator; -- } -- -- -- /*! -- this function calculates the Hyperbolic Cotangent -- look at the description of Coth(...) -- -- (the abbreviation of Hyperbolic Cotangent can be 'ctgh' as well) -- */ -- template -- ValueType Ctgh(const ValueType & x, ErrorCode * err = 0) -- { -- return Coth(x, err); -- } -- -- -- /* -- * -- * inverse hyperbolic functions -- * -- * -- */ -- -- -- /*! -- inverse hyperbolic sine -- -- asinh(x) = ln( x + sqrt(x^2 + 1) ) -- */ -- template -- ValueType ASinh(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType xx(x), one, result; -- uint c = 0; -- one.SetOne(); -- -- c += xx.Mul(x); -- c += xx.Add(one); -- one.exponent.SubOne(); // one=0.5 -- // xx is >= 1 -- c += xx.PowFrac(one); // xx=sqrt(xx) -- c += xx.Add(x); -- c += result.Ln(xx); // xx > 0 -- -- // here can only be a carry -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- inverse hyperbolic cosine -- -- acosh(x) = ln( x + sqrt(x^2 - 1) ) x in <1, infinity) -- */ -- template -- ValueType ACosh(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType xx(x), one, result; -- uint c = 0; -- one.SetOne(); -- -- if( x < one ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return result; // NaN is set by default -- } -- -- c += xx.Mul(x); -- c += xx.Sub(one); -- // xx is >= 0 -- // we can't call a PowFrac when the 'x' is zero -- // if x is 0 the sqrt(0) is 0 -- if( !xx.IsZero() ) -- { -- one.exponent.SubOne(); // one=0.5 -- c += xx.PowFrac(one); // xx=sqrt(xx) -- } -- c += xx.Add(x); -- c += result.Ln(xx); // xx >= 1 -- -- // here can only be a carry -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- inverse hyperbolic tangent -- -- atanh(x) = 0.5 * ln( (1+x) / (1-x) ) x in (-1, 1) -- */ -- template -- ValueType ATanh(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType nominator(x), denominator, one, result; -- uint c = 0; -- one.SetOne(); -- -- if( !x.SmallerWithoutSignThan(one) ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return result; // NaN is set by default -- } -- -- c += nominator.Add(one); -- denominator = one; -- c += denominator.Sub(x); -- c += nominator.Div(denominator); -- c += result.Ln(nominator); -- c += result.exponent.SubOne(); -- -- // here can only be a carry -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- inverse hyperbolic tantent -- */ -- template -- ValueType ATgh(const ValueType & x, ErrorCode * err = 0) -- { -- return ATanh(x, err); -- } -- -- -- /*! -- inverse hyperbolic cotangent -- -- acoth(x) = 0.5 * ln( (x+1) / (x-1) ) x in (-infinity, -1) or (1, infinity) -- */ -- template -- ValueType ACoth(const ValueType & x, ErrorCode * err = 0) -- { -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; // NaN -- } -- -- ValueType nominator(x), denominator(x), one, result; -- uint c = 0; -- one.SetOne(); -- -- if( !x.GreaterWithoutSignThan(one) ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return result; // NaN is set by default -- } -- -- c += nominator.Add(one); -- c += denominator.Sub(one); -- c += nominator.Div(denominator); -- c += result.Ln(nominator); -- c += result.exponent.SubOne(); -- -- // here can only be a carry -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- inverse hyperbolic cotantent -- */ -- template -- ValueType ACtgh(const ValueType & x, ErrorCode * err = 0) -- { -- return ACoth(x, err); -- } -- -- -- -- -- -- /* -- * -- * functions for converting between degrees, radians and gradians -- * -- * -- */ -- -- -- /*! -- this function converts degrees to radians -- -- it returns: x * pi / 180 -- */ -- template -- ValueType DegToRad(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result, temp; -- uint c = 0; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- result = x; -- -- // it is better to make division first and then multiplication -- // the result is more accurate especially when x is: 90,180,270 or 360 -- temp = 180; -- c += result.Div(temp); -- -- temp.SetPi(); -- c += result.Mul(temp); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- this function converts radians to degrees -- -- it returns: x * 180 / pi -- */ -- template -- ValueType RadToDeg(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result, delimiter; -- uint c = 0; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- result = 180; -- c += result.Mul(x); -- -- delimiter.SetPi(); -- c += result.Div(delimiter); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- this function converts degrees in the long format into one value -- -- long format: (degrees, minutes, seconds) -- minutes and seconds must be greater than or equal zero -- -- result: -- if d>=0 : result= d + ((s/60)+m)/60 -- if d<0 : result= d - ((s/60)+m)/60 -- -- ((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because -- there's only one division) -- -- for example: -- DegToDeg(10, 30, 0) = 10.5 -- DegToDeg(10, 24, 35.6)=10.4098(8) -- */ -- template -- ValueType DegToDeg( const ValueType & d, const ValueType & m, const ValueType & s, -- ErrorCode * err = 0) -- { -- ValueType delimiter, multipler; -- uint c = 0; -- -- if( d.IsNan() || m.IsNan() || s.IsNan() || m.IsSign() || s.IsSign() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- delimiter.SetZeroNan(); // not needed, only to get rid of GCC warning about an uninitialized variable -- -- return delimiter; -- } -- -- multipler = 60; -- delimiter = 3600; -- -- c += multipler.Mul(m); -- c += multipler.Add(s); -- c += multipler.Div(delimiter); -- -- if( d.IsSign() ) -- multipler.ChangeSign(); -- -- c += multipler.Add(d); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return multipler; -- } -- -- -- /*! -- this function converts degrees in the long format to radians -- */ -- template -- ValueType DegToRad( const ValueType & d, const ValueType & m, const ValueType & s, -- ErrorCode * err = 0) -- { -- ValueType temp_deg = DegToDeg(d,m,s,err); -- -- if( err && *err!=err_ok ) -- return temp_deg; -- -- return DegToRad(temp_deg, err); -- } -- -- -- /*! -- this function converts gradians to radians -- -- it returns: x * pi / 200 -- */ -- template -- ValueType GradToRad(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result, temp; -- uint c = 0; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- result = x; -- -- // it is better to make division first and then multiplication -- // the result is more accurate especially when x is: 100,200,300 or 400 -- temp = 200; -- c += result.Div(temp); -- -- temp.SetPi(); -- c += result.Mul(temp); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- this function converts radians to gradians -- -- it returns: x * 200 / pi -- */ -- template -- ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result, delimiter; -- uint c = 0; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- result = 200; -- c += result.Mul(x); -- -- delimiter.SetPi(); -- c += result.Div(delimiter); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- this function converts degrees to gradians -- -- it returns: x * 200 / 180 -- */ -- template -- ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result, temp; -- uint c = 0; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- result = x; -- -- temp = 200; -- c += result.Mul(temp); -- -- temp = 180; -- c += result.Div(temp); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- /*! -- this function converts degrees in the long format to gradians -- */ -- template -- ValueType DegToGrad( const ValueType & d, const ValueType & m, const ValueType & s, -- ErrorCode * err = 0) -- { -- ValueType temp_deg = DegToDeg(d,m,s,err); -- -- if( err && *err!=err_ok ) -- return temp_deg; -- -- return DegToGrad(temp_deg, err); -- } -- -- -- /*! -- this function converts degrees to gradians -- -- it returns: x * 180 / 200 -- */ -- template -- ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0) -- { -- ValueType result, temp; -- uint c = 0; -- -- if( x.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return x; -- } -- -- result = x; -- -- temp = 180; -- c += result.Mul(temp); -- -- temp = 200; -- c += result.Div(temp); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return result; -- } -- -- -- -- -- /* -- * -- * another functions -- * -- * -- */ -- -- -- /*! -- this function calculates the square root -- -- Sqrt(9) = 3 -- */ -- template -- ValueType Sqrt(ValueType x, ErrorCode * err = 0) -- { -- if( x.IsNan() || x.IsSign() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return x; -- } -- -- uint c = x.Sqrt(); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return x; -- } -- -- -- -- namespace auxiliaryfunctions -- { -- -- template -- bool RootCheckIndexSign(ValueType & x, const ValueType & index, ErrorCode * err) -- { -- if( index.IsSign() ) -- { -- // index cannot be negative -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return true; -- } -- -- return false; -- } -- -- -- template -- bool RootCheckIndexZero(ValueType & x, const ValueType & index, ErrorCode * err) -- { -- if( index.IsZero() ) -- { -- if( x.IsZero() ) -- { -- // there isn't root(0;0) - we assume it's not defined -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return true; -- } -- -- // root(x;0) is 1 (if x!=0) -- x.SetOne(); -- -- if( err ) -- *err = err_ok; -- -- return true; -- } -- -- return false; -- } -- -- -- template -- bool RootCheckIndexOne(const ValueType & index, ErrorCode * err) -- { -- ValueType one; -- one.SetOne(); -- -- if( index == one ) -- { -- //root(x;1) is x -- // we do it because if we used the PowFrac function -- // we would lose the precision -- if( err ) -- *err = err_ok; -- -- return true; -- } -- -- return false; -- } -- -- -- template -- bool RootCheckIndexTwo(ValueType & x, const ValueType & index, ErrorCode * err) -- { -- if( index == 2 ) -- { -- x = Sqrt(x, err); -- -- return true; -- } -- -- return false; -- } -- -- -- template -- bool RootCheckIndexFrac(ValueType & x, const ValueType & index, ErrorCode * err) -- { -- if( !index.IsInteger() ) -- { -- // index must be integer -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return true; -- } -- -- return false; -- } -- -- -- template -- bool RootCheckXZero(ValueType & x, ErrorCode * err) -- { -- if( x.IsZero() ) -- { -- // root(0;index) is zero (if index!=0) -- // RootCheckIndexZero() must be called beforehand -- x.SetZero(); -- -- if( err ) -- *err = err_ok; -- -- return true; -- } -- -- return false; -- } -- -- -- template -- bool RootCheckIndex(ValueType & x, const ValueType & index, ErrorCode * err, bool * change_sign) -- { -- *change_sign = false; -- -- if( index.Mod2() ) -- { -- // index is odd (1,3,5...) -- if( x.IsSign() ) -- { -- *change_sign = true; -- x.Abs(); -- } -- } -- else -- { -- // index is even -- // x cannot be negative -- if( x.IsSign() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return true; -- } -- } -- -- return false; -- } -- -- -- template -- uint RootCorrectInteger(ValueType & old_x, ValueType & x, const ValueType & index) -- { -- if( !old_x.IsInteger() || x.IsInteger() || !index.exponent.IsSign() ) -- return 0; -- -- // old_x is integer, -- // x is not integer, -- // index is relatively small (index.exponent<0 or index.exponent<=0) -- // (because we're using a special powering algorithm Big::PowUInt()) -- -- uint c = 0; -- -- ValueType temp(x); -- c += temp.Round(); -- -- ValueType temp_round(temp); -- c += temp.PowUInt(index); -- -- if( temp == old_x ) -- x = temp_round; -- -- return (c==0)? 0 : 1; -- } -- -- -- -- } // namespace auxiliaryfunctions -- -- -- -- /*! -- indexth Root of x -- index must be integer and not negative <0;1;2;3....) -- -- if index==0 the result is one -- if x==0 the result is zero and we assume root(0;0) is not defined -- -- if index is even (2;4;6...) the result is x^(1/index) and x>0 -- if index is odd (1;2;3;...) the result is either -- -(abs(x)^(1/index)) if x<0 or -- x^(1/index)) if x>0 -- -- (for index==1 the result is equal x) -- */ -- template -- ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0) -- { -- using namespace auxiliaryfunctions; -- -- if( x.IsNan() || index.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return x; -- } -- -- if( RootCheckIndexSign(x, index, err) ) return x; -- if( RootCheckIndexZero(x, index, err) ) return x; -- if( RootCheckIndexOne ( index, err) ) return x; -- if( RootCheckIndexTwo (x, index, err) ) return x; -- if( RootCheckIndexFrac(x, index, err) ) return x; -- if( RootCheckXZero (x, err) ) return x; -- -- // index integer and index!=0 -- // x!=0 -- -- ValueType old_x(x); -- bool change_sign; -- -- if( RootCheckIndex(x, index, err, &change_sign ) ) return x; -- -- ValueType temp; -- uint c = 0; -- -- // we're using the formula: root(x ; n) = exp( ln(x) / n ) -- c += temp.Ln(x); -- c += temp.Div(index); -- c += x.Exp(temp); -- -- if( change_sign ) -- { -- // x is different from zero -- x.SetSign(); -- } -- -- c += RootCorrectInteger(old_x, x, index); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return x; -- } -- -- -- -- /*! -- absolute value of x -- e.g. -2 = 2 -- 2 = 2 -- */ -- template -- ValueType Abs(const ValueType & x) -- { -- ValueType result( x ); -- result.Abs(); -- -- return result; -- } -- -- -- /*! -- it returns the sign of the value -- e.g. -2 = -1 -- 0 = 0 -- 10 = 1 -- */ -- template -- ValueType Sgn(ValueType x) -- { -- x.Sgn(); -- -- return x; -- } -- -- -- /*! -- the remainder from a division -- -- e.g. -- mod( 12.6 ; 3) = 0.6 because 12.6 = 3*4 + 0.6 -- mod(-12.6 ; 3) = -0.6 bacause -12.6 = 3*(-4) + (-0.6) -- mod( 12.6 ; -3) = 0.6 -- mod(-12.6 ; -3) = -0.6 -- */ -- template -- ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0) -- { -- if( a.IsNan() || b.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- a.SetNan(); -- -- return a; -- } -- -- uint c = a.Mod(b); -- -- if( err ) -- *err = c ? err_overflow : err_ok; -- -- return a; -- } -- -- -- -- namespace auxiliaryfunctions -- { -- -- /*! -- this function is used to store factorials in a given container -- 'more' means how many values should be added at the end -- -- e.g. -- std::vector fact; -- SetFactorialSequence(fact, 3); -- // now the container has three values: 1 1 2 -- -- SetFactorialSequence(fact, 2); -- // now the container has five values: 1 1 2 6 24 -- */ -- template -- void SetFactorialSequence(std::vector & fact, uint more = 20) -- { -- if( more == 0 ) -- more = 1; -- -- uint start = static_cast(fact.size()); -- fact.resize(fact.size() + more); -- -- if( start == 0 ) -- { -- fact[0] = 1; -- ++start; -- } -- -- for(uint i=start ; i -- ValueType SetBernoulliNumbersSum(CGamma & cgamma, const ValueType & n_, uint m, -- const volatile StopCalculating * stop = 0) -- { -- ValueType k_, temp, temp2, temp3, sum; -- -- sum.SetZero(); -- -- for(uint k=0 ; kWasStopSignal() ) -- return ValueType(); // NaN -- -- if( k>1 && (k & 1) == 1 ) // for that k the Bernoulli number is zero -- continue; -- -- k_ = k; -- -- temp = n_; // n_ is equal 2 -- temp.Pow(k_); -- // temp = 2^k -- -- temp2 = cgamma.fact[m]; -- temp3 = cgamma.fact[k]; -- temp3.Mul(cgamma.fact[m-k]); -- temp2.Div(temp3); -- // temp2 = (m k) = m! / ( k! * (m-k)! ) -- -- temp.Mul(temp2); -- temp.Mul(cgamma.bern[k]); -- -- sum.Add(temp); -- // sum += 2^k * (m k) * B(k) -- -- if( sum.IsNan() ) -- break; -- } -- -- return sum; -- } -- -- -- /*! -- an auxiliary function used to calculate Bernoulli numbers -- start is >= 2 -- -- we use the recurrence formula: -- B(m) = 1 / (2*(1 - 2^m)) * sum(m) -- where sum(m) is calculated by SetBernoulliNumbersSum() -- */ -- template -- bool SetBernoulliNumbersMore(CGamma & cgamma, uint start, const volatile StopCalculating * stop = 0) -- { -- ValueType denominator, temp, temp2, temp3, m_, sum, sum2, n_, k_; -- -- const uint n = 2; -- n_ = n; -- -- // start is >= 2 -- for(uint m=start ; mWasStopSignal() ) -- { -- cgamma.bern.resize(m); // valid numbers are in [0, m-1] -- return false; -- } -- -- cgamma.bern[m].Div(denominator); -- } -- } -- -- return true; -- } -- -- -- /*! -- this function is used to calculate Bernoulli numbers, -- returns false if there was a stop signal, -- 'more' means how many values should be added at the end -- -- e.g. -- typedef Big<1,2> MyBig; -- CGamma cgamma; -- SetBernoulliNumbers(cgamma, 3); -- // now we have three first Bernoulli numbers: 1 -0.5 0.16667 -- -- SetBernoulliNumbers(cgamma, 4); -- // now we have 7 Bernoulli numbers: 1 -0.5 0.16667 0 -0.0333 0 0.0238 -- */ -- template -- bool SetBernoulliNumbers(CGamma & cgamma, uint more = 20, const volatile StopCalculating * stop = 0) -- { -- if( more == 0 ) -- more = 1; -- -- uint start = static_cast(cgamma.bern.size()); -- cgamma.bern.resize(cgamma.bern.size() + more); -- -- if( start == 0 ) -- { -- cgamma.bern[0].SetOne(); -- ++start; -- } -- -- if( cgamma.bern.size() == 1 ) -- return true; -- -- if( start == 1 ) -- { -- cgamma.bern[1].Set05(); -- cgamma.bern[1].ChangeSign(); -- ++start; -- } -- -- // we should have sufficient factorials in cgamma.fact -- if( cgamma.fact.size() < cgamma.bern.size() ) -- SetFactorialSequence(cgamma.fact, static_cast(cgamma.bern.size() - cgamma.fact.size())); -- -- -- return SetBernoulliNumbersMore(cgamma, start, stop); -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- -- we calculate a sum: -- sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) ) } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ... -- B(m) means a mth Bernoulli number -- the sum starts from m=2, we calculate as long as the value will not change after adding a next part -- */ -- template -- ValueType GammaFactorialHighSum(const ValueType & n, CGamma & cgamma, ErrorCode & err, -- const volatile StopCalculating * stop) -- { -- ValueType temp, temp2, denominator, sum, oldsum; -- -- sum.SetZero(); -- -- for(uint m=2 ; mWasStopSignal() ) -- { -- err = err_interrupt; -- return ValueType(); // NaN -- } -- -- temp = (m-1); -- denominator = n; -- denominator.Pow(temp); -- // denominator = n ^ (m-1) -- -- temp = m; -- temp2 = temp; -- temp.Mul(temp2); -- temp.Sub(temp2); -- // temp = m^2 - m -- -- denominator.Mul(temp); -- // denominator = (m^2 - m) * n ^ (m-1) -- -- if( m >= cgamma.bern.size() ) -- { -- if( !SetBernoulliNumbers(cgamma, m - cgamma.bern.size() + 1 + 3, stop) ) // 3 more than needed -- { -- // there was the stop signal -- err = err_interrupt; -- return ValueType(); // NaN -- } -- } -- -- temp = cgamma.bern[m]; -- temp.Div(denominator); -- -- oldsum = sum; -- sum.Add(temp); -- -- if( sum.IsNan() || oldsum==sum ) -- break; -- } -- -- return sum; -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- -- we calculate a helper function GammaFactorialHigh() by using Stirling's series: -- n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) ) -- where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY) -- and sum(n) is calculated by GammaFactorialHighSum() -- */ -- template -- ValueType GammaFactorialHigh(const ValueType & n, CGamma & cgamma, ErrorCode & err, -- const volatile StopCalculating * stop) -- { -- ValueType temp, temp2, temp3, denominator, sum; -- -- temp.Set2Pi(); -- temp.Mul(n); -- temp2 = Sqrt(temp); -- // temp2 = sqrt(2*pi*n) -- -- temp = n; -- temp3.SetE(); -- temp.Div(temp3); -- temp.Pow(n); -- // temp = (n/e)^n -- -- sum = GammaFactorialHighSum(n, cgamma, err, stop); -- temp3.Exp(sum); -- // temp3 = exp(sum) -- -- temp.Mul(temp2); -- temp.Mul(temp3); -- -- return temp; -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- -- Gamma(x) = GammaFactorialHigh(x-1) -- */ -- template -- ValueType GammaPlusHigh(ValueType n, CGamma & cgamma, ErrorCode & err, const volatile StopCalculating * stop) -- { -- ValueType one; -- -- one.SetOne(); -- n.Sub(one); -- -- return GammaFactorialHigh(n, cgamma, err, stop); -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- -- we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY] -- we use the formula: -- gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1) -- */ -- template -- ValueType GammaPlusLowIntegerInt(uint n, CGamma & cgamma) -- { -- TTMATH_ASSERT( n > 0 ) -- -- if( n - 1 < static_cast(cgamma.fact.size()) ) -- return cgamma.fact[n - 1]; -- -- ValueType res; -- uint start = 2; -- -- if( cgamma.fact.size() < 2 ) -- { -- res.SetOne(); -- } -- else -- { -- start = static_cast(cgamma.fact.size()); -- res = cgamma.fact[start-1]; -- } -- -- for(uint i=start ; i -- ValueType GammaPlusLowInteger(const ValueType & n, CGamma & cgamma) -- { -- sint n_; -- -- n.ToInt(n_); -- -- return GammaPlusLowIntegerInt(n_, cgamma); -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- -- we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY] -- we use a recurrence formula: -- gamma(z+1) = z * gamma(z) -- then: gamma(z) = gamma(z+1) / z -- -- e.g. -- gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 ) -- */ -- template -- ValueType GammaPlusLow(ValueType n, CGamma & cgamma, ErrorCode & err, const volatile StopCalculating * stop) -- { -- ValueType one, denominator, temp, boundary; -- -- if( n.IsInteger() ) -- return GammaPlusLowInteger(n, cgamma); -- -- one.SetOne(); -- denominator = n; -- boundary = TTMATH_GAMMA_BOUNDARY; -- -- while( n < boundary ) -- { -- n.Add(one); -- denominator.Mul(n); -- } -- -- n.Add(one); -- -- // now n is sufficient big -- temp = GammaPlusHigh(n, cgamma, err, stop); -- temp.Div(denominator); -- -- return temp; -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- */ -- template -- ValueType GammaPlus(const ValueType & n, CGamma & cgamma, ErrorCode & err, const volatile StopCalculating * stop) -- { -- if( n > TTMATH_GAMMA_BOUNDARY ) -- return GammaPlusHigh(n, cgamma, err, stop); -- -- return GammaPlusLow(n, cgamma, err, stop); -- } -- -- -- /*! -- an auxiliary function used to calculate the Gamma() function -- -- this function is used when n is negative -- we use the reflection formula: -- gamma(1-z) * gamma(z) = pi / sin(pi*z) -- then: gamma(z) = pi / (sin(pi*z) * gamma(1-z)) -- -- */ -- template -- ValueType GammaMinus(const ValueType & n, CGamma & cgamma, ErrorCode & err, const volatile StopCalculating * stop) -- { -- ValueType pi, denominator, temp, temp2; -- -- if( n.IsInteger() ) -- { -- // gamma function is not defined when n is negative and integer -- err = err_improper_argument; -- return temp; // NaN -- } -- -- pi.SetPi(); -- -- temp = pi; -- temp.Mul(n); -- temp2 = Sin(temp); -- // temp2 = sin(pi * n) -- -- temp.SetOne(); -- temp.Sub(n); -- temp = GammaPlus(temp, cgamma, err, stop); -- // temp = gamma(1 - n) -- -- temp.Mul(temp2); -- pi.Div(temp); -- -- return pi; -- } -- -- } // namespace auxiliaryfunctions -- -- -- -- /*! -- this function calculates the Gamma function -- -- it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma() -- e.g. -- typedef Big<1,2> MyBig; -- MyBig x=234, y=345.53; -- CGamma cgamma; -- std::cout << Gamma(x, cgamma) << std::endl; -- std::cout << Gamma(y, cgamma) << std::endl; -- in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers), -- and they will be reused in next calls to the function -- -- each thread should have its own CGamma<> object, and you can use these objects with Factorial() function too -- */ -- template -- ValueType Gamma(const ValueType & n, CGamma & cgamma, ErrorCode * err = 0, -- const volatile StopCalculating * stop = 0) -- { -- using namespace auxiliaryfunctions; -- -- ValueType result; -- ErrorCode err_tmp; -- -- if( n.IsNan() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- return n; -- } -- -- if( cgamma.history.Get(n, result, err_tmp) ) -- { -- if( err ) -- *err = err_tmp; -- -- return result; -- } -- -- err_tmp = err_ok; -- -- if( n.IsSign() ) -- { -- result = GammaMinus(n, cgamma, err_tmp, stop); -- } -- else -- if( n.IsZero() ) -- { -- err_tmp = err_improper_argument; -- result.SetNan(); -- } -- else -- { -- result = GammaPlus(n, cgamma, err_tmp, stop); -- } -- -- if( result.IsNan() && err_tmp==err_ok ) -- err_tmp = err_overflow; -- -- if( err ) -- *err = err_tmp; -- -- if( stop && !stop->WasStopSignal() ) -- cgamma.history.Add(n, result, err_tmp); -- -- return result; -- } -- -- -- /*! -- this function calculates the Gamma function -- -- note: this function should be used only in a single-thread environment -- */ -- template -- ValueType Gamma(const ValueType & n, ErrorCode * err = 0) -- { -- // warning: this static object is not thread safe -- static CGamma cgamma; -- -- return Gamma(n, cgamma, err); -- } -- -- -- -- namespace auxiliaryfunctions -- { -- -- /*! -- an auxiliary function for calculating the factorial function -- -- we use the formula: -- x! = gamma(x+1) -- */ -- template -- ValueType Factorial2(ValueType x, -- CGamma * cgamma = 0, -- ErrorCode * err = 0, -- const volatile StopCalculating * stop = 0) -- { -- ValueType result, one; -- -- if( x.IsNan() || x.IsSign() || !x.IsInteger() ) -- { -- if( err ) -- *err = err_improper_argument; -- -- x.SetNan(); -- -- return x; -- } -- -- one.SetOne(); -- x.Add(one); -- -- if( cgamma ) -- return Gamma(x, *cgamma, err, stop); -- -- return Gamma(x, err); -- } -- -- } // namespace auxiliaryfunctions -- -- -- -- /*! -- the factorial from given 'x' -- e.g. -- Factorial(4) = 4! = 1*2*3*4 -- -- it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial() -- e.g. -- typedef Big<1,2> MyBig; -- MyBig x=234, y=54345; -- CGamma cgamma; -- std::cout << Factorial(x, cgamma) << std::endl; -- std::cout << Factorial(y, cgamma) << std::endl; -- in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers), -- and they will be reused in next calls to the function -- -- each thread should have its own CGamma<> object, and you can use these objects with Gamma() function too -- */ -- template -- ValueType Factorial(const ValueType & x, CGamma & cgamma, ErrorCode * err = 0, -- const volatile StopCalculating * stop = 0) -- { -- return auxiliaryfunctions::Factorial2(x, &cgamma, err, stop); -- } -- -- -- /*! -- the factorial from given 'x' -- e.g. -- Factorial(4) = 4! = 1*2*3*4 -- -- note: this function should be used only in a single-thread environment -- */ -- template -- ValueType Factorial(const ValueType & x, ErrorCode * err = 0) -- { -- return auxiliaryfunctions::Factorial2(x, (CGamma*)0, err, 0); -- } -- -- -- /*! -- this method prepares some coefficients: factorials and Bernoulli numbers -- stored in 'fact' and 'bern' objects -- -- we're defining the method here because we're using Gamma() function which -- is not available in ttmathobjects.h -- -- read the doc info in ttmathobjects.h file where CGamma<> struct is declared -- */ -- template -- void CGamma::InitAll() -- { -- ValueType x = TTMATH_GAMMA_BOUNDARY + 1; -- -- // history.Remove(x) removes only one object -- // we must be sure that there are not others objects with the key 'x' -- while( history.Remove(x) ) -- { -- } -- -- // the simplest way to initialize is to call the Gamma function with (TTMATH_GAMMA_BOUNDARY + 1) -- // when x is larger then fewer coefficients we need -- Gamma(x, *this); -- } -- -- -- --} // namespace -- -- --#ifdef _MSC_VER --//warning C4127: conditional expression is constant --#pragma warning( default: 4127 ) --//warning C4702: unreachable code --#pragma warning( default: 4702 ) --//warning C4800: forcing value to bool 'true' or 'false' (performance warning) --#pragma warning( default: 4800 ) --#endif -- --#endif -diff --git a/extern/ttmath/ttmathint.h b/extern/ttmath/ttmathint.h -deleted file mode 100644 -index 8ad0189f93..0000000000 ---- a/extern/ttmath/ttmathint.h -+++ /dev/null -@@ -1,1917 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2011, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- -- --#ifndef headerfilettmathint --#define headerfilettmathint -- --/*! -- \file ttmathint.h -- \brief template class Int --*/ -- --#include "ttmathuint.h" -- --namespace ttmath --{ -- -- --/*! -- \brief Int implements a big integer value with a sign -- -- value_size - how many bytes specify our value -- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits -- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits -- value_size = 1,2,3,4,5,6.... --*/ --template --class Int : public UInt --{ --public: -- -- /*! -- this method sets the max value which this class can hold -- (all bits will be one besides the last one) -- */ -- void SetMax() -- { -- UInt::SetMax(); -- UInt::table[value_size-1] = ~ TTMATH_UINT_HIGHEST_BIT; -- } -- -- -- /*! -- this method sets the min value which this class can hold -- (all bits will be zero besides the last one which is one) -- */ -- void SetMin() -- { -- UInt::SetZero(); -- UInt::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT; -- } -- -- -- /*! -- this method sets -1 as the value -- (-1 is equal the max value in an unsigned type) -- */ -- void SetSignOne() -- { -- UInt::SetMax(); -- } -- -- -- /*! -- we change the sign of the value -- -- if it isn't possible to change the sign this method returns 1 -- else return 0 and changing the sign -- */ -- uint ChangeSign() -- { -- /* -- if the value is equal that one which has been returned from SetMin -- (only the highest bit is set) that means we can't change sign -- because the value is too big (bigger about one) -- -- e.g. when value_size = 1 and value is -2147483648 we can't change it to the -- 2147483648 because the max value which can be held is 2147483647 -- -- we don't change the value and we're using this fact somewhere in some methods -- (if we look on our value without the sign we get the correct value -- eg. -2147483648 in Int<1> will be 2147483648 on the UInt<1> type) -- */ -- if( UInt::IsOnlyTheHighestBitSet() ) -- return 1; -- -- UInt temp(*this); -- UInt::SetZero(); -- UInt::Sub(temp); -- -- return 0; -- } -- -- -- -- /*! -- this method sets the sign -- -- e.g. 1 -> -1 -- -2 -> -2 -- -- from a positive value we make a negative value, -- if the value is negative we do nothing -- */ -- void SetSign() -- { -- if( IsSign() ) -- return; -- -- ChangeSign(); -- } -- -- -- -- /*! -- this method returns true if there's the sign -- -- (the highest bit will be converted to the bool) -- */ -- bool IsSign() const -- { -- return UInt::IsTheHighestBitSet(); -- } -- -- -- -- /*! -- it sets an absolute value -- -- it can return carry (1) (look on ChangeSign() for details) -- */ -- uint Abs() -- { -- if( !IsSign() ) -- return 0; -- -- return ChangeSign(); -- } -- -- -- -- -- /*! -- * -- * basic mathematic functions -- * -- */ -- --private: -- -- uint CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign) -- { -- if( !p1_is_sign && !p2_is_sign ) -- { -- if( UInt::IsTheHighestBitSet() ) -- return 1; -- } -- -- if( p1_is_sign && p2_is_sign ) -- { -- if( ! UInt::IsTheHighestBitSet() ) -- return 1; -- } -- -- return 0; -- } -- -- --public: -- -- /*! -- this method adds two value with a sign and returns a carry -- -- we're using methods from the base class because values are stored with U2 -- we must only make the carry correction -- -- this = p1(=this) + p2 -- -- when p1>=0 i p2>=0 carry is set when the highest bit of value is set -- when p1<0 i p2<0 carry is set when the highest bit of value is clear -- when p1>=0 i p2<0 carry will never be set -- when p1<0 i p2>=0 carry will never be set -- */ -- uint Add(const Int & ss2) -- { -- bool p1_is_sign = IsSign(); -- bool p2_is_sign = ss2.IsSign(); -- -- UInt::Add(ss2); -- -- return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign); -- } -- -- -- /*! -- this method adds one *unsigned* word (at a specific position) -- and returns a carry (if it was) -- -- look at a description in UInt<>::AddInt(...) -- */ -- uint AddInt(uint value, uint index = 0) -- { -- bool p1_is_sign = IsSign(); -- -- UInt::AddInt(value, index); -- -- return CorrectCarryAfterAdding(p1_is_sign, false); -- } -- -- -- /*! -- this method adds two *unsigned* words to the existing value -- and these words begin on the 'index' position -- -- index should be equal or smaller than value_size-2 (index <= value_size-2) -- x1 - lower word, x2 - higher word -- -- look at a description in UInt<>::AddTwoInts(...) -- */ -- uint AddTwoInts(uint x2, uint x1, uint index) -- { -- bool p1_is_sign = IsSign(); -- -- UInt::AddTwoInts(x2, x1, index); -- -- return CorrectCarryAfterAdding(p1_is_sign, false); -- } -- --private: -- -- uint CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign) -- { -- if( !p1_is_sign && p2_is_sign ) -- { -- if( UInt::IsTheHighestBitSet() ) -- return 1; -- } -- -- if( p1_is_sign && !p2_is_sign ) -- { -- if( ! UInt::IsTheHighestBitSet() ) -- return 1; -- } -- -- return 0; -- } -- --public: -- -- /*! -- this method subtracts two values with a sign -- -- we don't use the previous Add because the method ChangeSign can -- sometimes return carry -- -- this = p1(=this) - p2 -- -- when p1>=0 i p2>=0 carry will never be set -- when p1<0 i p2<0 carry will never be set -- when p1>=0 i p2<0 carry is set when the highest bit of value is set -- when p1<0 i p2>=0 carry is set when the highest bit of value is clear -- */ -- uint Sub(const Int & ss2) -- { -- bool p1_is_sign = IsSign(); -- bool p2_is_sign = ss2.IsSign(); -- -- UInt::Sub(ss2); -- -- return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign); -- } -- -- -- /*! -- this method subtracts one *unsigned* word (at a specific position) -- and returns a carry (if it was) -- */ -- uint SubInt(uint value, uint index = 0) -- { -- bool p1_is_sign = IsSign(); -- -- UInt::SubInt(value, index); -- -- return CorrectCarryAfterSubtracting(p1_is_sign, false); -- } -- -- -- /*! -- this method adds one to the value and returns carry -- */ -- uint AddOne() -- { -- bool p1_is_sign = IsSign(); -- -- UInt::AddOne(); -- -- return CorrectCarryAfterAdding(p1_is_sign, false); -- } -- -- -- /*! -- this method subtracts one from the value and returns carry -- */ -- uint SubOne() -- { -- bool p1_is_sign = IsSign(); -- -- UInt::SubOne(); -- -- return CorrectCarryAfterSubtracting(p1_is_sign, false); -- } -- -- --private: -- -- -- uint CheckMinCarry(bool ss1_is_sign, bool ss2_is_sign) -- { -- /* -- we have to examine the sign of the result now -- but if the result is with the sign then: -- 1. if the signs were the same that means the result is too big -- (the result must be without a sign) -- 2. if the signs were different that means if the result -- is different from that one which has been returned from SetMin() -- that is carry (result too big) but if the result is equal SetMin() -- there'll be ok (and the next SetSign will has no effect because -- the value is actually negative -- look at description of that case -- in ChangeSign()) -- */ -- if( IsSign() ) -- { -- if( ss1_is_sign != ss2_is_sign ) -- { -- /* -- there can be one case where signs are different and -- the result will be equal the value from SetMin() (only the highest bit is set) -- (this situation is ok) -- */ -- if( !UInt::IsOnlyTheHighestBitSet() ) -- return 1; -- } -- else -- { -- // signs were the same -- return 1; -- } -- } -- -- return 0; -- } -- -- --public: -- -- -- /*! -- multiplication: this = this * ss2 -- -- it can return a carry -- */ -- uint MulInt(sint ss2) -- { -- bool ss1_is_sign, ss2_is_sign; -- uint c; -- -- ss1_is_sign = IsSign(); -- -- /* -- we don't have to check the carry from Abs (values will be correct -- because next we're using the method MulInt from the base class UInt -- which is without a sign) -- */ -- Abs(); -- -- if( ss2 < 0 ) -- { -- ss2 = -ss2; -- ss2_is_sign = true; -- } -- else -- { -- ss2_is_sign = false; -- } -- -- c = UInt::MulInt((uint)ss2); -- c += CheckMinCarry(ss1_is_sign, ss2_is_sign); -- -- if( ss1_is_sign != ss2_is_sign ) -- SetSign(); -- -- return c; -- } -- -- -- -- /*! -- multiplication this = this * ss2 -- -- it returns carry if the result is too big -- (we're using the method from the base class but we have to make -- one correction in account of signs) -- */ -- uint Mul(Int ss2) -- { -- bool ss1_is_sign, ss2_is_sign; -- uint c; -- -- ss1_is_sign = IsSign(); -- ss2_is_sign = ss2.IsSign(); -- -- /* -- we don't have to check the carry from Abs (values will be correct -- because next we're using the method Mul from the base class UInt -- which is without a sign) -- */ -- Abs(); -- ss2.Abs(); -- -- c = UInt::Mul(ss2); -- c += CheckMinCarry(ss1_is_sign, ss2_is_sign); -- -- if( ss1_is_sign != ss2_is_sign ) -- SetSign(); -- -- return c; -- } -- -- -- /*! -- division this = this / ss2 -- returned values: -- 0 - ok -- 1 - division by zero -- -- for example: (result means 'this') -- 20 / 3 --> result: 6 remainder: 2 -- -20 / 3 --> result: -6 remainder: -2 -- 20 / -3 --> result: -6 remainder: 2 -- -20 / -3 --> result: 6 remainder: -2 -- -- in other words: this(old) = ss2 * this(new)(result) + remainder -- */ -- uint Div(Int ss2, Int * remainder = 0) -- { -- bool ss1_is_sign, ss2_is_sign; -- -- ss1_is_sign = IsSign(); -- ss2_is_sign = ss2.IsSign(); -- -- /* -- we don't have to test the carry from Abs as well as in Mul -- */ -- Abs(); -- ss2.Abs(); -- -- uint c = UInt::Div(ss2, remainder); -- -- if( ss1_is_sign != ss2_is_sign ) -- SetSign(); -- -- if( ss1_is_sign && remainder ) -- remainder->SetSign(); -- -- return c; -- } -- -- uint Div(const Int & ss2, Int & remainder) -- { -- return Div(ss2, &remainder); -- } -- -- -- /*! -- division this = this / ss2 (ss2 is int) -- returned values: -- 0 - ok -- 1 - division by zero -- -- for example: (result means 'this') -- 20 / 3 --> result: 6 remainder: 2 -- -20 / 3 --> result: -6 remainder: -2 -- 20 / -3 --> result: -6 remainder: 2 -- -20 / -3 --> result: 6 remainder: -2 -- -- in other words: this(old) = ss2 * this(new)(result) + remainder -- */ -- uint DivInt(sint ss2, sint * remainder = 0) -- { -- bool ss1_is_sign, ss2_is_sign; -- -- ss1_is_sign = IsSign(); -- -- /* -- we don't have to test the carry from Abs as well as in Mul -- */ -- Abs(); -- -- if( ss2 < 0 ) -- { -- ss2 = -ss2; -- ss2_is_sign = true; -- } -- else -- { -- ss2_is_sign = false; -- } -- -- uint rem; -- uint c = UInt::DivInt((uint)ss2, &rem); -- -- if( ss1_is_sign != ss2_is_sign ) -- SetSign(); -- -- if( remainder ) -- { -- if( ss1_is_sign ) -- *remainder = -sint(rem); -- else -- *remainder = sint(rem); -- } -- -- return c; -- } -- -- -- uint DivInt(sint ss2, sint & remainder) -- { -- return DivInt(ss2, &remainder); -- } -- -- --private: -- -- -- /*! -- power this = this ^ pow -- this can be negative -- pow is >= 0 -- */ -- uint Pow2(const Int & pow) -- { -- bool was_sign = IsSign(); -- uint c = 0; -- -- if( was_sign ) -- c += Abs(); -- -- uint c_temp = UInt::Pow(pow); -- if( c_temp > 0 ) -- return c_temp; // c_temp can be: 0, 1 or 2 -- -- if( was_sign && (pow.table[0] & 1) == 1 ) -- // negative value to the power of odd number is negative -- c += ChangeSign(); -- -- return (c==0)? 0 : 1; -- } -- -- --public: -- -- -- /*! -- power this = this ^ pow -- -- return values: -- 0 - ok -- 1 - carry -- 2 - incorrect arguments 0^0 or 0^(-something) -- */ -- uint Pow(Int pow) -- { -- if( !pow.IsSign() ) -- return Pow2(pow); -- -- if( UInt::IsZero() ) -- // if 'pow' is negative then -- // 'this' must be different from zero -- return 2; -- -- if( pow.ChangeSign() ) -- return 1; -- -- Int t(*this); -- uint c_temp = t.Pow2(pow); -- if( c_temp > 0 ) -- return c_temp; -- -- UInt::SetOne(); -- if( Div(t) ) -- return 1; -- -- return 0; -- } -- -- -- -- /*! -- * -- * convertion methods -- * -- */ --private: -- -- -- /*! -- an auxiliary method for converting both from UInt and Int -- */ -- template -- uint FromUIntOrInt(const UInt & p, bool UInt_type) -- { -- uint min_size = (value_size < argument_size)? value_size : argument_size; -- uint i; -- -- for(i=0 ; i::table[i] = p.table[i]; -- -- -- if( value_size > argument_size ) -- { -- uint fill; -- -- if( UInt_type ) -- fill = 0; -- else -- fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)? -- TTMATH_UINT_MAX_VALUE : 0; -- -- // 'this' is longer than 'p' -- for( ; i::table[i] = fill; -- } -- else -- { -- uint test = (UInt::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)? -- TTMATH_UINT_MAX_VALUE : 0; -- -- if( UInt_type && test!=0 ) -- return 1; -- -- for( ; i type into this class -- -- this operation has mainly sense if the value from p -- can be held in this type -- -- it returns a carry if the value 'p' is too big -- */ -- template -- uint FromInt(const Int & p) -- { -- return FromUIntOrInt(p, false); -- } -- -- -- /*! -- this method converts the sint type into this class -- */ -- uint FromInt(sint value) -- { -- uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0; -- -- for(uint i=1 ; i::table[i] = fill; -- -- UInt::table[0] = uint(value); -- -- // there'll never be a carry here -- return 0; -- } -- -- -- /*! -- this method converts UInt into this class -- */ -- template -- uint FromUInt(const UInt & p) -- { -- return FromUIntOrInt(p, true); -- } -- -- -- /*! -- this method converts UInt into this class -- */ -- template -- uint FromInt(const UInt & p) -- { -- return FromUIntOrInt(p, true); -- } -- -- -- /*! -- this method converts the uint type into this class -- */ -- uint FromUInt(uint value) -- { -- for(uint i=1 ; i::table[i] = 0; -- -- UInt::table[0] = value; -- -- // there can be a carry here when the size of this value is equal one word -- // and the 'value' has the highest bit set -- if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 ) -- return 1; -- -- return 0; -- } -- -- -- /*! -- this method converts the uint type into this class -- */ -- uint FromInt(uint value) -- { -- return FromUInt(value); -- } -- -- -- /*! -- the default assignment operator -- */ --/* Int & operator=(const Int & p) -- { -- FromInt(p); -- -- return *this; -- } -- */ -- -- /*! -- this operator converts an Int type to this class -- -- it doesn't return a carry -- */ --/* template -- Int & operator=(const Int & p) -- { -- FromInt(p); -- -- return *this; -- } -- */ -- -- /*! -- this method converts the sint type to this class -- */ -- Int & operator=(sint i) -- { -- FromInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting the uint to this class -- */ --/* Int(sint i) -- { -- FromInt(i); -- } --*/ -- -- /*! -- a copy constructor -- */ --/* Int(const Int & u) -- { -- FromInt(u); -- } --*/ -- -- /*! -- a constructor for copying from another types -- */ --/* template -- Int(const Int & u) -- { -- // look that 'size' we still set as 'value_size' and not as u.value_size -- FromInt(u); -- } --*/ -- -- -- /*! -- this operator converts an UInt type to this class -- -- it doesn't return a carry -- */ -- template -- Int & operator=(const UInt & p) -- { -- FromUInt(p); -- -- return *this; -- } -- -- -- /*! -- this method converts the Uint type to this class -- */ -- Int & operator=(uint i) -- { -- FromUInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting the uint to this class -- */ --/* Int(uint i) -- { -- FromUInt(i); -- } --*/ -- -- /*! -- a constructor for copying from another types -- */ --/* template -- Int(const UInt & u) -- { -- // look that 'size' we still set as 'value_size' and not as u.value_size -- FromUInt(u); -- } --*/ -- -- --#ifdef TTMATH_PLATFORM32 -- -- -- /*! -- this method converts unsigned 64 bit int type to this class -- ***this method is created only on a 32bit platform*** -- */ -- uint FromUInt(ulint n) -- { -- uint c = UInt::FromUInt(n); -- -- if( c ) -- return 1; -- -- if( value_size == 1 ) -- return ((UInt::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1; -- -- if( value_size == 2 ) -- return ((UInt::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0) ? 0 : 1; -- -- return 0; -- } -- -- -- /*! -- this method converts unsigned 64 bit int type to this class -- ***this method is created only on a 32bit platform*** -- */ -- uint FromInt(ulint n) -- { -- return FromUInt(n); -- } -- -- -- /*! -- this method converts signed 64 bit int type to this class -- ***this method is created only on a 32bit platform*** -- */ -- uint FromInt(slint n) -- { -- uint mask = (n < 0) ? TTMATH_UINT_MAX_VALUE : 0; -- -- UInt::table[0] = (uint)(ulint)n; -- -- if( value_size == 1 ) -- { -- if( uint(ulint(n) >> 32) != mask ) -- return 1; -- -- return ((UInt::table[0] & TTMATH_UINT_HIGHEST_BIT) == (mask & TTMATH_UINT_HIGHEST_BIT)) ? 0 : 1; -- } -- -- UInt::table[1] = (uint)(ulint(n) >> 32); -- -- for(uint i=2 ; i::table[i] = mask; -- -- return 0; -- } -- -- -- /*! -- this operator converts unsigned 64 bit int type to this class -- ***this operator is created only on a 32bit platform*** -- */ -- Int & operator=(ulint n) -- { -- FromUInt(n); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting unsigned 64 bit int to this class -- ***this constructor is created only on a 32bit platform*** -- */ --/* Int(ulint n) -- { -- FromUInt(n); -- } --*/ -- -- /*! -- this operator converts signed 64 bit int type to this class -- ***this operator is created only on a 32bit platform*** -- */ -- Int & operator=(slint n) -- { -- FromInt(n); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting signed 64 bit int to this class -- ***this constructor is created only on a 32bit platform*** -- */ --/* Int(slint n) -- { -- FromInt(n); -- } --*/ --#endif -- -- -- -- --#ifdef TTMATH_PLATFORM64 -- -- /*! -- this method converts 32 bit unsigned int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- uint FromUInt(unsigned int i) -- { -- return FromUInt(uint(i)); -- } -- -- -- /*! -- this method converts 32 bit unsigned int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- uint FromInt(unsigned int i) -- { -- return FromUInt(i); -- } -- -- -- /*! -- this method converts 32 bit signed int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- uint FromInt(signed int i) -- { -- return FromInt(sint(i)); -- } -- -- -- /*! -- this method converts 32 bit unsigned int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- Int & operator=(unsigned int i) -- { -- FromUInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting 32 bit unsigned int to this class -- ***this constructor is created only on a 64bit platform*** -- */ --/* Int(unsigned int i) -- { -- FromUInt(i); -- } --*/ -- -- /*! -- this operator converts 32 bit signed int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- Int & operator=(signed int i) -- { -- FromInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting 32 bit signed int to this class -- ***this constructor is created only on a 64bit platform*** -- */ --/* Int(signed int i) -- { -- FromInt(i); -- } --*/ --#endif -- -- -- -- /*! -- a constructor for converting string to this class (with the base=10) -- */ --/* Int(const char * s) -- { -- FromString(s); -- } --*/ -- -- /*! -- a constructor for converting a string to this class (with the base=10) -- */ --/* Int(const std::string & s) -- { -- FromString( s.c_str() ); -- } --*/ -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- a constructor for converting string to this class (with the base=10) -- */ -- Int(const wchar_t * s) -- { -- FromString(s); -- } -- -- -- /*! -- a constructor for converting a string to this class (with the base=10) -- */ -- Int(const std::wstring & s) -- { -- FromString( s.c_str() ); -- } -- --#endif -- -- -- /*! -- a default constructor -- -- we don't clear table etc. -- */ --/* Int() -- { -- } --*/ -- -- /*! -- the destructor -- */ --/* ~Int() -- { -- } --*/ -- -- /*! -- this method returns the lowest value from table with a sign -- -- we must be sure when we using this method whether the value -- will hold in an sint type or not (the rest value from table must be zero or -1) -- */ -- sint ToInt() const -- { -- return sint( UInt::table[0] ); -- } -- -- -- /*! -- this method converts the value to uint type -- can return a carry if the value is too long to store it in uint type -- */ -- uint ToUInt(uint & result) const -- { -- uint c = UInt::ToUInt(result); -- -- if( value_size == 1 ) -- return (result & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1; -- -- return c; -- } -- -- -- /*! -- this method converts the value to uint type -- can return a carry if the value is too long to store it in uint type -- */ -- uint ToInt(uint & result) const -- { -- return ToUInt(result); -- } -- -- -- /*! -- this method converts the value to sint type -- can return a carry if the value is too long to store it in sint type -- */ -- uint ToInt(sint & result) const -- { -- result = sint( UInt::table[0] ); -- uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0; -- -- if( (result & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) ) -- return 1; -- -- for(uint i=1 ; i::table[i] != mask ) -- return 1; -- -- return 0; -- } -- -- --#ifdef TTMATH_PLATFORM32 -- -- /*! -- this method converts the value to ulint type (64 bit unsigned integer) -- can return a carry if the value is too long to store it in ulint type -- *** this method is created only on a 32 bit platform *** -- */ -- uint ToUInt(ulint & result) const -- { -- uint c = UInt::ToUInt(result); -- -- if( value_size == 1 ) -- return (UInt::table[0] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1; -- -- if( value_size == 2 ) -- return (UInt::table[1] & TTMATH_UINT_HIGHEST_BIT) == 0 ? 0 : 1; -- -- return c; -- } -- -- -- /*! -- this method converts the value to ulint type (64 bit unsigned integer) -- can return a carry if the value is too long to store it in ulint type -- *** this method is created only on a 32 bit platform *** -- */ -- uint ToInt(ulint & result) const -- { -- return ToUInt(result); -- } -- -- -- /*! -- this method converts the value to slint type (64 bit signed integer) -- can return a carry if the value is too long to store it in slint type -- *** this method is created only on a 32 bit platform *** -- */ -- uint ToInt(slint & result) const -- { -- if( value_size == 1 ) -- { -- result = slint(sint(UInt::table[0])); -- } -- else -- { -- uint low = UInt::table[0]; -- uint high = UInt::table[1]; -- -- result = low; -- result |= (ulint(high) << TTMATH_BITS_PER_UINT); -- -- uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0; -- -- if( (high & TTMATH_UINT_HIGHEST_BIT) != (mask & TTMATH_UINT_HIGHEST_BIT) ) -- return 1; -- -- for(uint i=2 ; i::table[i] != mask ) -- return 1; -- } -- -- return 0; -- } -- --#endif -- -- -- --#ifdef TTMATH_PLATFORM64 -- -- /*! -- this method converts the value to a 32 bit unsigned integer -- can return a carry if the value is too long to store it in this type -- *** this method is created only on a 64 bit platform *** -- */ -- uint ToUInt(unsigned int & result) const -- { -- uint c = UInt::ToUInt(result); -- -- if( c || IsSign() ) -- return 1; -- -- return 0; -- } -- -- -- /*! -- this method converts the value to a 32 bit unsigned integer -- can return a carry if the value is too long to store it in this type -- *** this method is created only on a 64 bit platform *** -- */ -- uint ToInt(unsigned int & result) const -- { -- return ToUInt(result); -- } -- -- -- /*! -- this method converts the value to a 32 bit signed integer -- can return a carry if the value is too long to store it in this type -- *** this method is created only on a 64 bit platform *** -- */ -- uint ToInt(int & result) const -- { -- uint first = UInt::table[0]; -- -- result = int(first); -- uint mask = IsSign() ? TTMATH_UINT_MAX_VALUE : 0; -- -- if( (first >> 31) != (mask >> 31) ) -- return 1; -- -- for(uint i=1 ; i::table[i] != mask ) -- return 1; -- -- return 0; -- } -- --#endif -- -- -- -- /*! -- an auxiliary method for converting to a string -- */ -- template -- void ToStringBase(string_type & result, uint b = 10) const -- { -- if( IsSign() ) -- { -- Int temp(*this); -- temp.Abs(); -- temp.UInt::ToStringBase(result, b, true); -- } -- else -- { -- UInt::ToStringBase(result, b, false); -- } -- } -- -- /*! -- this method converts the value to a string with a base equal 'b' -- */ -- void ToString(std::string & result, uint b = 10) const -- { -- return ToStringBase(result, b); -- } -- -- -- /*! -- this method converts the value to a string with a base equal 'b' -- */ -- std::string ToString(uint b = 10) const -- { -- std::string result; -- ToStringBase(result, b); -- -- return result; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method converts the value to a string with a base equal 'b' -- */ -- void ToString(std::wstring & result, uint b = 10) const -- { -- return ToStringBase(result, b); -- } -- -- -- /*! -- this method converts the value to a string with a base equal 'b' -- */ -- std::wstring ToWString(uint b = 10) const -- { -- std::wstring result; -- ToStringBase(result, b); -- -- return result; -- } -- --#endif -- -- -- --private: -- -- /*! -- an auxiliary method for converting from a string -- */ -- template -- uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0) -- { -- bool is_sign = false; -- -- Misc::SkipWhiteCharacters(s); -- -- if( *s == '-' ) -- { -- is_sign = true; -- Misc::SkipWhiteCharacters(++s); -- } -- else -- if( *s == '+' ) -- { -- Misc::SkipWhiteCharacters(++s); -- } -- -- if( UInt::FromString(s,b,after_source,value_read) ) -- return 1; -- -- if( is_sign ) -- { -- Int mmin; -- -- mmin.SetMin(); -- -- /* -- the reference to mmin will be automatically converted to the reference -- to UInt type -- (this value can be equal mmin -- look at a description in ChangeSign()) -- */ -- if( UInt::operator>( mmin ) ) -- return 1; -- -- /* -- if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it) -- */ -- ChangeSign(); -- } -- else -- { -- Int mmax; -- -- mmax.SetMax(); -- -- if( UInt::operator>( mmax ) ) -- return 1; -- } -- -- return 0; -- } -- -- --public: -- -- /*! -- this method converts a string into its value -- it returns carry=1 if the value will be too big or an incorrect base 'b' is given -- -- string is ended with a non-digit value, for example: -- "-12" will be translated to -12 -- as well as: -- "- 12foo" will be translated to -12 too -- -- existing first white characters will be ommited -- (between '-' and a first digit can be white characters too) -- -- after_source (if exists) is pointing at the end of the parsed string -- -- value_read (if exists) tells whether something has actually been read (at least one digit) -- */ -- uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0) -- { -- return FromStringBase(s, b, after_source, value_read); -- } -- -- -- /*! -- this method converts a string into its value -- */ -- uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0) -- { -- return FromStringBase(s, b, after_source, value_read); -- } -- -- -- /*! -- this method converts a string into its value -- it returns carry=1 if the value will be too big or an incorrect base 'b' is given -- */ -- uint FromString(const std::string & s, uint b = 10) -- { -- return FromString( s.c_str(), b ); -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- Int & operator=(const char * s) -- { -- FromString(s); -- -- return *this; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- -- /*! -- this method converts a string into its value -- it returns carry=1 if the value will be too big or an incorrect base 'b' is given -- */ -- uint FromString(const std::wstring & s, uint b = 10) -- { -- return FromString( s.c_str(), b ); -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- Int & operator=(const wchar_t * s) -- { -- FromString(s); -- -- return *this; -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- Int & operator=(const std::wstring & s) -- { -- FromString( s.c_str() ); -- -- return *this; -- } -- --#endif -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- Int & operator=(const std::string & s) -- { -- FromString( s.c_str() ); -- -- return *this; -- } -- -- -- -- /*! -- * -- * methods for comparing -- * -- * -- */ -- -- bool operator==(const Int & l) const -- { -- return UInt::operator==(l); -- } -- -- bool operator!=(const Int & l) const -- { -- return UInt::operator!=(l); -- } -- -- bool operator<(const Int & l) const -- { -- sint i=value_size-1; -- -- sint a1 = sint(UInt::table[i]); -- sint a2 = sint(l.table[i]); -- -- if( a1 != a2 ) -- return a1 < a2; -- -- -- for(--i ; i>=0 ; --i) -- { -- if( UInt::table[i] != l.table[i] ) -- // comparison as unsigned int -- return UInt::table[i] < l.table[i]; -- } -- -- // they're equal -- return false; -- } -- -- -- bool operator>(const Int & l) const -- { -- sint i=value_size-1; -- -- sint a1 = sint(UInt::table[i]); -- sint a2 = sint(l.table[i]); -- -- if( a1 != a2 ) -- return a1 > a2; -- -- -- for(--i ; i>=0 ; --i) -- { -- if( UInt::table[i] != l.table[i] ) -- // comparison as unsigned int -- return UInt::table[i] > l.table[i]; -- } -- -- // they're equal -- return false; -- } -- -- -- bool operator<=(const Int & l) const -- { -- sint i=value_size-1; -- -- sint a1 = sint(UInt::table[i]); -- sint a2 = sint(l.table[i]); -- -- if( a1 != a2 ) -- return a1 < a2; -- -- -- for(--i ; i>=0 ; --i) -- { -- if( UInt::table[i] != l.table[i] ) -- // comparison as unsigned int -- return UInt::table[i] < l.table[i]; -- } -- -- // they're equal -- return true; -- } -- -- -- bool operator>=(const Int & l) const -- { -- sint i=value_size-1; -- -- sint a1 = sint(UInt::table[i]); -- sint a2 = sint(l.table[i]); -- -- if( a1 != a2 ) -- return a1 > a2; -- -- -- for(--i ; i>=0 ; --i) -- { -- if( UInt::table[i] != l.table[i] ) -- // comparison as unsigned int -- return UInt::table[i] > l.table[i]; -- } -- -- // they're equal -- return true; -- } -- -- -- -- /*! -- * -- * standard mathematical operators -- * -- */ -- -- -- /*! -- an operator for changing the sign -- -- it's not changing 'this' but the changed value will be returned -- */ -- Int operator-() const -- { -- Int temp(*this); -- -- temp.ChangeSign(); -- -- return temp; -- } -- -- -- Int operator-(const Int & p2) const -- { -- Int temp(*this); -- -- temp.Sub(p2); -- -- return temp; -- } -- -- -- Int & operator-=(const Int & p2) -- { -- Sub(p2); -- -- return *this; -- } -- -- -- Int operator+(const Int & p2) const -- { -- Int temp(*this); -- -- temp.Add(p2); -- -- return temp; -- } -- -- -- Int & operator+=(const Int & p2) -- { -- Add(p2); -- -- return *this; -- } -- -- -- Int operator*(const Int & p2) const -- { -- Int temp(*this); -- -- temp.Mul(p2); -- -- return temp; -- } -- -- -- Int & operator*=(const Int & p2) -- { -- Mul(p2); -- -- return *this; -- } -- -- -- Int operator/(const Int & p2) const -- { -- Int temp(*this); -- -- temp.Div(p2); -- -- return temp; -- } -- -- -- Int & operator/=(const Int & p2) -- { -- Div(p2); -- -- return *this; -- } -- -- -- Int operator%(const Int & p2) const -- { -- Int temp(*this); -- Int remainder; -- -- temp.Div(p2, remainder); -- -- return remainder; -- } -- -- -- Int & operator%=(const Int & p2) -- { -- Int remainder; -- -- Div(p2, remainder); -- operator=(remainder); -- -- return *this; -- } -- -- -- /*! -- Prefix operator e.g. ++variable -- */ -- UInt & operator++() -- { -- AddOne(); -- -- return *this; -- } -- -- -- /*! -- Postfix operator e.g. variable++ -- */ -- UInt operator++(int) -- { -- UInt temp( *this ); -- -- AddOne(); -- -- return temp; -- } -- -- -- UInt & operator--() -- { -- SubOne(); -- -- return *this; -- } -- -- -- UInt operator--(int) -- { -- UInt temp( *this ); -- -- SubOne(); -- -- return temp; -- } -- -- -- -- /*! -- * -- * input/output operators for standard streams -- * -- */ -- --private: -- -- /*! -- an auxiliary method for outputing to standard streams -- */ -- template -- static ostream_type & OutputToStream(ostream_type & s, const Int & l) -- { -- string_type ss; -- -- l.ToString(ss); -- s << ss; -- -- return s; -- } -- -- -- --public: -- -- -- /*! -- output to standard streams -- */ -- friend std::ostream & operator<<(std::ostream & s, const Int & l) -- { -- return OutputToStream(s, l); -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- output to standard streams -- */ -- friend std::wostream & operator<<(std::wostream & s, const Int & l) -- { -- return OutputToStream(s, l); -- } -- --#endif -- -- -- --private: -- -- /*! -- an auxiliary method for converting from a string -- */ -- template -- static istream_type & InputFromStream(istream_type & s, Int & l) -- { -- string_type ss; -- -- // char or wchar_t for operator>> -- char_type z; -- -- // operator>> omits white characters if they're set for ommiting -- s >> z; -- -- if( z=='-' || z=='+' ) -- { -- ss += z; -- s >> z; // we're reading a next character (white characters can be ommited) -- } -- -- // we're reading only digits (base=10) -- while( s.good() && Misc::CharToDigit(z, 10)>=0 ) -- { -- ss += z; -- z = static_cast(s.get()); -- } -- -- // we're leaving the last readed character -- // (it's not belonging to the value) -- s.unget(); -- -- l.FromString(ss); -- -- return s; -- } -- -- --public: -- -- /*! -- input from standard streams -- */ -- friend std::istream & operator>>(std::istream & s, Int & l) -- { -- return InputFromStream(s, l); -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- input from standard streams -- */ -- friend std::wistream & operator>>(std::wistream & s, Int & l) -- { -- return InputFromStream(s, l); -- } --#endif -- -- --}; -- --} // namespace -- --#endif -diff --git a/extern/ttmath/ttmathmisc.h b/extern/ttmath/ttmathmisc.h -deleted file mode 100644 -index 330a43a468..0000000000 ---- a/extern/ttmath/ttmathmisc.h -+++ /dev/null -@@ -1,250 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2010, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#ifndef headerfilettmathmisc --#define headerfilettmathmisc -- -- --/*! -- \file ttmathmisc.h -- \brief some helpful functions --*/ -- -- --#include -- -- --namespace ttmath --{ -- --/*! -- some helpful functions --*/ --class Misc --{ --public: -- -- --/* -- * -- * AssignString(result, str) -- * result = str -- * -- */ -- --/*! -- result = str --*/ --static void AssignString(std::string & result, const char * str) --{ -- result = str; --} -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- --/*! -- result = str --*/ --static void AssignString(std::wstring & result, const char * str) --{ -- result.clear(); -- -- for( ; *str ; ++str ) -- result += *str; --} -- -- --/*! -- result = str --*/ --static void AssignString(std::wstring & result, const std::string & str) --{ -- return AssignString(result, str.c_str()); --} -- -- --/*! -- result = str --*/ --static void AssignString(std::string & result, const wchar_t * str) --{ -- result.clear(); -- -- for( ; *str ; ++str ) -- result += static_cast(*str); --} -- -- --/*! -- result = str --*/ --static void AssignString(std::string & result, const std::wstring & str) --{ -- return AssignString(result, str.c_str()); --} -- --#endif -- -- --/* -- * -- * AddString(result, str) -- * result += str -- * -- */ -- -- --/*! -- result += str --*/ --static void AddString(std::string & result, const char * str) --{ -- result += str; --} -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- --/*! -- result += str --*/ --static void AddString(std::wstring & result, const char * str) --{ -- for( ; *str ; ++str ) -- result += *str; --} -- --#endif -- -- --/* -- this method omits any white characters from the string -- char_type is char or wchar_t --*/ --template --static void SkipWhiteCharacters(const char_type * & c) --{ -- // 13 is at the end in a DOS text file (\r\n) -- while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') ) -- ++c; --} -- -- -- -- --/*! -- this static method converts one character into its value -- -- for example: -- 1 -> 1 -- 8 -> 8 -- A -> 10 -- f -> 15 -- -- this method don't check whether c is correct or not --*/ --static uint CharToDigit(uint c) --{ -- if(c>='0' && c<='9') -- return c-'0'; -- -- if(c>='a' && c<='z') -- return c-'a'+10; -- --return c-'A'+10; --} -- -- --/*! -- this method changes a character 'c' into its value -- (if there can't be a correct value it returns -1) -- -- for example: -- c=2, base=10 -> function returns 2 -- c=A, base=10 -> function returns -1 -- c=A, base=16 -> function returns 10 --*/ --static sint CharToDigit(uint c, uint base) --{ -- if( c>='0' && c<='9' ) -- c=c-'0'; -- else -- if( c>='a' && c<='z' ) -- c=c-'a'+10; -- else -- if( c>='A' && c<='Z' ) -- c=c-'A'+10; -- else -- return -1; -- -- -- if( c >= base ) -- return -1; -- -- --return sint(c); --} -- -- -- --/*! -- this method converts a digit into a char -- digit should be from <0,F> -- (we don't have to get a base) -- -- for example: -- 1 -> 1 -- 8 -> 8 -- 10 -> A -- 15 -> F --*/ --static uint DigitToChar(uint digit) --{ -- if( digit < 10 ) -- return digit + '0'; -- --return digit - 10 + 'A'; --} -- -- --}; // struct Misc -- --} -- -- --#endif -diff --git a/extern/ttmath/ttmathobjects.h b/extern/ttmath/ttmathobjects.h -deleted file mode 100644 -index c35026bbd0..0000000000 ---- a/extern/ttmath/ttmathobjects.h -+++ /dev/null -@@ -1,809 +0,0 @@ --/* -- * This file is a part of TTMath Mathematical Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2010, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- --#ifndef headerfilettmathobject --#define headerfilettmathobject -- --/*! -- \file ttmathobjects.h -- \brief Mathematic functions. --*/ -- --#include --#include --#include --#include -- --#include "ttmathtypes.h" --#include "ttmathmisc.h" -- -- --namespace ttmath --{ -- --/*! -- objects of this class are used with the mathematical parser -- they hold variables or functions defined by a user -- -- each object has its own table in which we're keeping variables or functions --*/ --class Objects --{ --public: -- -- -- /*! -- one item (variable or function) -- 'items' will be on the table -- */ -- struct Item -- { -- // name of a variable of a function -- // internally we store variables and funcions as std::string (not std::wstring even when wide characters are used) -- std::string value; -- -- // number of parameters required by the function -- // (if there's a variable this 'param' is ignored) -- int param; -- -- Item() {} -- Item(const std::string & v, int p) : value(v), param(p) {} -- }; -- -- // 'Table' is the type of our table -- typedef std::map Table; -- typedef Table::iterator Iterator; -- typedef Table::const_iterator CIterator; -- -- -- -- /*! -- this method returns true if a character 'c' is a character -- which can be in a name -- -- if 'can_be_digit' is true that means when the 'c' is a digit this -- method returns true otherwise it returns false -- */ -- static bool CorrectCharacter(int c, bool can_be_digit) -- { -- if( (c>='a' && c<='z') || (c>='A' && c<='Z') ) -- return true; -- -- if( can_be_digit && ((c>='0' && c<='9') || c=='_') ) -- return true; -- -- return false; -- } -- -- -- /*! -- this method returns true if the name can be as a name of an object -- */ -- template -- static bool IsNameCorrect(const string_type & name) -- { -- if( name.empty() ) -- return false; -- -- if( !CorrectCharacter(name[0], false) ) -- return false; -- -- typename string_type::const_iterator i = name.begin(); -- -- for(++i ; i!=name.end() ; ++i) -- if( !CorrectCharacter(*i, true) ) -- return false; -- -- return true; -- } -- -- -- /*! -- this method returns true if such an object is defined (name exists) -- */ -- bool IsDefined(const std::string & name) -- { -- Iterator i = table.find(name); -- -- if( i != table.end() ) -- // we have this object in our table -- return true; -- -- return false; -- } -- -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method returns true if such an object is defined (name exists) -- */ -- bool IsDefined(const std::wstring & name) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return false; -- -- Misc::AssignString(str_tmp1, name); -- -- return IsDefined(str_tmp1); -- } -- --#endif -- -- -- /*! -- this method adds one object (variable of function) into the table -- */ -- ErrorCode Add(const std::string & name, const std::string & value, int param = 0) -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Iterator i = table.find(name); -- -- if( i != table.end() ) -- // we have this object in our table -- return err_object_exists; -- -- table.insert( std::make_pair(name, Item(value, param)) ); -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method adds one object (variable of function) into the table -- */ -- ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- Misc::AssignString(str_tmp2, value); -- -- return Add(str_tmp1, str_tmp2, param); -- } -- --#endif -- -- -- /*! -- this method returns 'true' if the table is empty -- */ -- bool Empty() const -- { -- return table.empty(); -- } -- -- -- /*! -- this method clears the table -- */ -- void Clear() -- { -- return table.clear(); -- } -- -- -- /*! -- this method returns 'const_iterator' on the first item on the table -- */ -- CIterator Begin() const -- { -- return table.begin(); -- } -- -- -- /*! -- this method returns 'const_iterator' pointing at the space after last item -- (returns table.end()) -- */ -- CIterator End() const -- { -- return table.end(); -- } -- -- -- /*! -- this method changes the value and the number of parameters for a specific object -- */ -- ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0) -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Iterator i = table.find(name); -- -- if( i == table.end() ) -- return err_unknown_object; -- -- i->second.value = value; -- i->second.param = param; -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- -- /*! -- this method changes the value and the number of parameters for a specific object -- */ -- ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- Misc::AssignString(str_tmp2, value); -- -- return EditValue(str_tmp1, str_tmp2, param); -- } -- --#endif -- -- -- /*! -- this method changes the name of a specific object -- */ -- ErrorCode EditName(const std::string & old_name, const std::string & new_name) -- { -- if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) ) -- return err_incorrect_name; -- -- Iterator old_i = table.find(old_name); -- if( old_i == table.end() ) -- return err_unknown_object; -- -- if( old_name == new_name ) -- // the new name is the same as the old one -- // we treat it as a normal situation -- return err_ok; -- -- ErrorCode err = Add(new_name, old_i->second.value, old_i->second.param); -- -- if( err == err_ok ) -- { -- old_i = table.find(old_name); -- TTMATH_ASSERT( old_i != table.end() ) -- -- table.erase(old_i); -- } -- -- return err; -- } -- -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- -- /*! -- this method changes the name of a specific object -- */ -- ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, old_name); -- Misc::AssignString(str_tmp2, new_name); -- -- return EditName(str_tmp1, str_tmp2); -- } -- --#endif -- -- -- /*! -- this method deletes an object -- */ -- ErrorCode Delete(const std::string & name) -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Iterator i = table.find(name); -- -- if( i == table.end() ) -- return err_unknown_object; -- -- table.erase( i ); -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- -- /*! -- this method deletes an object -- */ -- ErrorCode Delete(const std::wstring & name) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- -- return Delete(str_tmp1); -- } -- --#endif -- -- -- /*! -- this method gets the value of a specific object -- */ -- ErrorCode GetValue(const std::string & name, std::string & value) const -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- CIterator i = table.find(name); -- -- if( i == table.end() ) -- { -- value.clear(); -- return err_unknown_object; -- } -- -- value = i->second.value; -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method gets the value of a specific object -- */ -- ErrorCode GetValue(const std::wstring & name, std::wstring & value) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- ErrorCode err = GetValue(str_tmp1, str_tmp2); -- Misc::AssignString(value, str_tmp2); -- -- return err; -- } -- --#endif -- -- -- /*! -- this method gets the value of a specific object -- (this version is used for not copying the whole string) -- */ -- ErrorCode GetValue(const std::string & name, const char ** value) const -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- CIterator i = table.find(name); -- -- if( i == table.end() ) -- { -- *value = 0; -- return err_unknown_object; -- } -- -- *value = i->second.value.c_str(); -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method gets the value of a specific object -- (this version is used for not copying the whole string) -- */ -- ErrorCode GetValue(const std::wstring & name, const char ** value) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- -- return GetValue(str_tmp1, value); -- } -- --#endif -- -- -- /*! -- this method gets the value and the number of parameters -- of a specific object -- */ -- ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- CIterator i = table.find(name); -- -- if( i == table.end() ) -- { -- value.empty(); -- *param = 0; -- return err_unknown_object; -- } -- -- value = i->second.value; -- *param = i->second.param; -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method gets the value and the number of parameters -- of a specific object -- */ -- ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param); -- Misc::AssignString(value, str_tmp2); -- -- return err; -- } -- --#endif -- -- -- /*! -- this method sets the value and the number of parameters -- of a specific object -- (this version is used for not copying the whole string) -- */ -- ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const -- { -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- CIterator i = table.find(name); -- -- if( i == table.end() ) -- { -- *value = 0; -- *param = 0; -- return err_unknown_object; -- } -- -- *value = i->second.value.c_str(); -- *param = i->second.param; -- -- return err_ok; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- -- /*! -- this method sets the value and the number of parameters -- of a specific object -- (this version is used for not copying the whole string -- but in fact we make one copying during AssignString()) -- */ -- ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param) -- { -- // we should check whether the name (in wide characters) are correct -- // before calling AssignString() function -- if( !IsNameCorrect(name) ) -- return err_incorrect_name; -- -- Misc::AssignString(str_tmp1, name); -- -- return GetValueAndParam(str_tmp1, value, param); -- } -- -- --#endif -- -- -- /*! -- this method returns a pointer into the table -- */ -- Table * GetTable() -- { -- return &table; -- } -- -- --private: -- -- Table table; -- std::string str_tmp1, str_tmp2; -- --}; // end of class Objects -- -- -- -- -- -- -- --/*! -- objects of the class History are used to keep values in functions -- which take a lot of time during calculating, for instance in the -- function Factorial(x) -- -- it means that when we're calculating e.g. Factorial(1000) and the -- Factorial finds that we have calculated it before, the value (result) -- is taken from the history --*/ --template --class History --{ -- /*! -- one item in the History's object holds a key, a value for the key -- and a corresponding error code -- */ -- struct Item -- { -- ValueType key, value; -- ErrorCode err; -- }; -- -- -- /*! -- we use std::list for simply deleting the first item -- but because we're searching through the whole container -- (in the method Get) the container should not be too big -- (linear time of searching) -- */ -- typedef std::list buffer_type; -- buffer_type buffer; -- typename buffer_type::size_type buffer_max_size; -- --public: -- -- /*! -- default constructor -- default max size of the History's container is 15 items -- */ -- History() -- { -- buffer_max_size = 15; -- } -- -- -- /*! -- a constructor which takes another value of the max size -- of the History's container -- */ -- History(typename buffer_type::size_type new_size) -- { -- buffer_max_size = new_size; -- } -- -- -- /*! -- this method adds one item into the History -- if the size of the container is greater than buffer_max_size -- the first item will be removed -- */ -- void Add(const ValueType & key, const ValueType & value, ErrorCode err) -- { -- Item item; -- item.key = key; -- item.value = value; -- item.err = err; -- -- buffer.insert( buffer.end(), item ); -- -- if( buffer.size() > buffer_max_size ) -- buffer.erase(buffer.begin()); -- } -- -- -- /*! -- this method checks whether we have an item which has the key equal 'key' -- -- if there's such item the method sets the 'value' and the 'err' -- and returns true otherwise it returns false and 'value' and 'err' -- remain unchanged -- */ -- bool Get(const ValueType & key, ValueType & value, ErrorCode & err) -- { -- typename buffer_type::iterator i = buffer.begin(); -- -- for( ; i != buffer.end() ; ++i ) -- { -- if( i->key == key ) -- { -- value = i->value; -- err = i->err; -- return true; -- } -- } -- -- return false; -- } -- -- -- /*! -- this methods deletes an item -- -- we assume that there is only one item with the 'key' -- (this methods removes the first one) -- */ -- bool Remove(const ValueType & key) -- { -- typename buffer_type::iterator i = buffer.begin(); -- -- for( ; i != buffer.end() ; ++i ) -- { -- if( i->key == key ) -- { -- buffer.erase(i); -- return true; -- } -- } -- -- return false; -- } -- -- --}; // end of class History -- -- -- --/*! -- this is an auxiliary class used when calculating Gamma() or Factorial() -- -- in multithreaded environment you can provide an object of this class to -- the Gamma() or Factorial() function, e.g; -- typedef Big<1, 3> MyBig; -- MyBig x = 123456; -- CGamma cgamma; -- std::cout << Gamma(x, cgamma); -- each thread should have its own CGamma<> object -- -- in a single-thread environment a CGamma<> object is a static variable -- in a second version of Gamma() and you don't have to explicitly use it, e.g. -- typedef Big<1, 3> MyBig; -- MyBig x = 123456; -- std::cout << Gamma(x); --*/ --template --struct CGamma --{ -- /*! -- this table holds factorials -- 1 -- 1 -- 2 -- 6 -- 24 -- 120 -- 720 -- ....... -- */ -- std::vector fact; -- -- -- /*! -- this table holds Bernoulli numbers -- 1 -- -0.5 -- 0.166666666666666666666666667 -- 0 -- -0.0333333333333333333333333333 -- 0 -- 0.0238095238095238095238095238 -- 0 -- -0.0333333333333333333333333333 -- 0 -- 0.075757575757575757575757576 -- ..... -- */ -- std::vector bern; -- -- -- /*! -- here we store some calculated values -- (this is for speeding up, if the next argument of Gamma() or Factorial() -- is in the 'history' then the result we are not calculating but simply -- return from the 'history' object) -- */ -- History history; -- -- -- /*! -- this method prepares some coefficients: factorials and Bernoulli numbers -- stored in 'fact' and 'bern' objects -- -- how many values should be depends on the size of the mantissa - if -- the mantissa is larger then we must calculate more values -- for a mantissa which consists of 256 bits (8 words on a 32bit platform) -- we have to calculate about 30 values (the size of fact and bern will be 30), -- and for a 2048 bits mantissa we have to calculate 306 coefficients -- -- you don't have to call this method, these coefficients will be automatically calculated -- when they are needed -- -- you must note that calculating these coefficients is a little time-consuming operation, -- (especially when the mantissa is large) and first call to Gamma() or Factorial() -- can take more time than next calls, and in the end this is the point when InitAll() -- comes in handy: you can call this method somewhere at the beginning of your program -- */ -- void InitAll(); -- // definition is in ttmath.h --}; -- -- -- -- --} // namespace -- --#endif -diff --git a/extern/ttmath/ttmaththreads.h b/extern/ttmath/ttmaththreads.h -deleted file mode 100644 -index 586227f2fc..0000000000 ---- a/extern/ttmath/ttmaththreads.h -+++ /dev/null -@@ -1,250 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2009, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- -- --#ifndef headerfilettmaththreads --#define headerfilettmaththreads -- --#include "ttmathtypes.h" -- --#ifdef TTMATH_WIN32_THREADS --#include --#include --#endif -- --#ifdef TTMATH_POSIX_THREADS --#include --#endif -- -- -- --/*! -- \file ttmaththreads.h -- \brief Some objects used in multithreads environment --*/ -- -- --/* -- this is a simple skeleton of a program in multithreads environment: -- -- #define TTMATH_MULTITHREADS -- #include -- -- TTMATH_MULTITHREADS_HELPER -- -- int main() -- { -- [...] -- } -- -- make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file) -- use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope) --*/ -- -- --namespace ttmath --{ -- -- --#ifdef TTMATH_WIN32_THREADS -- -- /* -- we use win32 threads -- */ -- -- -- /*! -- in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro -- somewhere in *.cpp file -- -- (at the moment in win32 this macro does nothing) -- */ -- #define TTMATH_MULTITHREADS_HELPER -- -- -- /*! -- objects of this class are used to synchronize -- */ -- class ThreadLock -- { -- HANDLE mutex_handle; -- -- -- void CreateName(char * buffer) const -- { -- #ifdef _MSC_VER -- #pragma warning (disable : 4996) -- // warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. -- #endif -- -- sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId()); -- -- #ifdef _MSC_VER -- #pragma warning (default : 4996) -- #endif -- } -- -- -- public: -- -- bool Lock() -- { -- char buffer[50]; -- -- CreateName(buffer); -- mutex_handle = CreateMutexA(0, false, buffer); -- -- if( mutex_handle == 0 ) -- return false; -- -- WaitForSingleObject(mutex_handle, INFINITE); -- -- return true; -- } -- -- -- ThreadLock() -- { -- mutex_handle = 0; -- } -- -- -- ~ThreadLock() -- { -- if( mutex_handle != 0 ) -- { -- ReleaseMutex(mutex_handle); -- CloseHandle(mutex_handle); -- } -- } -- }; -- --#endif // #ifdef TTMATH_WIN32_THREADS -- -- -- -- -- --#ifdef TTMATH_POSIX_THREADS -- -- /* -- we use posix threads -- */ -- -- -- /*! -- in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro -- somewhere in *.cpp file -- (this macro defines a pthread_mutex_t object used by TTMath library) -- */ -- #define TTMATH_MULTITHREADS_HELPER \ -- namespace ttmath \ -- { \ -- pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \ -- } -- -- -- /*! -- ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro -- */ -- extern pthread_mutex_t ttmath_mutex; -- -- -- /*! -- objects of this class are used to synchronize -- */ -- class ThreadLock -- { -- public: -- -- bool Lock() -- { -- if( pthread_mutex_lock(&ttmath_mutex) != 0 ) -- return false; -- -- return true; -- } -- -- -- ~ThreadLock() -- { -- pthread_mutex_unlock(&ttmath_mutex); -- } -- }; -- --#endif // #ifdef TTMATH_POSIX_THREADS -- -- -- -- --#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS) -- -- /*! -- we don't use win32 and pthreads -- */ -- -- /*! -- */ -- #define TTMATH_MULTITHREADS_HELPER -- -- -- /*! -- objects of this class are used to synchronize -- actually we don't synchronize, the method Lock() returns always 'false' -- */ -- class ThreadLock -- { -- public: -- -- bool Lock() -- { -- return false; -- } -- }; -- -- --#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS) -- -- -- -- -- --} // namespace -- --#endif -- -diff --git a/extern/ttmath/ttmathtypes.h b/extern/ttmath/ttmathtypes.h -deleted file mode 100644 -index 3d9ddbe7b0..0000000000 ---- a/extern/ttmath/ttmathtypes.h -+++ /dev/null -@@ -1,676 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2012, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- --#ifndef headerfilettmathtypes --#define headerfilettmathtypes -- --/*! -- \file ttmathtypes.h -- \brief constants used in the library -- -- As our library is written in header files (templates) we cannot use -- constants like 'const int' etc. because we should have some source files -- *.cpp to define this variables. Only what we can have are constants -- defined by #define preprocessor macros. -- -- All macros are preceded by TTMATH_ prefix --*/ -- -- --#include --#include --#include -- --#ifndef _MSC_VER --#include --// for uint64_t and int64_t on a 32 bit platform --#endif -- -- -- --/*! -- the version of the library -- -- TTMATH_PRERELEASE_VER is either zero or one -- zero means that this is the release version of the library -- (one means something like beta) --*/ --#define TTMATH_MAJOR_VER 0 --#define TTMATH_MINOR_VER 9 --#define TTMATH_REVISION_VER 3 -- --#define TTMATH_PRERELEASE_VER 0 -- -- -- --/*! -- you can define a platform explicitly by defining either -- TTMATH_PLATFORM32 or TTMATH_PLATFORM64 macro --*/ --#if !defined TTMATH_PLATFORM32 && !defined TTMATH_PLATFORM64 -- -- #if !defined _M_X64 && !defined __x86_64__ -- -- /* -- other platforms than x86 and amd64 are not recognized at the moment -- so you should set TTMATH_PLATFORMxx manually -- */ -- -- // we're using a 32bit platform -- #define TTMATH_PLATFORM32 -- -- #else -- -- // we're using a 64bit platform -- #define TTMATH_PLATFORM64 -- -- #endif -- --#endif -- -- --/*! -- asm version of the library is available by default only for: -- x86 and amd64 platforms and for Microsoft Visual and GCC compilers -- -- but you can force using asm version (the same asm as for Microsoft Visual) -- by defining TTMATH_FORCEASM macro -- you have to be sure that your compiler accept such an asm format --*/ --#ifndef TTMATH_FORCEASM -- -- #if !defined __i386__ && !defined _X86_ && !defined _M_IX86 && !defined __x86_64__ && !defined _M_X64 -- /*! -- x86 architecture: -- __i386__ defined by GNU C -- _X86_ defined by MinGW32 -- _M_IX86 defined by Visual Studio, Intel C/C++, Digital Mars and Watcom C/C++ -- -- amd64 architecture: -- __x86_64__ defined by GNU C, CLANG (LLVM) and Sun Studio -- _M_X64 defined by Visual Studio -- -- asm version is available only for x86 or amd64 platforms -- */ -- #define TTMATH_NOASM -- #endif -- -- -- -- #if !defined _MSC_VER && !defined __GNUC__ -- /*! -- another compilers than MS VC or GCC or CLANG (LLVM) by default use no asm version -- (CLANG defines __GNUC__ too) -- */ -- #define TTMATH_NOASM -- #endif -- --#endif -- -- --namespace ttmath --{ -- -- --#ifdef TTMATH_PLATFORM32 -- -- /*! -- on 32bit platforms one word (uint, sint) will be equal 32bits -- */ -- typedef unsigned int uint; -- typedef signed int sint; -- -- /*! -- on 32 bit platform ulint and slint will be equal 64 bits -- */ -- #ifdef _MSC_VER -- // long long on MS Windows (Visual and GCC mingw compilers) have 64 bits -- // stdint.h is not available on Visual Studio prior to VS 2010 version -- typedef unsigned long long int ulint; -- typedef signed long long int slint; -- #else -- // we do not use 'long' here because there is a difference in unix and windows -- // environments: in unix 'long' has 64 bits but in windows it has only 32 bits -- typedef uint64_t ulint; -- typedef int64_t slint; -- #endif -- -- /*! -- how many bits there are in the uint type -- */ -- #define TTMATH_BITS_PER_UINT 32u -- -- /*! -- the mask for the highest bit in the unsigned 32bit word (2^31) -- */ -- #define TTMATH_UINT_HIGHEST_BIT 2147483648u -- -- /*! -- the max value of the unsigned 32bit word (2^32 - 1) -- (all bits equal one) -- */ -- #define TTMATH_UINT_MAX_VALUE 4294967295u -- -- /*! -- the number of words (32bit words on 32bit platform) -- which are kept in built-in variables for a Big<> type -- (these variables are defined in ttmathbig.h) -- */ -- #define TTMATH_BUILTIN_VARIABLES_SIZE 256u -- -- /*! -- this macro returns the number of machine words -- capable to hold min_bits bits -- e.g. TTMATH_BITS(128) returns 4 -- */ -- #define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1) -- --#else -- -- /*! -- on 64bit platforms one word (uint, sint) will be equal 64bits -- */ -- #ifdef _MSC_VER -- /* in VC 'long' type has 32 bits, __int64 is VC extension */ -- typedef unsigned __int64 uint; -- typedef signed __int64 sint; -- #else -- typedef unsigned long uint; -- typedef signed long sint; -- #endif -- -- /*! -- on 64bit platforms we do not define ulint and slint -- */ -- -- /*! -- how many bits there are in the uint type -- */ -- #define TTMATH_BITS_PER_UINT 64ul -- -- /*! -- the mask for the highest bit in the unsigned 64bit word (2^63) -- */ -- #define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul -- -- /*! -- the max value of the unsigned 64bit word (2^64 - 1) -- (all bits equal one) -- */ -- #define TTMATH_UINT_MAX_VALUE 18446744073709551615ul -- -- /*! -- the number of words (64bit words on 64bit platforms) -- which are kept in built-in variables for a Big<> type -- (these variables are defined in ttmathbig.h) -- */ -- #define TTMATH_BUILTIN_VARIABLES_SIZE 128ul -- -- /*! -- this macro returns the number of machine words -- capable to hold min_bits bits -- e.g. TTMATH_BITS(128) returns 2 -- */ -- #define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1) -- --#endif --} -- -- --#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC) -- #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS) -- -- #if defined(_WIN32) -- #define TTMATH_WIN32_THREADS -- #elif defined(unix) || defined(__unix__) || defined(__unix) -- #define TTMATH_POSIX_THREADS -- #endif -- -- #endif --#endif -- -- -- --/*! -- this variable defines how many iterations are performed -- during some kind of calculating when we're making any long formulas -- (for example Taylor series) -- -- it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc. -- -- note! there'll not be so many iterations, iterations are stopped when -- there is no sense to continue calculating (for example when the result -- still remains unchanged after adding next series and we know that the next -- series are smaller than previous ones) --*/ --#define TTMATH_ARITHMETIC_MAX_LOOP 10000 -- -- -- --/*! -- this is a limit when calculating Karatsuba multiplication -- if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE -- the Karatsuba algorithm will use standard schoolbook multiplication --*/ --#ifdef TTMATH_DEBUG_LOG -- // if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler -- #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3 --#else -- #ifdef __GNUC__ -- #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3 -- #else -- #define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5 -- #endif --#endif -- -- --/*! -- this is a special value used when calculating the Gamma(x) function -- if x is greater than this value then the Gamma(x) will be calculated using -- some kind of series -- -- don't use smaller values than about 100 --*/ --#define TTMATH_GAMMA_BOUNDARY 2000 -- -- -- -- -- --namespace ttmath --{ -- -- /*! -- lib type codes: -- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) -- asm_gcc_32 - with asm code designed for GCC (32 bits) -- asm_vc_64 - with asm for VC (64 bit) -- asm_gcc_64 - with asm for GCC (64 bit) -- no_asm_32 - pure C++ version (32 bit) - without any asm code -- no_asm_64 - pure C++ version (64 bit) - without any asm code -- */ -- enum LibTypeCode -- { -- asm_vc_32 = 0, -- asm_gcc_32, -- asm_vc_64, -- asm_gcc_64, -- no_asm_32, -- no_asm_64 -- }; -- -- -- /*! -- error codes -- */ -- enum ErrorCode -- { -- err_ok = 0, -- err_nothing_has_read, -- err_unknown_character, -- err_unexpected_final_bracket, -- err_stack_not_clear, -- err_unknown_variable, -- err_division_by_zero, -- err_interrupt, -- err_overflow, -- err_unknown_function, -- err_unknown_operator, -- err_unexpected_semicolon_operator, -- err_improper_amount_of_arguments, -- err_improper_argument, -- err_unexpected_end, -- err_internal_error, -- err_incorrect_name, -- err_incorrect_value, -- err_variable_exists, -- err_variable_loop, -- err_functions_loop, -- err_must_be_only_one_value, -- err_object_exists, -- err_unknown_object, -- err_still_calculating, -- err_in_short_form_used_function, -- err_percent_from -- }; -- -- -- /*! -- this struct is used when converting to/from a string -- /temporarily only in Big::ToString() and Big::FromString()/ -- */ -- struct Conv -- { -- /*! -- base (radix) on which the value will be shown (or read) -- default: 10 -- */ -- uint base; -- -- -- /*! -- used only in Big::ToString() -- if true the value will be always shown in the scientific mode, e.g: 123e+30 -- default: false -- */ -- bool scient; -- -- -- /*! -- used only in Big::ToString() -- if scient is false then the value will be printed in the scientific mode -- only if the exponent is greater than scien_from -- default: 15 -- */ -- sint scient_from; -- -- -- /*! -- if 'base_round' is true and 'base' is different from 2, 4, 8, or 16 -- and the result value is not an integer then we make an additional rounding -- (after converting the last digit from the result is skipped) -- default: true -- -- e.g. -- Conv c; -- c.base_round = false; -- Big<1, 1> a = "0.1"; // decimal input -- std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999 -- */ -- bool base_round; -- -- -- /*! -- used only in Big::ToString() -- tells how many digits after comma are possible -- default: -1 which means all digits are printed -- -- set it to zero if you want integer value only -- -- for example when the value is: -- 12.345678 and 'round' is 4 -- then the result will be -- 12.3457 (the last digit was rounded) -- */ -- sint round; -- -- -- /*! -- if true that not mattered digits in the mantissa will be cut off -- (zero characters at the end -- after the comma operator) -- e.g. 1234,78000 will be: 1234,78 -- default: true -- */ -- bool trim_zeroes; -- -- -- /*! -- the main comma operator (used when reading and writing) -- default is a dot '.' -- */ -- uint comma; -- -- -- /*! -- additional comma operator (used only when reading) -- if you don't want it just set it to zero -- default is a comma ',' -- -- this allowes you to convert from a value: -- 123.45 as well as from 123,45 -- */ -- uint comma2; -- -- -- /*! -- it sets the character which is used for grouping -- if group=' ' then: 1234,56789 will be printed as: 1 234,567 89 -- -- if you don't want grouping just set it to zero (which is default) -- */ -- uint group; -- -- -- /*! -- how many digits should be grouped (it is used if 'group' is non zero) -- default: 3 -- */ -- uint group_digits; -- -- -- /*! -- */ -- uint group_exp; // not implemented yet -- -- -- -- -- Conv() -- { -- // default values -- base = 10; -- scient = false; -- scient_from = 15; -- base_round = true; -- round = -1; -- trim_zeroes = true; -- comma = '.'; -- comma2 = ','; -- group = 0; -- group_digits = 3; -- group_exp = 0; -- } -- }; -- -- -- -- /*! -- this simple class can be used in multithreading model -- (you can write your own class derived from this one) -- -- for example: in some functions like Factorial() -- /at the moment only Factorial/ you can give a pointer to -- the 'stop object', if the method WasStopSignal() of this -- object returns true that means we should break the calculating -- and return -- */ -- class StopCalculating -- { -- public: -- virtual bool WasStopSignal() const volatile { return false; } -- virtual ~StopCalculating(){} -- }; -- -- -- /*! -- a small class which is useful when compiling with gcc -- -- object of this type holds the name and the line of a file -- in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used -- */ -- class ExceptionInfo -- { -- const char * file; -- int line; -- -- public: -- ExceptionInfo() : file(0), line(0) {} -- ExceptionInfo(const char * f, int l) : file(f), line(l) {} -- -- std::string Where() const -- { -- if( !file ) -- return "unknown"; -- -- std::ostringstream result; -- result << file << ":" << line; -- -- return result.str(); -- } -- }; -- -- -- /*! -- A small class used for reporting 'reference' errors -- -- In the library is used macro TTMATH_REFERENCE_ASSERT which -- can throw an exception of this type -- -- ** from version 0.9.2 this macro is removed from all methods -- in public interface so you don't have to worry about it ** -- -- If you compile with gcc you can get a small benefit -- from using method Where() (it returns std::string) with -- the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT -- was used) -- */ -- class ReferenceError : public std::logic_error, public ExceptionInfo -- { -- public: -- -- ReferenceError() : std::logic_error("reference error") -- { -- } -- -- ReferenceError(const char * f, int l) : -- std::logic_error("reference error"), ExceptionInfo(f,l) -- { -- } -- -- std::string Where() const -- { -- return ExceptionInfo::Where(); -- } -- }; -- -- -- /*! -- a small class used for reporting errors -- -- in the library is used macro TTMATH_ASSERT which -- (if the condition in it is false) throw an exception -- of this type -- -- if you compile with gcc you can get a small benefit -- from using method Where() (it returns std::string) with -- the name and the line of a file where the macro TTMATH_ASSERT -- was used) -- */ -- class RuntimeError : public std::runtime_error, public ExceptionInfo -- { -- public: -- -- RuntimeError() : std::runtime_error("internal error") -- { -- } -- -- RuntimeError(const char * f, int l) : -- std::runtime_error("internal error"), ExceptionInfo(f,l) -- { -- } -- -- std::string Where() const -- { -- return ExceptionInfo::Where(); -- } -- }; -- -- -- -- /*! -- TTMATH_DEBUG -- this macro enables further testing during writing your code -- you don't have to define it in a release mode -- -- if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT -- are set as well and these macros can throw an exception if a condition in it -- is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT) -- -- TTMATH_DEBUG is set automatically if DEBUG or _DEBUG are defined -- */ -- #if defined DEBUG || defined _DEBUG -- #define TTMATH_DEBUG -- #endif -- -- -- #ifdef TTMATH_DEBUG -- -- #if defined(__FILE__) && defined(__LINE__) -- -- #define TTMATH_REFERENCE_ASSERT(expression) \ -- if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__); -- -- #define TTMATH_ASSERT(expression) \ -- if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__); -- -- #else -- -- #define TTMATH_REFERENCE_ASSERT(expression) \ -- if( &(expression) == this ) throw ReferenceError(); -- -- #define TTMATH_ASSERT(expression) \ -- if( !(expression) ) throw RuntimeError(); -- #endif -- -- #else -- #define TTMATH_REFERENCE_ASSERT(expression) -- #define TTMATH_ASSERT(expression) -- #endif -- -- -- -- #ifdef TTMATH_DEBUG_LOG -- #define TTMATH_LOG(msg) PrintLog(msg, std::cout); -- #define TTMATH_LOGC(msg, carry) PrintLog(msg, carry, std::cout); -- #define TTMATH_VECTOR_LOG(msg, vector, len) PrintVectorLog(msg, std::cout, vector, len); -- #define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len); -- #else -- #define TTMATH_LOG(msg) -- #define TTMATH_LOGC(msg, carry) -- #define TTMATH_VECTOR_LOG(msg, vector, len) -- #define TTMATH_VECTOR_LOGC(msg, carry, vector, len) -- #endif -- -- -- -- --} // namespace -- -- --#endif -- -diff --git a/extern/ttmath/ttmathuint.h b/extern/ttmath/ttmathuint.h -deleted file mode 100644 -index b9cf67cd11..0000000000 ---- a/extern/ttmath/ttmathuint.h -+++ /dev/null -@@ -1,4126 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2011, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- -- --#ifndef headerfilettmathuint --#define headerfilettmathuint -- -- --/*! -- \file ttmathuint.h -- \brief template class UInt --*/ -- --#include --#include -- -- --#include "ttmathtypes.h" --#include "ttmathmisc.h" -- -- -- --/*! -- \brief a namespace for the TTMath library --*/ --namespace ttmath --{ -- --/*! -- \brief UInt implements a big integer value without a sign -- -- value_size - how many bytes specify our value -- on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits -- on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits -- value_size = 1,2,3,4,5,6.... --*/ --template --class UInt --{ --public: -- -- /*! -- buffer for the integer value -- table[0] - the lowest word of the value -- */ -- uint table[value_size]; -- -- -- -- /*! -- some methods used for debugging purposes -- */ -- -- -- /*! -- this method is used when macro TTMATH_DEBUG_LOG is defined -- */ -- template -- static void PrintVectorLog(const char_type * msg, ostream_type & output, const uint * vector, uint vector_len) -- { -- output << msg << std::endl; -- -- for(uint i=0 ; i -- static void PrintVectorLog(const char_type * msg, uint carry, ostream_type & output, const uint * vector, uint vector_len) -- { -- PrintVectorLog(msg, output, vector, vector_len); -- output << " carry: " << carry << std::endl; -- } -- -- -- /*! -- this method is used when macro TTMATH_DEBUG_LOG is defined -- */ -- template -- void PrintLog(const char_type * msg, ostream_type & output) const -- { -- PrintVectorLog(msg, output, table, value_size); -- } -- -- -- /*! -- this method is used when macro TTMATH_DEBUG_LOG is defined -- */ -- template -- void PrintLog(const char_type * msg, uint carry, ostream_type & output) const -- { -- PrintVectorLog(msg, output, table, value_size); -- output << " carry: " << carry << std::endl; -- } -- -- -- /*! -- this method returns the size of the table -- */ -- uint Size() const -- { -- return value_size; -- } -- -- -- /*! -- this method sets zero -- */ -- void SetZero() -- { -- // in the future here can be 'memset' -- -- for(uint i=0 ; i & ss2) -- { -- for(uint i=0 ; i=0 && temp_table_index=0 ; --i) -- table[i] = 0; -- -- -- TTMATH_LOG("UInt::SetFromTable") -- } -- --#endif -- -- --#ifdef TTMATH_PLATFORM64 -- /*! -- this method copies the value stored in an another table -- (warning: first values in temp_table are the highest words -- it's different -- from our table) -- -- ***this method is created only on a 64bit platform*** -- -- we copy as many words as it is possible -- -- if temp_table_len is bigger than value_size we'll try to round -- the lowest word from table depending on the last not used bit in temp_table -- (this rounding isn't a perfect rounding -- look at the description below) -- -- and if temp_table_len is smaller than value_size we'll clear the rest words -- in the table -- -- warning: we're using 'temp_table' as a pointer at 32bit words -- */ -- void SetFromTable(const unsigned int * temp_table, uint temp_table_len) -- { -- uint temp_table_index = 0; -- sint i; // 'i' with a sign -- -- for(i=value_size-1 ; i>=0 && temp_table_index= 0 ; --i) -- table[i] = 0; -- -- TTMATH_LOG("UInt::SetFromTable") -- } -- --#endif -- -- -- -- -- -- /*! -- * -- * basic mathematic functions -- * -- */ -- -- -- -- -- /*! -- this method adds one to the existing value -- */ -- uint AddOne() -- { -- return AddInt(1); -- } -- -- -- /*! -- this method subtracts one from the existing value -- */ -- uint SubOne() -- { -- return SubInt(1); -- } -- -- --private: -- -- -- /*! -- an auxiliary method for moving bits into the left hand side -- -- this method moves only words -- */ -- void RclMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c) -- { -- rest_bits = bits % TTMATH_BITS_PER_UINT; -- uint all_words = bits / TTMATH_BITS_PER_UINT; -- uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0; -- -- -- if( all_words >= value_size ) -- { -- if( all_words == value_size && rest_bits == 0 ) -- last_c = table[0] & 1; -- // else: last_c is default set to 0 -- -- // clearing -- for(uint i = 0 ; i 0 ) -- { -- // 0 < all_words < value_size -- -- sint first, second; -- last_c = table[value_size - all_words] & 1; // all_words is greater than 0 -- -- // copying the first part of the value -- for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second) -- table[first] = table[second]; -- -- // setting the rest to 'c' -- for( ; first>=0 ; --first ) -- table[first] = mask; -- } -- -- TTMATH_LOG("UInt::RclMoveAllWords") -- } -- --public: -- -- /*! -- moving all bits into the left side 'bits' times -- return value <- this <- C -- -- bits is from a range of <0, man * TTMATH_BITS_PER_UINT> -- or it can be even bigger then all bits will be set to 'c' -- -- the value c will be set into the lowest bits -- and the method returns state of the last moved bit -- */ -- uint Rcl(uint bits, uint c=0) -- { -- uint last_c = 0; -- uint rest_bits = bits; -- -- if( bits == 0 ) -- return 0; -- -- if( bits >= TTMATH_BITS_PER_UINT ) -- RclMoveAllWords(rest_bits, last_c, bits, c); -- -- if( rest_bits == 0 ) -- { -- TTMATH_LOG("UInt::Rcl") -- return last_c; -- } -- -- // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now -- if( rest_bits == 1 ) -- { -- last_c = Rcl2_one(c); -- } -- else if( rest_bits == 2 ) -- { -- // performance tests showed that for rest_bits==2 it's better to use Rcl2_one twice instead of Rcl2(2,c) -- Rcl2_one(c); -- last_c = Rcl2_one(c); -- } -- else -- { -- last_c = Rcl2(rest_bits, c); -- } -- -- TTMATH_LOGC("UInt::Rcl", last_c) -- -- return last_c; -- } -- --private: -- -- /*! -- an auxiliary method for moving bits into the right hand side -- -- this method moves only words -- */ -- void RcrMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c) -- { -- rest_bits = bits % TTMATH_BITS_PER_UINT; -- uint all_words = bits / TTMATH_BITS_PER_UINT; -- uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0; -- -- -- if( all_words >= value_size ) -- { -- if( all_words == value_size && rest_bits == 0 ) -- last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; -- // else: last_c is default set to 0 -- -- // clearing -- for(uint i = 0 ; i 0 ) -- { -- // 0 < all_words < value_size -- -- uint first, second; -- last_c = (table[all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0 -- -- // copying the first part of the value -- for(first=0, second=all_words ; second this -> return value -- -- bits is from a range of <0, man * TTMATH_BITS_PER_UINT> -- or it can be even bigger then all bits will be set to 'c' -- -- the value c will be set into the highest bits -- and the method returns state of the last moved bit -- */ -- uint Rcr(uint bits, uint c=0) -- { -- uint last_c = 0; -- uint rest_bits = bits; -- -- if( bits == 0 ) -- return 0; -- -- if( bits >= TTMATH_BITS_PER_UINT ) -- RcrMoveAllWords(rest_bits, last_c, bits, c); -- -- if( rest_bits == 0 ) -- { -- TTMATH_LOG("UInt::Rcr") -- return last_c; -- } -- -- // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now -- if( rest_bits == 1 ) -- { -- last_c = Rcr2_one(c); -- } -- else if( rest_bits == 2 ) -- { -- // performance tests showed that for rest_bits==2 it's better to use Rcr2_one twice instead of Rcr2(2,c) -- Rcr2_one(c); -- last_c = Rcr2_one(c); -- } -- else -- { -- last_c = Rcr2(rest_bits, c); -- } -- -- TTMATH_LOGC("UInt::Rcr", last_c) -- -- return last_c; -- } -- -- -- /*! -- this method moves all bits into the left side -- (it returns value how many bits have been moved) -- */ -- uint CompensationToLeft() -- { -- uint moving = 0; -- -- // a - index a last word which is different from zero -- sint a; -- for(a=value_size-1 ; a>=0 && table[a]==0 ; --a); -- -- if( a < 0 ) -- return moving; // all words in table have zero -- -- if( a != value_size-1 ) -- { -- moving += ( value_size-1 - a ) * TTMATH_BITS_PER_UINT; -- -- // moving all words -- sint i; -- for(i=value_size-1 ; a>=0 ; --i, --a) -- table[i] = table[a]; -- -- // setting the rest word to zero -- for(; i>=0 ; --i) -- table[i] = 0; -- } -- -- uint moving2 = FindLeadingBitInWord( table[value_size-1] ); -- // moving2 is different from -1 because the value table[value_size-1] -- // is not zero -- -- moving2 = TTMATH_BITS_PER_UINT - moving2 - 1; -- Rcl(moving2); -- -- TTMATH_LOG("UInt::CompensationToLeft") -- -- return moving + moving2; -- } -- -- -- /*! -- this method looks for the highest set bit -- -- result: -- if 'this' is not zero: -- return value - true -- 'table_id' - the index of a word <0..value_size-1> -- 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT) -- -- if 'this' is zero: -- return value - false -- both 'table_id' and 'index' are zero -- */ -- bool FindLeadingBit(uint & table_id, uint & index) const -- { -- for(table_id=value_size-1 ; table_id!=0 && table[table_id]==0 ; --table_id); -- -- if( table_id==0 && table[table_id]==0 ) -- { -- // is zero -- index = 0; -- -- return false; -- } -- -- // table[table_id] is different from 0 -- index = FindLeadingBitInWord( table[table_id] ); -- -- return true; -- } -- -- -- /*! -- this method looks for the smallest set bit -- -- result: -- if 'this' is not zero: -- return value - true -- 'table_id' - the index of a word <0..value_size-1> -- 'index' - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT) -- -- if 'this' is zero: -- return value - false -- both 'table_id' and 'index' are zero -- */ -- bool FindLowestBit(uint & table_id, uint & index) const -- { -- for(table_id=0 ; table_id= value_size ) -- { -- // is zero -- index = 0; -- table_id = 0; -- -- return false; -- } -- -- // table[table_id] is different from 0 -- index = FindLowestBitInWord( table[table_id] ); -- -- return true; -- } -- -- -- /*! -- getting the 'bit_index' bit -- -- bit_index bigger or equal zero -- */ -- uint GetBit(uint bit_index) const -- { -- TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT ) -- -- uint index = bit_index / TTMATH_BITS_PER_UINT; -- uint bit = bit_index % TTMATH_BITS_PER_UINT; -- -- uint temp = table[index]; -- uint res = SetBitInWord(temp, bit); -- -- return res; -- } -- -- -- /*! -- setting the 'bit_index' bit -- and returning the last state of the bit -- -- bit_index bigger or equal zero -- */ -- uint SetBit(uint bit_index) -- { -- TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT ) -- -- uint index = bit_index / TTMATH_BITS_PER_UINT; -- uint bit = bit_index % TTMATH_BITS_PER_UINT; -- uint res = SetBitInWord(table[index], bit); -- -- TTMATH_LOG("UInt::SetBit") -- -- return res; -- } -- -- -- /*! -- this method performs a bitwise operation AND -- */ -- void BitAnd(const UInt & ss2) -- { -- for(uint x=0 ; x & ss2) -- { -- for(uint x=0 ; x & ss2) -- { -- for(uint x=0 ; x -- -- for example: -- BitNot2(8) = BitNot2( 1000(bin) ) = 111(bin) = 7 -- */ -- void BitNot2() -- { -- uint table_id, index; -- -- if( FindLeadingBit(table_id, index) ) -- { -- for(uint x=0 ; x>= shift; -- -- table[table_id] ^= mask; -- } -- else -- table[0] = 1; -- -- -- TTMATH_LOG("UInt::BitNot2") -- } -- -- -- -- /*! -- * -- * Multiplication -- * -- * -- */ -- --public: -- -- /*! -- multiplication: this = this * ss2 -- -- it can return a carry -- */ -- uint MulInt(uint ss2) -- { -- uint r1, r2, x1; -- uint c = 0; -- -- UInt u(*this); -- SetZero(); -- -- if( ss2 == 0 ) -- { -- TTMATH_LOGC("UInt::MulInt(uint)", 0) -- return 0; -- } -- -- for(x1=0 ; x1 -- void MulInt(uint ss2, UInt & result) const -- { -- TTMATH_ASSERT( result_size > value_size ) -- -- uint r2,r1; -- uint x1size=value_size; -- uint x1start=0; -- -- result.SetZero(); -- -- if( ss2 == 0 ) -- { -- TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size) -- return; -- } -- -- if( value_size > 2 ) -- { -- // if the value_size is smaller than or equal to 2 -- // there is no sense to set x1size and x1start to another values -- -- for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size); -- -- if( x1size == 0 ) -- { -- TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size) -- return; -- } -- -- for(x1start=0 ; x1start)", result.table, result_size) -- -- return; -- } -- -- -- -- /*! -- the multiplication 'this' = 'this' * ss2 -- -- algorithm: 100 - means automatically choose the fastest algorithm -- */ -- uint Mul(const UInt & ss2, uint algorithm = 100) -- { -- switch( algorithm ) -- { -- case 1: -- return Mul1(ss2); -- -- case 2: -- return Mul2(ss2); -- -- case 3: -- return Mul3(ss2); -- -- case 100: -- default: -- return MulFastest(ss2); -- } -- } -- -- -- /*! -- the multiplication 'result' = 'this' * ss2 -- -- since the 'result' is twice bigger than 'this' and 'ss2' -- this method never returns a carry -- -- algorithm: 100 - means automatically choose the fastest algorithm -- */ -- void MulBig(const UInt & ss2, -- UInt & result, -- uint algorithm = 100) -- { -- switch( algorithm ) -- { -- case 1: -- return Mul1Big(ss2, result); -- -- case 2: -- return Mul2Big(ss2, result); -- -- case 3: -- return Mul3Big(ss2, result); -- -- case 100: -- default: -- return MulFastestBig(ss2, result); -- } -- } -- -- -- -- /*! -- the first version of the multiplication algorithm -- */ -- --private: -- -- /*! -- multiplication: this = this * ss2 -- -- it returns carry if it has been -- */ -- uint Mul1Ref(const UInt & ss2) -- { -- TTMATH_REFERENCE_ASSERT( ss2 ) -- -- UInt ss1( *this ); -- SetZero(); -- -- for(uint i=0; i < value_size*TTMATH_BITS_PER_UINT ; ++i) -- { -- if( Add(*this) ) -- { -- TTMATH_LOGC("UInt::Mul1", 1) -- return 1; -- } -- -- if( ss1.Rcl(1) ) -- if( Add(ss2) ) -- { -- TTMATH_LOGC("UInt::Mul1", 1) -- return 1; -- } -- } -- -- TTMATH_LOGC("UInt::Mul1", 0) -- -- return 0; -- } -- -- --public: -- -- /*! -- multiplication: this = this * ss2 -- can return carry -- */ -- uint Mul1(const UInt & ss2) -- { -- if( this == &ss2 ) -- { -- UInt copy_ss2(ss2); -- return Mul1Ref(copy_ss2); -- } -- else -- { -- return Mul1Ref(ss2); -- } -- } -- -- -- /*! -- multiplication: result = this * ss2 -- -- result is twice bigger than 'this' and 'ss2' -- this method never returns carry -- */ -- void Mul1Big(const UInt & ss2_, UInt & result) -- { -- UInt ss2; -- uint i; -- -- // copying *this into result and ss2_ into ss2 -- for(i=0 ; i & ss2) -- { -- UInt result; -- uint i, c = 0; -- -- Mul2Big(ss2, result); -- -- // copying result -- for(i=0 ; i & ss2, UInt & result) -- { -- Mul2Big2(table, ss2.table, result); -- -- TTMATH_LOG("UInt::Mul2Big") -- } -- -- --private: -- -- /*! -- an auxiliary method for calculating the multiplication -- -- arguments we're taking as pointers (this is to improve the Mul3Big2()- avoiding -- unnecessary copying objects), the result should be taken as a pointer too, -- but at the moment there is no method AddTwoInts() which can operate on pointers -- */ -- template -- void Mul2Big2(const uint * ss1, const uint * ss2, UInt & result) -- { -- uint x1size = ss_size, x2size = ss_size; -- uint x1start = 0, x2start = 0; -- -- if( ss_size > 2 ) -- { -- // if the ss_size is smaller than or equal to 2 -- // there is no sense to set x1size (and others) to another values -- -- for(x1size=ss_size ; x1size>0 && ss1[x1size-1]==0 ; --x1size); -- for(x2size=ss_size ; x2size>0 && ss2[x2size-1]==0 ; --x2size); -- -- for(x1start=0 ; x1start(ss1, ss2, result, x1start, x1size, x2start, x2size); -- } -- -- -- -- /*! -- an auxiliary method for calculating the multiplication -- */ -- template -- void Mul2Big3(const uint * ss1, const uint * ss2, UInt & result, uint x1start, uint x1size, uint x2start, uint x2size) -- { -- uint r2, r1; -- -- result.SetZero(); -- -- if( x1size==0 || x2size==0 ) -- return; -- -- for(uint x1=x1start ; x1 & ss2) -- { -- UInt result; -- uint i, c = 0; -- -- Mul3Big(ss2, result); -- -- // copying result -- for(i=0 ; i & ss2, UInt & result) -- { -- Mul3Big2(table, ss2.table, result.table); -- -- TTMATH_LOG("UInt::Mul3Big") -- } -- -- -- --private: -- -- /*! -- an auxiliary method for calculating the Karatsuba multiplication -- -- result_size is equal ss_size*2 -- */ -- template -- void Mul3Big2(const uint * ss1, const uint * ss2, uint * result) -- { -- const uint * x1, * x0, * y1, * y0; -- -- -- if( ss_size>1 && ss_size res; -- Mul2Big2(ss1, ss2, res); -- --#ifdef __clang__ --#pragma clang diagnostic push --#pragma clang diagnostic ignored "-Wtautological-compare" --#endif -- -- for(uint i=0 ; i(x1, x0, y1, y0, result); -- } -- else -- { -- // ss_size is even -- x0 = ss1; -- y0 = ss2; -- x1 = ss1 + ss_size / 2; -- y1 = ss2 + ss_size / 2; -- -- // all four vectors (x0 x1 y0 y1) are equal in size -- Mul3Big3(x1, x0, y1, y0, result); -- } -- } -- -- -- --#ifdef _MSC_VER --#pragma warning (disable : 4717) --//warning C4717: recursive on all control paths, function will cause runtime stack overflow --//we have the stop point in Mul3Big2() method --#endif -- -- -- /*! -- an auxiliary method for calculating the Karatsuba multiplication -- -- x = x1*B^m + x0 -- y = y1*B^m + y0 -- -- first_size - is the size of vectors: x0 and y0 -- second_size - is the size of vectors: x1 and y1 (can be either equal first_size or smaller about one from first_size) -- -- x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0 -- where -- z0 = x0*y0 -- z2 = x1*y1 -- z1 = (x1 + x0)*(y1 + y0) - z2 - z0 -- */ -- template -- uint Mul3Big3(const uint * x1, const uint * x0, const uint * y1, const uint * y0, uint * result) -- { -- uint i, c, xc, yc; -- -- UInt temp, temp2; -- UInt z1; -- -- // z0 and z2 we store directly in the result (we don't use any temporary variables) -- Mul3Big2(x0, y0, result); // z0 -- Mul3Big2(x1, y1, result+first_size*2); // z2 -- -- // now we calculate z1 -- // temp = (x0 + x1) -- // temp2 = (y0 + y1) -- // we're using temp and temp2 with UInt, although there can be a carry but -- // we simple remember it in xc and yc (xc and yc can be either 0 or 1), -- // and (x0 + x1)*(y0 + y1) we calculate in this way (schoolbook algorithm): -- // -- // xc | temp -- // yc | temp2 -- // -------------------- -- // (temp * temp2) -- // xc*temp2 | -- // yc*temp | -- // xc*yc | -- // ---------- z1 -------- -- // -- // and the result is never larger in size than 3*first_size -- -- xc = AddVector(x0, x1, first_size, second_size, temp.table); -- yc = AddVector(y0, y1, first_size, second_size, temp2.table); -- -- Mul3Big2(temp.table, temp2.table, z1.table); -- --#ifdef __clang__ --#pragma clang diagnostic push --#pragma clang diagnostic ignored "-Wtautological-compare" --#endif -- -- // clearing the rest of z1 -- for(i=first_size*2 ; i second_size ) -- { -- uint z1_size = result_size - first_size; -- TTMATH_ASSERT( z1_size <= first_size*3 ) -- --#ifdef __clang__ --#pragma clang diagnostic push --#pragma clang diagnostic ignored "-Wtautological-compare" --#endif -- -- for(i=z1_size ; i & ss2) -- { -- UInt result; -- uint i, c = 0; -- -- MulFastestBig(ss2, result); -- -- // copying result -- for(i=0 ; i & ss2, UInt & result) -- { -- if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE ) -- return Mul2Big(ss2, result); -- -- uint x1size = value_size, x2size = value_size; -- uint x1start = 0, x2start = 0; -- -- for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size); -- for(x2size=value_size ; x2size>0 && ss2.table[x2size-1]==0 ; --x2size); -- -- if( x1size==0 || x2size==0 ) -- { -- // either 'this' or 'ss2' is equal zero - the result is zero too -- result.SetZero(); -- return; -- } -- -- for(x1start=0 ; x1start(table, ss2.table, result, x1start, x1size, x2start, x2size); -- -- -- // Karatsuba multiplication -- Mul3Big(ss2, result); -- -- TTMATH_LOG("UInt::MulFastestBig") -- } -- -- -- /*! -- * -- * Division -- * -- * -- */ -- --public: -- -- -- /*! -- division by one unsigned word -- -- returns 1 when divisor is zero -- */ -- uint DivInt(uint divisor, uint * remainder = 0) -- { -- if( divisor == 0 ) -- { -- if( remainder ) -- *remainder = 0; // this is for convenience, without it the compiler can report that 'remainder' is uninitialized -- -- TTMATH_LOG("UInt::DivInt") -- -- return 1; -- } -- -- if( divisor == 1 ) -- { -- if( remainder ) -- *remainder = 0; -- -- TTMATH_LOG("UInt::DivInt") -- -- return 0; -- } -- -- UInt dividend(*this); -- SetZero(); -- -- sint i; // i must be with a sign -- uint r = 0; -- -- // we're looking for the last word in ss1 -- for(i=value_size-1 ; i>0 && dividend.table[i]==0 ; --i); -- -- for( ; i>=0 ; --i) -- DivTwoWords(r, dividend.table[i], divisor, &table[i], &r); -- -- if( remainder ) -- *remainder = r; -- -- TTMATH_LOG("UInt::DivInt") -- -- return 0; -- } -- -- uint DivInt(uint divisor, uint & remainder) -- { -- return DivInt(divisor, &remainder); -- } -- -- -- -- /*! -- division this = this / ss2 -- -- return values: -- 0 - ok -- 1 - division by zero -- 'this' will be the quotient -- 'remainder' - remainder -- */ -- uint Div( const UInt & divisor, -- UInt * remainder = 0, -- uint algorithm = 3) -- { -- switch( algorithm ) -- { -- case 1: -- return Div1(divisor, remainder); -- -- case 2: -- return Div2(divisor, remainder); -- -- case 3: -- default: -- return Div3(divisor, remainder); -- } -- } -- -- uint Div(const UInt & divisor, UInt & remainder, uint algorithm = 3) -- { -- return Div(divisor, &remainder, algorithm); -- } -- -- -- --private: -- -- /*! -- return values: -- 0 - none has to be done -- 1 - division by zero -- 2 - division should be made -- */ -- uint Div_StandardTest( const UInt & v, -- uint & m, uint & n, -- UInt * remainder = 0) -- { -- switch( Div_CalculatingSize(v, m, n) ) -- { -- case 4: // 'this' is equal v -- if( remainder ) -- remainder->SetZero(); -- -- SetOne(); -- TTMATH_LOG("UInt::Div_StandardTest") -- return 0; -- -- case 3: // 'this' is smaller than v -- if( remainder ) -- *remainder = *this; -- -- SetZero(); -- TTMATH_LOG("UInt::Div_StandardTest") -- return 0; -- -- case 2: // 'this' is zero -- if( remainder ) -- remainder->SetZero(); -- -- SetZero(); -- TTMATH_LOG("UInt::Div_StandardTest") -- return 0; -- -- case 1: // v is zero -- TTMATH_LOG("UInt::Div_StandardTest") -- return 1; -- } -- -- TTMATH_LOG("UInt::Div_StandardTest") -- -- return 2; -- } -- -- -- -- /*! -- return values: -- 0 - ok -- 'm' - is the index (from 0) of last non-zero word in table ('this') -- 'n' - is the index (from 0) of last non-zero word in v.table -- 1 - v is zero -- 2 - 'this' is zero -- 3 - 'this' is smaller than v -- 4 - 'this' is equal v -- -- if the return value is different than zero the 'm' and 'n' are undefined -- */ -- uint Div_CalculatingSize(const UInt & v, uint & m, uint & n) -- { -- m = n = value_size-1; -- -- for( ; n!=0 && v.table[n]==0 ; --n); -- -- if( n==0 && v.table[n]==0 ) -- return 1; -- -- for( ; m!=0 && table[m]==0 ; --m); -- -- if( m==0 && table[m]==0 ) -- return 2; -- -- if( m < n ) -- return 3; -- else -- if( m == n ) -- { -- uint i; -- for(i = n ; i!=0 && table[i]==v.table[i] ; --i); -- -- if( table[i] < v.table[i] ) -- return 3; -- else -- if (table[i] == v.table[i] ) -- return 4; -- } -- -- return 0; -- } -- -- --public: -- -- /*! -- the first division algorithm -- radix 2 -- */ -- uint Div1(const UInt & divisor, UInt * remainder = 0) -- { -- uint m,n, test; -- -- test = Div_StandardTest(divisor, m, n, remainder); -- if( test < 2 ) -- return test; -- -- if( !remainder ) -- { -- UInt rem; -- -- return Div1_Calculate(divisor, rem); -- } -- -- return Div1_Calculate(divisor, *remainder); -- } -- -- -- /*! -- the first division algorithm -- radix 2 -- */ -- uint Div1(const UInt & divisor, UInt & remainder) -- { -- return Div1(divisor, &remainder); -- } -- -- --private: -- -- uint Div1_Calculate(const UInt & divisor, UInt & rest) -- { -- if( this == &divisor ) -- { -- UInt divisor_copy(divisor); -- return Div1_CalculateRef(divisor_copy, rest); -- } -- else -- { -- return Div1_CalculateRef(divisor, rest); -- } -- } -- -- -- uint Div1_CalculateRef(const UInt & divisor, UInt & rest) -- { -- TTMATH_REFERENCE_ASSERT( divisor ) -- -- sint loop; -- sint c; -- -- rest.SetZero(); -- loop = value_size * TTMATH_BITS_PER_UINT; -- c = 0; -- -- -- div_a: -- c = Rcl(1, c); -- c = rest.Add(rest,c); -- c = rest.Sub(divisor,c); -- -- c = !c; -- -- if(!c) -- goto div_d; -- -- -- div_b: -- --loop; -- if(loop) -- goto div_a; -- -- c = Rcl(1, c); -- TTMATH_LOG("UInt::Div1_Calculate") -- return 0; -- -- -- div_c: -- c = Rcl(1, c); -- c = rest.Add(rest,c); -- c = rest.Add(divisor); -- -- if(c) -- goto div_b; -- -- -- div_d: -- --loop; -- if(loop) -- goto div_c; -- -- c = Rcl(1, c); -- c = rest.Add(divisor); -- -- TTMATH_LOG("UInt::Div1_Calculate") -- -- return 0; -- } -- -- --public: -- -- /*! -- the second division algorithm -- -- return values: -- 0 - ok -- 1 - division by zero -- */ -- uint Div2(const UInt & divisor, UInt * remainder = 0) -- { -- if( this == &divisor ) -- { -- UInt divisor_copy(divisor); -- return Div2Ref(divisor_copy, remainder); -- } -- else -- { -- return Div2Ref(divisor, remainder); -- } -- } -- -- -- /*! -- the second division algorithm -- -- return values: -- 0 - ok -- 1 - division by zero -- */ -- uint Div2(const UInt & divisor, UInt & remainder) -- { -- return Div2(divisor, &remainder); -- } -- -- --private: -- -- /*! -- the second division algorithm -- -- return values: -- 0 - ok -- 1 - division by zero -- */ -- uint Div2Ref(const UInt & divisor, UInt * remainder = 0) -- { -- uint bits_diff; -- uint status = Div2_Calculate(divisor, remainder, bits_diff); -- if( status < 2 ) -- return status; -- -- if( CmpBiggerEqual(divisor) ) -- { -- Div2(divisor, remainder); -- SetBit(bits_diff); -- } -- else -- { -- if( remainder ) -- *remainder = *this; -- -- SetZero(); -- SetBit(bits_diff); -- } -- -- TTMATH_LOG("UInt::Div2") -- -- return 0; -- } -- -- -- /*! -- return values: -- 0 - we've calculated the division -- 1 - division by zero -- 2 - we have to still calculate -- -- */ -- uint Div2_Calculate(const UInt & divisor, UInt * remainder, -- uint & bits_diff) -- { -- uint table_id, index; -- uint divisor_table_id, divisor_index; -- -- uint status = Div2_FindLeadingBitsAndCheck( divisor, remainder, -- table_id, index, -- divisor_table_id, divisor_index); -- -- if( status < 2 ) -- { -- TTMATH_LOG("UInt::Div2_Calculate") -- return status; -- } -- -- // here we know that 'this' is greater than divisor -- // then 'index' is greater or equal 'divisor_index' -- bits_diff = index - divisor_index; -- -- UInt divisor_copy(divisor); -- divisor_copy.Rcl(bits_diff, 0); -- -- if( CmpSmaller(divisor_copy, table_id) ) -- { -- divisor_copy.Rcr(1); -- --bits_diff; -- } -- -- Sub(divisor_copy, 0); -- -- TTMATH_LOG("UInt::Div2_Calculate") -- -- return 2; -- } -- -- -- /*! -- return values: -- 0 - we've calculated the division -- 1 - division by zero -- 2 - we have to still calculate -- */ -- uint Div2_FindLeadingBitsAndCheck( const UInt & divisor, -- UInt * remainder, -- uint & table_id, uint & index, -- uint & divisor_table_id, uint & divisor_index) -- { -- if( !divisor.FindLeadingBit(divisor_table_id, divisor_index) ) -- { -- // division by zero -- TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck") -- return 1; -- } -- -- if( !FindLeadingBit(table_id, index) ) -- { -- // zero is divided by something -- -- SetZero(); -- -- if( remainder ) -- remainder->SetZero(); -- -- TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck") -- -- return 0; -- } -- -- divisor_index += divisor_table_id * TTMATH_BITS_PER_UINT; -- index += table_id * TTMATH_BITS_PER_UINT; -- -- if( divisor_table_id == 0 ) -- { -- // dividor has only one 32-bit word -- -- uint r; -- DivInt(divisor.table[0], &r); -- -- if( remainder ) -- { -- remainder->SetZero(); -- remainder->table[0] = r; -- } -- -- TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck") -- -- return 0; -- } -- -- -- if( Div2_DivisorGreaterOrEqual( divisor, remainder, -- table_id, index, -- divisor_index) ) -- { -- TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck") -- return 0; -- } -- -- -- TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck") -- -- return 2; -- } -- -- -- /*! -- return values: -- true if divisor is equal or greater than 'this' -- */ -- bool Div2_DivisorGreaterOrEqual( const UInt & divisor, -- UInt * remainder, -- uint table_id, uint index, -- uint divisor_index ) -- { -- if( divisor_index > index ) -- { -- // divisor is greater than this -- -- if( remainder ) -- *remainder = *this; -- -- SetZero(); -- -- TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual") -- -- return true; -- } -- -- if( divisor_index == index ) -- { -- // table_id == divisor_table_id as well -- -- uint i; -- for(i = table_id ; i!=0 && table[i]==divisor.table[i] ; --i); -- -- if( table[i] < divisor.table[i] ) -- { -- // divisor is greater than 'this' -- -- if( remainder ) -- *remainder = *this; -- -- SetZero(); -- -- TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual") -- -- return true; -- } -- else -- if( table[i] == divisor.table[i] ) -- { -- // divisor is equal 'this' -- -- if( remainder ) -- remainder->SetZero(); -- -- SetOne(); -- -- TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual") -- -- return true; -- } -- } -- -- TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual") -- -- return false; -- } -- -- --public: -- -- /*! -- the third division algorithm -- */ -- uint Div3(const UInt & ss2, UInt * remainder = 0) -- { -- if( this == &ss2 ) -- { -- UInt copy_ss2(ss2); -- return Div3Ref(copy_ss2, remainder); -- } -- else -- { -- return Div3Ref(ss2, remainder); -- } -- } -- -- -- /*! -- the third division algorithm -- */ -- uint Div3(const UInt & ss2, UInt & remainder) -- { -- return Div3(ss2, &remainder); -- } -- -- --private: -- -- /*! -- the third division algorithm -- -- this algorithm is described in the following book: -- "The art of computer programming 2" (4.3.1 page 272) -- Donald E. Knuth -- !! give the description here (from the book) -- */ -- uint Div3Ref(const UInt & v, UInt * remainder = 0) -- { -- uint m,n, test; -- -- test = Div_StandardTest(v, m, n, remainder); -- if( test < 2 ) -- return test; -- -- if( n == 0 ) -- { -- uint r; -- DivInt( v.table[0], &r ); -- -- if( remainder ) -- { -- remainder->SetZero(); -- remainder->table[0] = r; -- } -- -- TTMATH_LOG("UInt::Div3") -- -- return 0; -- } -- -- -- // we can only use the third division algorithm when -- // the divisor is greater or equal 2^32 (has more than one 32-bit word) -- ++m; -- ++n; -- m = m - n; -- Div3_Division(v, remainder, m, n); -- -- TTMATH_LOG("UInt::Div3") -- -- return 0; -- } -- -- -- --private: -- -- -- void Div3_Division(UInt v, UInt * remainder, uint m, uint n) -- { -- TTMATH_ASSERT( n>=2 ) -- -- UInt uu, vv; -- UInt q; -- uint d, u_value_size, u0, u1, u2, v1, v0, j=m; -- -- u_value_size = Div3_Normalize(v, n, d); -- -- if( j+n == value_size ) -- u2 = u_value_size; -- else -- u2 = table[j+n]; -- -- Div3_MakeBiggerV(v, vv); -- -- for(uint i = j+1 ; i & uu, uint j, uint n, uint u_max) -- { -- uint i; -- -- for(i=0 ; i so and 'i' is from <0..value_size> -- // then table[i] is always correct (look at the declaration of 'uu') -- uu.table[i] = u_max; -- -- for( ++i ; i & uu, uint j, uint n) -- { -- uint i; -- -- for(i=0 ; i & v, UInt & vv) -- { -- for(uint i=0 ; i & v, uint n, uint & d) -- { -- // v.table[n-1] is != 0 -- -- uint bit = (uint)FindLeadingBitInWord(v.table[n-1]); -- uint move = (TTMATH_BITS_PER_UINT - bit - 1); -- uint res = table[value_size-1]; -- d = move; -- -- if( move > 0 ) -- { -- v.Rcl(move, 0); -- Rcl(move, 0); -- res = res >> (bit + 1); -- } -- else -- { -- res = 0; -- } -- -- TTMATH_LOG("UInt::Div3_Normalize") -- -- return res; -- } -- -- -- void Div3_Unnormalize(UInt * remainder, uint n, uint d) -- { -- for(uint i=n ; i u_temp; -- uint rp; -- bool next_test; -- -- TTMATH_ASSERT( v1 != 0 ) -- -- u_temp.table[1] = u2; -- u_temp.table[0] = u1; -- u_temp.DivInt(v1, &rp); -- -- TTMATH_ASSERT( u_temp.table[1]==0 || u_temp.table[1]==1 ) -- -- do -- { -- bool decrease = false; -- -- if( u_temp.table[1] == 1 ) -- decrease = true; -- else -- { -- UInt<2> temp1, temp2; -- -- UInt<2>::MulTwoWords(u_temp.table[0], v0, temp1.table+1, temp1.table); -- temp2.table[1] = rp; -- temp2.table[0] = u0; -- -- if( temp1 > temp2 ) -- decrease = true; -- } -- -- next_test = false; -- -- if( decrease ) -- { -- u_temp.SubOne(); -- -- rp += v1; -- -- if( rp >= v1 ) // it means that there wasn't a carry (r & uu, -- const UInt & vv, uint & qp) -- { -- // D4 (in the book) -- -- UInt vv_temp(vv); -- vv_temp.MulInt(qp); -- -- if( uu.Sub(vv_temp) ) -- { -- // there was a carry -- -- // -- // !!! this part of code was not tested -- // -- -- --qp; -- uu.Add(vv); -- -- // can be a carry from this additions but it should be ignored -- // because it cancels with the borrow from uu.Sub(vv_temp) -- } -- -- TTMATH_LOG("UInt::Div3_MultiplySubtract") -- } -- -- -- -- -- -- --public: -- -- -- /*! -- power this = this ^ pow -- binary algorithm (r-to-l) -- -- return values: -- 0 - ok -- 1 - carry -- 2 - incorrect argument (0^0) -- */ -- uint Pow(UInt pow) -- { -- if(pow.IsZero() && IsZero()) -- // we don't define zero^zero -- return 2; -- -- UInt start(*this); -- UInt result; -- result.SetOne(); -- uint c = 0; -- -- while( !c ) -- { -- if( pow.table[0] & 1 ) -- c += result.Mul(start); -- -- pow.Rcr2_one(0); -- if( pow.IsZero() ) -- break; -- -- c += start.Mul(start); -- } -- -- *this = result; -- -- TTMATH_LOGC("UInt::Pow(UInt<>)", c) -- -- return (c==0)? 0 : 1; -- } -- -- -- /*! -- square root -- e.g. Sqrt(9) = 3 -- ('digit-by-digit' algorithm) -- */ -- void Sqrt() -- { -- UInt bit, temp; -- -- if( IsZero() ) -- return; -- -- UInt value(*this); -- -- SetZero(); -- bit.SetZero(); -- bit.table[value_size-1] = (TTMATH_UINT_HIGHEST_BIT >> 1); -- -- while( bit > value ) -- bit.Rcr(2); -- -- while( !bit.IsZero() ) -- { -- temp = *this; -- temp.Add(bit); -- -- if( value >= temp ) -- { -- value.Sub(temp); -- Rcr(1); -- Add(bit); -- } -- else -- { -- Rcr(1); -- } -- -- bit.Rcr(2); -- } -- -- TTMATH_LOG("UInt::Sqrt") -- } -- -- -- -- /*! -- this method sets n first bits to value zero -- -- For example: -- let n=2 then if there's a value 111 (bin) there'll be '100' (bin) -- */ -- void ClearFirstBits(uint n) -- { -- if( n >= value_size*TTMATH_BITS_PER_UINT ) -- { -- SetZero(); -- TTMATH_LOG("UInt::ClearFirstBits") -- return; -- } -- -- uint * p = table; -- -- // first we're clearing the whole words -- while( n >= TTMATH_BITS_PER_UINT ) -- { -- *p++ = 0; -- n -= TTMATH_BITS_PER_UINT; -- } -- -- if( n == 0 ) -- { -- TTMATH_LOG("UInt::ClearFirstBits") -- return; -- } -- -- // and then we're clearing one word which has left -- // mask -- all bits are set to one -- uint mask = TTMATH_UINT_MAX_VALUE; -- -- mask = mask << n; -- -- (*p) &= mask; -- -- TTMATH_LOG("UInt::ClearFirstBits") -- } -- -- -- /*! -- this method returns true if the highest bit of the value is set -- */ -- bool IsTheHighestBitSet() const -- { -- return (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0; -- } -- -- -- /*! -- this method returns true if the lowest bit of the value is set -- */ -- bool IsTheLowestBitSet() const -- { -- return (*table & 1) != 0; -- } -- -- -- /*! -- returning true if only the highest bit is set -- */ -- bool IsOnlyTheHighestBitSet() const -- { --#ifdef __clang__ --#pragma clang diagnostic push --#pragma clang diagnostic ignored "-Wtautological-compare" --#endif -- -- for(uint i=0 ; i> (TTMATH_BITS_PER_UINT - rest); -- -- return (table[i] & mask) == 0; -- } -- -- -- -- /*! -- * -- * conversion methods -- * -- */ -- -- -- -- /*! -- this method converts an UInt type to this class -- -- this operation has mainly sense if the value from p is -- equal or smaller than that one which is returned from UInt::SetMax() -- -- it returns a carry if the value 'p' is too big -- */ -- template -- uint FromUInt(const UInt & p) -- { -- uint min_size = (value_size < argument_size)? value_size : argument_size; -- uint i; -- -- for(i=0 ; i argument_size ) -- { -- // 'this' is longer than 'p' -- -- for( ; i)", 1) -- return 1; -- } -- } -- -- TTMATH_LOGC("UInt::FromUInt(UInt<>)", 0) -- -- return 0; -- } -- -- -- /*! -- this method converts an UInt type to this class -- -- this operation has mainly sense if the value from p is -- equal or smaller than that one which is returned from UInt::SetMax() -- -- it returns a carry if the value 'p' is too big -- */ -- template -- uint FromInt(const UInt & p) -- { -- return FromUInt(p); -- } -- -- -- /*! -- this method converts the uint type to this class -- */ -- uint FromUInt(uint value) -- { -- for(uint i=1 ; i type to this class -- -- it doesn't return a carry -- */ --/* template -- UInt & operator=(const UInt & p) -- { -- FromUInt(p); -- -- return *this; -- } --*/ -- -- /*! -- the assignment operator -- */ --/* UInt & operator=(const UInt & p) -- { -- for(uint i=0 ; i)") -- -- return *this; -- } --*/ -- -- /*! -- this method converts the uint type to this class -- */ -- UInt & operator=(uint i) -- { -- FromUInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting the uint to this class -- */ --/* UInt(uint i) -- { -- FromUInt(i); -- } --*/ -- -- /*! -- this method converts the sint type to this class -- */ -- UInt & operator=(sint i) -- { -- FromInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting the sint to this class -- -- look at the description of UInt::operator=(sint) -- */ --/* UInt(sint i) -- { -- FromInt(i); -- } --*/ -- --#ifdef TTMATH_PLATFORM32 -- -- -- /*! -- this method converts unsigned 64 bit int type to this class -- ***this method is created only on a 32bit platform*** -- */ -- uint FromUInt(ulint n) -- { -- table[0] = (uint)n; -- -- if( value_size == 1 ) -- { -- uint c = ((n >> TTMATH_BITS_PER_UINT) == 0) ? 0 : 1; -- -- TTMATH_LOGC("UInt::FromUInt(ulint)", c) -- return c; -- } -- -- table[1] = (uint)(n >> TTMATH_BITS_PER_UINT); -- -- for(uint i=2 ; i & operator=(ulint n) -- { -- FromUInt(n); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting unsigned 64 bit int to this class -- ***this constructor is created only on a 32bit platform*** -- */ --/* UInt(ulint n) -- { -- FromUInt(n); -- } --*/ -- -- /*! -- this operator converts signed 64 bit int type to this class -- ***this operator is created only on a 32bit platform*** -- */ -- UInt & operator=(slint n) -- { -- FromInt(n); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting signed 64 bit int to this class -- ***this constructor is created only on a 32bit platform*** -- */ --/* UInt(slint n) -- { -- FromInt(n); -- } --*/ --#endif -- -- -- --#ifdef TTMATH_PLATFORM64 -- -- -- /*! -- this method converts 32 bit unsigned int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- uint FromUInt(unsigned int i) -- { -- return FromUInt(uint(i)); -- } -- -- /*! -- this method converts 32 bit unsigned int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- uint FromInt(unsigned int i) -- { -- return FromUInt(uint(i)); -- } -- -- -- /*! -- this method converts 32 bit signed int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- uint FromInt(signed int i) -- { -- return FromInt(sint(i)); -- } -- -- -- /*! -- this operator converts 32 bit unsigned int type to this class -- ***this operator is created only on a 64bit platform*** -- */ -- UInt & operator=(unsigned int i) -- { -- FromUInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting 32 bit unsigned int to this class -- ***this constructor is created only on a 64bit platform*** -- */ --/* UInt(unsigned int i) -- { -- FromUInt(i); -- } --*/ -- -- /*! -- an operator for converting 32 bit signed int to this class -- ***this constructor is created only on a 64bit platform*** -- */ -- UInt & operator=(signed int i) -- { -- FromInt(i); -- -- return *this; -- } -- -- -- /*! -- a constructor for converting 32 bit signed int to this class -- ***this constructor is created only on a 64bit platform*** -- */ --/* UInt(signed int i) -- { -- FromInt(i); -- } --*/ -- --#endif -- -- -- -- -- -- /*! -- a constructor for converting a string to this class (with the base=10) -- */ --/* UInt(const char * s) -- { -- FromString(s); -- } --*/ -- -- /*! -- a constructor for converting a string to this class (with the base=10) -- */ --/* UInt(const std::string & s) -- { -- FromString( s.c_str() ); -- } --*/ -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- a constructor for converting a string to this class (with the base=10) -- */ -- UInt(const wchar_t * s) -- { -- FromString(s); -- } -- -- -- /*! -- a constructor for converting a string to this class (with the base=10) -- */ -- UInt(const std::wstring & s) -- { -- FromString( s.c_str() ); -- } -- --#endif -- -- -- -- -- /*! -- a default constructor -- -- we don't clear the table -- */ --/* UInt() -- { -- // when macro TTMATH_DEBUG_LOG is defined -- // we set special values to the table -- // in order to be everywhere the same value of the UInt object -- // without this it would be difficult to analyse the log file -- #ifdef TTMATH_DEBUG_LOG -- #ifdef TTMATH_PLATFORM32 -- for(uint i=0 ; i & u) -- { -- for(uint i=0 ; i)") -- } --*/ -- -- -- /*! -- a template for producting constructors for copying from another types -- */ --/* template -- UInt(const UInt & u) -- { -- // look that 'size' we still set as 'value_size' and not as u.value_size -- FromUInt(u); -- } --*/ -- -- -- -- /*! -- a destructor -- */ --/* ~UInt() -- { -- } --*/ -- -- /*! -- this method returns the lowest value from table -- -- we must be sure when we using this method whether the value -- will hold in an uint type or not (the rest value from the table must be zero) -- */ -- uint ToUInt() const -- { -- return table[0]; -- } -- -- -- /*! -- this method converts the value to uint type -- can return a carry if the value is too long to store it in uint type -- */ -- uint ToUInt(uint & result) const -- { -- result = table[0]; -- -- for(uint i=1 ; i> 32) != 0 ) -- return 1; -- -- for(uint i=1 ; i -- */ -- double ToStringLog2(uint x) const -- { -- static double log_tab[] = { -- 1.000000000000000000, -- 0.630929753571457437, -- 0.500000000000000000, -- 0.430676558073393050, -- 0.386852807234541586, -- 0.356207187108022176, -- 0.333333333333333333, -- 0.315464876785728718, -- 0.301029995663981195, -- 0.289064826317887859, -- 0.278942945651129843, -- 0.270238154427319741, -- 0.262649535037193547, -- 0.255958024809815489, -- 0.250000000000000000 -- }; -- -- if( x<2 || x>16 ) -- return 0; -- -- return log_tab[x-2]; -- } -- -- --public: -- -- -- /*! -- an auxiliary method for converting to a string -- it's used from Int::ToString() too (negative is set true then) -- */ -- template -- void ToStringBase(string_type & result, uint b = 10, bool negative = false) const -- { -- UInt temp(*this); -- uint rest, table_id, index, digits; -- double digits_d; -- char character; -- -- result.clear(); -- -- if( b<2 || b>16 ) -- return; -- -- if( !FindLeadingBit(table_id, index) ) -- { -- result = '0'; -- return; -- } -- -- if( negative ) -- result = '-'; -- -- digits_d = table_id; // for not making an overflow in uint type -- digits_d *= TTMATH_BITS_PER_UINT; -- digits_d += index + 1; -- digits_d *= ToStringLog2(b); -- digits = static_cast(digits_d) + 3; // plus some epsilon -- -- if( result.capacity() < digits ) -- result.reserve(digits); -- -- do -- { -- temp.DivInt(b, &rest); -- character = static_cast(Misc::DigitToChar(rest)); -- result.insert(result.end(), character); -- } -- while( !temp.IsZero() ); -- -- size_t i1 = negative ? 1 : 0; // the first is a hyphen (when negative is true) -- size_t i2 = result.size() - 1; -- -- for( ; i1 < i2 ; ++i1, --i2 ) -- { -- char tempc = static_cast(result[i1]); -- result[i1] = result[i2]; -- result[i2] = tempc; -- } -- } -- -- -- -- /*! -- this method converts the value to a string with a base equal 'b' -- */ -- void ToString(std::string & result, uint b = 10) const -- { -- return ToStringBase(result, b); -- } -- -- -- std::string ToString(uint b = 10) const -- { -- std::string result; -- ToStringBase(result, b); -- -- return result; -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- void ToString(std::wstring & result, uint b = 10) const -- { -- return ToStringBase(result, b); -- } -- -- std::wstring ToWString(uint b = 10) const -- { -- std::wstring result; -- ToStringBase(result, b); -- -- return result; -- } -- --#endif -- -- -- --private: -- -- /*! -- an auxiliary method for converting from a string -- */ -- template -- uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0) -- { -- UInt base; -- base.FromUInt( b ); -- UInt temp; -- sint z; -- uint c = 0; -- -- SetZero(); -- temp.SetZero(); -- Misc::SkipWhiteCharacters(s); -- -- if( after_source ) -- *after_source = s; -- -- if( value_read ) -- *value_read = false; -- -- if( b<2 || b>16 ) -- return 1; -- -- -- for( ; (z=Misc::CharToDigit(*s, b)) != -1 ; ++s) -- { -- if( value_read ) -- *value_read = true; -- -- if( c == 0 ) -- { -- temp.table[0] = z; -- -- c += Mul(base); // !! IMPROVE ME: there can be used MulInt here -- c += Add(temp); -- } -- } -- -- if( after_source ) -- *after_source = s; -- -- TTMATH_LOGC("UInt::FromString", c) -- -- return (c==0)? 0 : 1; -- } -- -- --public: -- -- -- /*! -- this method converts a string into its value -- it returns carry=1 if the value will be too big or an incorrect base 'b' is given -- -- string is ended with a non-digit value, for example: -- "12" will be translated to 12 -- as well as: -- "12foo" will be translated to 12 too -- -- existing first white characters will be ommited -- -- if the value from s is too large the rest digits will be skipped -- -- after_source (if exists) is pointing at the end of the parsed string -- -- value_read (if exists) tells whether something has actually been read (at least one digit) -- */ -- uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0) -- { -- return FromStringBase(s, b, after_source, value_read); -- } -- -- -- /*! -- this method converts a string into its value -- -- (it returns carry=1 if the value will be too big or an incorrect base 'b' is given) -- */ -- uint FromString(const std::string & s, uint b = 10) -- { -- return FromString( s.c_str(), b ); -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- UInt & operator=(const char * s) -- { -- FromString(s); -- -- return *this; -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- UInt & operator=(const std::string & s) -- { -- FromString( s.c_str() ); -- -- return *this; -- } -- -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- this method converts a string into its value -- */ -- uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0) -- { -- return FromStringBase(s, b, after_source, value_read); -- } -- -- -- /*! -- this method converts a string into its value -- -- (it returns carry=1 if the value will be too big or an incorrect base 'b' is given) -- */ -- uint FromString(const std::wstring & s, uint b = 10) -- { -- return FromString( s.c_str(), b ); -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- UInt & operator=(const wchar_t * s) -- { -- FromString(s); -- -- return *this; -- } -- -- -- /*! -- this operator converts a string into its value (with base = 10) -- */ -- UInt & operator=(const std::wstring & s) -- { -- FromString( s.c_str() ); -- -- return *this; -- } -- --#endif -- -- -- /*! -- * -- * methods for comparing -- * -- */ -- -- -- /*! -- this method returns true if 'this' is smaller than 'l' -- -- 'index' is an index of the first word from will be the comparison performed -- (note: we start the comparison from back - from the last word, when index is -1 /default/ -- it is automatically set into the last word) -- I introduced it for some kind of optimization made in the second division algorithm (Div2) -- */ -- bool CmpSmaller(const UInt & l, sint index = -1) const -- { -- sint i; -- -- if( index==-1 || index>=sint(value_size) ) -- i = value_size - 1; -- else -- i = index; -- -- -- for( ; i>=0 ; --i) -- { -- if( table[i] != l.table[i] ) -- return table[i] < l.table[i]; -- } -- -- // they're equal -- return false; -- } -- -- -- -- /*! -- this method returns true if 'this' is bigger than 'l' -- -- 'index' is an index of the first word from will be the comparison performed -- (note: we start the comparison from back - from the last word, when index is -1 /default/ -- it is automatically set into the last word) -- -- I introduced it for some kind of optimization made in the second division algorithm (Div2) -- */ -- bool CmpBigger(const UInt & l, sint index = -1) const -- { -- sint i; -- -- if( index==-1 || index>=sint(value_size) ) -- i = value_size - 1; -- else -- i = index; -- -- -- for( ; i>=0 ; --i) -- { -- if( table[i] != l.table[i] ) -- return table[i] > l.table[i]; -- } -- -- // they're equal -- return false; -- } -- -- -- /*! -- this method returns true if 'this' is equal 'l' -- -- 'index' is an index of the first word from will be the comparison performed -- (note: we start the comparison from back - from the last word, when index is -1 /default/ -- it is automatically set into the last word) -- */ -- bool CmpEqual(const UInt & l, sint index = -1) const -- { -- sint i; -- -- if( index==-1 || index>=sint(value_size) ) -- i = value_size - 1; -- else -- i = index; -- -- -- for( ; i>=0 ; --i) -- if( table[i] != l.table[i] ) -- return false; -- -- return true; -- } -- -- -- -- /*! -- this method returns true if 'this' is smaller than or equal 'l' -- -- 'index' is an index of the first word from will be the comparison performed -- (note: we start the comparison from back - from the last word, when index is -1 /default/ -- it is automatically set into the last word) -- */ -- bool CmpSmallerEqual(const UInt & l, sint index=-1) const -- { -- sint i; -- -- if( index==-1 || index>=sint(value_size) ) -- i = value_size - 1; -- else -- i = index; -- -- -- for( ; i>=0 ; --i) -- { -- if( table[i] != l.table[i] ) -- return table[i] < l.table[i]; -- } -- -- // they're equal -- return true; -- } -- -- -- -- /*! -- this method returns true if 'this' is bigger than or equal 'l' -- -- 'index' is an index of the first word from will be the comparison performed -- (note: we start the comparison from back - from the last word, when index is -1 /default/ -- it is automatically set into the last word) -- */ -- bool CmpBiggerEqual(const UInt & l, sint index=-1) const -- { -- sint i; -- -- if( index==-1 || index>=sint(value_size) ) -- i = value_size - 1; -- else -- i = index; -- -- -- for( ; i>=0 ; --i) -- { -- if( table[i] != l.table[i] ) -- return table[i] > l.table[i]; -- } -- -- // they're equal -- return true; -- } -- -- -- /* -- operators for comparising -- */ -- -- bool operator<(const UInt & l) const -- { -- return CmpSmaller(l); -- } -- -- -- bool operator>(const UInt & l) const -- { -- return CmpBigger(l); -- } -- -- -- bool operator==(const UInt & l) const -- { -- return CmpEqual(l); -- } -- -- -- bool operator!=(const UInt & l) const -- { -- return !operator==(l); -- } -- -- -- bool operator<=(const UInt & l) const -- { -- return CmpSmallerEqual(l); -- } -- -- bool operator>=(const UInt & l) const -- { -- return CmpBiggerEqual(l); -- } -- -- -- /*! -- * -- * standard mathematical operators -- * -- */ -- -- UInt operator-(const UInt & p2) const -- { -- UInt temp(*this); -- -- temp.Sub(p2); -- -- return temp; -- } -- -- UInt & operator-=(const UInt & p2) -- { -- Sub(p2); -- -- return *this; -- } -- -- UInt operator+(const UInt & p2) const -- { -- UInt temp(*this); -- -- temp.Add(p2); -- -- return temp; -- } -- -- UInt & operator+=(const UInt & p2) -- { -- Add(p2); -- -- return *this; -- } -- -- -- UInt operator*(const UInt & p2) const -- { -- UInt temp(*this); -- -- temp.Mul(p2); -- -- return temp; -- } -- -- -- UInt & operator*=(const UInt & p2) -- { -- Mul(p2); -- -- return *this; -- } -- -- -- UInt operator/(const UInt & p2) const -- { -- UInt temp(*this); -- -- temp.Div(p2); -- -- return temp; -- } -- -- -- UInt & operator/=(const UInt & p2) -- { -- Div(p2); -- -- return *this; -- } -- -- -- UInt operator%(const UInt & p2) const -- { -- UInt temp(*this); -- UInt remainder; -- -- temp.Div( p2, remainder ); -- -- return remainder; -- } -- -- -- UInt & operator%=(const UInt & p2) -- { -- UInt remainder; -- -- Div( p2, remainder ); -- operator=(remainder); -- -- return *this; -- } -- -- -- /*! -- Prefix operator e.g ++variable -- */ -- UInt & operator++() -- { -- AddOne(); -- -- return *this; -- } -- -- -- /*! -- Postfix operator e.g variable++ -- */ -- UInt operator++(int) -- { -- UInt temp( *this ); -- -- AddOne(); -- -- return temp; -- } -- -- -- UInt & operator--() -- { -- SubOne(); -- -- return *this; -- } -- -- -- UInt operator--(int) -- { -- UInt temp( *this ); -- -- SubOne(); -- -- return temp; -- } -- -- -- -- /*! -- * -- * bitwise operators -- * -- */ -- -- UInt operator~() const -- { -- UInt temp( *this ); -- -- temp.BitNot(); -- -- return temp; -- } -- -- -- UInt operator&(const UInt & p2) const -- { -- UInt temp( *this ); -- -- temp.BitAnd(p2); -- -- return temp; -- } -- -- -- UInt & operator&=(const UInt & p2) -- { -- BitAnd(p2); -- -- return *this; -- } -- -- -- UInt operator|(const UInt & p2) const -- { -- UInt temp( *this ); -- -- temp.BitOr(p2); -- -- return temp; -- } -- -- -- UInt & operator|=(const UInt & p2) -- { -- BitOr(p2); -- -- return *this; -- } -- -- -- UInt operator^(const UInt & p2) const -- { -- UInt temp( *this ); -- -- temp.BitXor(p2); -- -- return temp; -- } -- -- -- UInt & operator^=(const UInt & p2) -- { -- BitXor(p2); -- -- return *this; -- } -- -- -- UInt operator>>(int move) const -- { -- UInt temp( *this ); -- -- temp.Rcr(move); -- -- return temp; -- } -- -- -- UInt & operator>>=(int move) -- { -- Rcr(move); -- -- return *this; -- } -- -- -- UInt operator<<(int move) const -- { -- UInt temp( *this ); -- -- temp.Rcl(move); -- -- return temp; -- } -- -- -- UInt & operator<<=(int move) -- { -- Rcl(move); -- -- return *this; -- } -- -- -- /*! -- * -- * input/output operators for standard streams -- * -- * (they are very simple, in the future they should be changed) -- * -- */ -- -- --private: -- -- -- /*! -- an auxiliary method for outputing to standard streams -- */ -- template -- static ostream_type & OutputToStream(ostream_type & s, const UInt & l) -- { -- string_type ss; -- -- l.ToString(ss); -- s << ss; -- -- return s; -- } -- -- --public: -- -- -- /*! -- output to standard streams -- */ -- friend std::ostream & operator<<(std::ostream & s, const UInt & l) -- { -- return OutputToStream(s, l); -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- output to standard streams -- */ -- friend std::wostream & operator<<(std::wostream & s, const UInt & l) -- { -- return OutputToStream(s, l); -- } -- --#endif -- -- -- --private: -- -- /*! -- an auxiliary method for reading from standard streams -- */ -- template -- static istream_type & InputFromStream(istream_type & s, UInt & l) -- { -- string_type ss; -- -- // char or wchar_t for operator>> -- char_type z; -- -- // operator>> omits white characters if they're set for ommiting -- s >> z; -- -- // we're reading only digits (base=10) -- while( s.good() && Misc::CharToDigit(z, 10)>=0 ) -- { -- ss += z; -- z = static_cast(s.get()); -- } -- -- // we're leaving the last read character -- // (it's not belonging to the value) -- s.unget(); -- -- l.FromString(ss); -- -- return s; -- } -- --public: -- -- -- /*! -- input from standard streams -- */ -- friend std::istream & operator>>(std::istream & s, UInt & l) -- { -- return InputFromStream(s, l); -- } -- -- --#ifndef TTMATH_DONT_USE_WCHAR -- -- /*! -- input from standard streams -- */ -- friend std::wistream & operator>>(std::wistream & s, UInt & l) -- { -- return InputFromStream(s, l); -- } -- --#endif -- -- -- /* -- Following methods are defined in: -- ttmathuint_x86.h -- ttmathuint_x86_64.h -- ttmathuint_noasm.h -- */ -- --#ifdef TTMATH_NOASM -- static uint AddTwoWords(uint a, uint b, uint carry, uint * result); -- static uint SubTwoWords(uint a, uint b, uint carry, uint * result); -- --#ifdef TTMATH_PLATFORM64 -- -- union uint_ -- { -- struct -- { -- unsigned int low; // 32 bit -- unsigned int high; // 32 bit -- } u_; -- -- uint u; // 64 bit -- }; -- -- -- static void DivTwoWords2(uint a,uint b, uint c, uint * r, uint * rest); -- static uint DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_); -- static uint DivTwoWordsUnnormalize(uint u, uint d); -- static unsigned int DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_); -- static void MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_); -- --#endif // TTMATH_PLATFORM64 --#endif // TTMATH_NOASM -- -- --private: -- uint Rcl2_one(uint c); -- uint Rcr2_one(uint c); -- uint Rcl2(uint bits, uint c); -- uint Rcr2(uint bits, uint c); -- --public: -- static const char * LibTypeStr(); -- static LibTypeCode LibType(); -- uint Add(const UInt & ss2, uint c=0); -- uint AddInt(uint value, uint index = 0); -- uint AddTwoInts(uint x2, uint x1, uint index); -- static uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result); -- uint Sub(const UInt & ss2, uint c=0); -- uint SubInt(uint value, uint index = 0); -- static uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result); -- static sint FindLeadingBitInWord(uint x); -- static sint FindLowestBitInWord(uint x); -- static uint SetBitInWord(uint & value, uint bit); -- static void MulTwoWords(uint a, uint b, uint * result_high, uint * result_low); -- static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest); -- --}; -- -- -- --/*! -- this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array" -- when compiling Mul3Big2() method --*/ --template<> --class UInt<0> --{ --public: -- uint table[1]; -- -- void Mul2Big(const UInt<0> &, UInt<0> &) { TTMATH_ASSERT(false) }; -- void SetZero() { TTMATH_ASSERT(false) }; -- uint AddTwoInts(uint, uint, uint) { TTMATH_ASSERT(false) return 0; }; --}; -- -- --} //namespace -- -- --#include "ttmathuint_x86.h" --#include "ttmathuint_x86_64.h" --#include "ttmathuint_noasm.h" -- --#endif -diff --git a/extern/ttmath/ttmathuint_noasm.h b/extern/ttmath/ttmathuint_noasm.h -deleted file mode 100644 -index 07c73fc499..0000000000 ---- a/extern/ttmath/ttmathuint_noasm.h -+++ /dev/null -@@ -1,1017 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2010, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#ifndef headerfilettmathuint_noasm --#define headerfilettmathuint_noasm -- -- --#ifdef TTMATH_NOASM -- --/*! -- \file ttmathuint_noasm.h -- \brief template class UInt with methods without any assembler code -- -- this file is included at the end of ttmathuint.h --*/ -- -- --namespace ttmath --{ -- -- /*! -- returning the string represents the currect type of the library -- we have following types: -- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) -- asm_gcc_32 - with asm code designed for GCC (32 bits) -- asm_vc_64 - with asm for VC (64 bit) -- asm_gcc_64 - with asm for GCC (64 bit) -- no_asm_32 - pure C++ version (32 bit) - without any asm code -- no_asm_64 - pure C++ version (64 bit) - without any asm code -- */ -- template -- const char * UInt::LibTypeStr() -- { -- #ifdef TTMATH_PLATFORM32 -- static const char info[] = "no_asm_32"; -- #endif -- -- #ifdef TTMATH_PLATFORM64 -- static const char info[] = "no_asm_64"; -- #endif -- -- return info; -- } -- -- -- /*! -- returning the currect type of the library -- */ -- template -- LibTypeCode UInt::LibType() -- { -- #ifdef TTMATH_PLATFORM32 -- LibTypeCode info = no_asm_32; -- #endif -- -- #ifdef TTMATH_PLATFORM64 -- LibTypeCode info = no_asm_64; -- #endif -- -- return info; -- } -- -- -- /*! -- this method adds two words together -- returns carry -- -- this method is created only when TTMATH_NOASM macro is defined -- */ -- template -- uint UInt::AddTwoWords(uint a, uint b, uint carry, uint * result) -- { -- uint temp; -- -- if( carry == 0 ) -- { -- temp = a + b; -- -- if( temp < a ) -- carry = 1; -- } -- else -- { -- carry = 1; -- temp = a + b + carry; -- -- if( temp > a ) // !(temp<=a) -- carry = 0; -- } -- -- *result = temp; -- -- return carry; -- } -- -- -- -- /*! -- this method adding ss2 to the this and adding carry if it's defined -- (this = this + ss2 + c) -- -- c must be zero or one (might be a bigger value than 1) -- function returns carry (1) (if it was) -- */ -- -- template -- uint UInt::Add(const UInt & ss2, uint c) -- { -- uint i; -- -- for(i=0 ; i -- uint UInt::AddInt(uint value, uint index) -- { -- uint i, c; -- -- TTMATH_ASSERT( index < value_size ) -- -- -- c = AddTwoWords(table[index], value, 0, &table[index]); -- -- for(i=index+1 ; i -- uint UInt::AddTwoInts(uint x2, uint x1, uint index) -- { -- uint i, c; -- -- TTMATH_ASSERT( index < value_size - 1 ) -- -- -- c = AddTwoWords(table[index], x1, 0, &table[index]); -- c = AddTwoWords(table[index+1], x2, c, &table[index+1]); -- -- for(i=index+2 ; i -- uint UInt::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) -- { -- uint i, c = 0; -- -- TTMATH_ASSERT( ss1_size >= ss2_size ) -- -- for(i=0 ; i -- uint UInt::SubTwoWords(uint a, uint b, uint carry, uint * result) -- { -- if( carry == 0 ) -- { -- *result = a - b; -- -- if( a < b ) -- carry = 1; -- } -- else -- { -- carry = 1; -- *result = a - b - carry; -- -- if( a > b ) // !(a <= b ) -- carry = 0; -- } -- -- return carry; -- } -- -- -- -- -- /*! -- this method's subtracting ss2 from the 'this' and subtracting -- carry if it has been defined -- (this = this - ss2 - c) -- -- c must be zero or one (might be a bigger value than 1) -- function returns carry (1) (if it was) -- */ -- template -- uint UInt::Sub(const UInt & ss2, uint c) -- { -- uint i; -- -- for(i=0 ; i -- uint UInt::SubInt(uint value, uint index) -- { -- uint i, c; -- -- TTMATH_ASSERT( index < value_size ) -- -- -- c = SubTwoWords(table[index], value, 0, &table[index]); -- -- for(i=index+1 ; i -- uint UInt::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) -- { -- uint i, c = 0; -- -- TTMATH_ASSERT( ss1_size >= ss2_size ) -- -- for(i=0 ; i -- uint UInt::Rcl2_one(uint c) -- { -- uint i, new_c; -- -- if( c != 0 ) -- c = 1; -- -- for(i=0 ; i this -> return value -- -- the highest *bit* will be held the 'c' and -- the state of one additional bit (on the right hand side) -- will be returned -- -- for example: -- let this is 000000010 -- after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0 -- */ -- template -- uint UInt::Rcr2_one(uint c) -- { -- sint i; // signed i -- uint new_c; -- -- if( c != 0 ) -- c = TTMATH_UINT_HIGHEST_BIT; -- -- for(i=sint(value_size)-1 ; i>=0 ; --i) -- { -- new_c = (table[i] & 1) ? TTMATH_UINT_HIGHEST_BIT : 0; -- table[i] = (table[i] >> 1) | c; -- c = new_c; -- } -- -- c = (c != 0)? 1 : 0; -- -- TTMATH_LOGC("UInt::Rcr2_one", c) -- -- return c; -- } -- -- -- -- -- /*! -- this method moves all bits into the left hand side -- return value <- this <- c -- -- the lowest *bits* will be held the 'c' and -- the state of one additional bit (on the left hand side) -- will be returned -- -- for example: -- let this is 001010000 -- after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1 -- */ -- template -- uint UInt::Rcl2(uint bits, uint c) -- { -- TTMATH_ASSERT( bits>0 && bits> move; -- -- for(i=0 ; i> move; -- table[i] = (table[i] << bits) | c; -- c = new_c; -- } -- -- TTMATH_LOGC("UInt::Rcl2", (c & 1)) -- -- return (c & 1); -- } -- -- -- -- -- /*! -- this method moves all bits into the right hand side -- C -> this -> return value -- -- the highest *bits* will be held the 'c' and -- the state of one additional bit (on the right hand side) -- will be returned -- -- for example: -- let this is 000000010 -- after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1 -- */ -- template -- uint UInt::Rcr2(uint bits, uint c) -- { -- TTMATH_ASSERT( bits>0 && bits=0 ; --i) -- { -- new_c = table[i] << move; -- table[i] = (table[i] >> bits) | c; -- c = new_c; -- } -- -- c = (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; -- -- TTMATH_LOGC("UInt::Rcr2", c) -- -- return c; -- } -- -- -- -- -- /*! -- this method returns the number of the highest set bit in x -- if the 'x' is zero this method returns '-1' -- */ -- template -- sint UInt::FindLeadingBitInWord(uint x) -- { -- if( x == 0 ) -- return -1; -- -- uint bit = TTMATH_BITS_PER_UINT - 1; -- -- while( (x & TTMATH_UINT_HIGHEST_BIT) == 0 ) -- { -- x = x << 1; -- --bit; -- } -- -- return bit; -- } -- -- -- -- /*! -- this method returns the number of the highest set bit in x -- if the 'x' is zero this method returns '-1' -- */ -- template -- sint UInt::FindLowestBitInWord(uint x) -- { -- if( x == 0 ) -- return -1; -- -- uint bit = 0; -- -- while( (x & 1) == 0 ) -- { -- x = x >> 1; -- ++bit; -- } -- -- return bit; -- } -- -- -- -- /*! -- this method sets a special bit in the 'value' -- and returns the last state of the bit (zero or one) -- -- bit is from <0,TTMATH_BITS_PER_UINT-1> -- -- e.g. -- uint x = 100; -- uint bit = SetBitInWord(x, 3); -- now: x = 108 and bit = 0 -- */ -- template -- uint UInt::SetBitInWord(uint & value, uint bit) -- { -- TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT ) -- -- uint mask = 1; -- -- if( bit > 0 ) -- mask = mask << bit; -- -- uint last = value & mask; -- value = value | mask; -- -- return (last != 0) ? 1 : 0; -- } -- -- -- -- -- -- -- /*! -- * -- * Multiplication -- * -- * -- */ -- -- -- /*! -- multiplication: result_high:result_low = a * b -- result_high - higher word of the result -- result_low - lower word of the result -- -- this methos never returns a carry -- this method is used in the second version of the multiplication algorithms -- */ -- template -- void UInt::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low) -- { -- #ifdef TTMATH_PLATFORM32 -- -- /* -- on 32bit platforms we have defined 'unsigned long long int' type known as 'ulint' in ttmath namespace -- this type has 64 bits, then we're using only one multiplication: 32bit * 32bit = 64bit -- */ -- -- union uint_ -- { -- struct -- { -- uint low; // 32 bits -- uint high; // 32 bits -- } u_; -- -- ulint u; // 64 bits -- } res; -- -- res.u = ulint(a) * ulint(b); // multiply two 32bit words, the result has 64 bits -- -- *result_high = res.u_.high; -- *result_low = res.u_.low; -- -- #else -- -- /* -- 64 bits platforms -- -- we don't have a native type which has 128 bits -- then we're splitting 'a' and 'b' to 4 parts (high and low halves) -- and using 4 multiplications (with additions and carry correctness) -- */ -- -- uint_ a_; -- uint_ b_; -- uint_ res_high1, res_high2; -- uint_ res_low1, res_low2; -- -- a_.u = a; -- b_.u = b; -- -- /* -- the multiplication is as follows (schoolbook algorithm with O(n^2) ): -- -- 32 bits 32 bits -- -- +--------------------------------+ -- | a_.u_.high | a_.u_.low | -- +--------------------------------+ -- | b_.u_.high | b_.u_.low | -- +--------------------------------+--------------------------------+ -- | res_high1.u | res_low1.u | -- +--------------------------------+--------------------------------+ -- | res_high2.u | res_low2.u | -- +--------------------------------+--------------------------------+ -- -- 64 bits 64 bits -- */ -- -- -- uint_ temp; -- -- res_low1.u = uint(b_.u_.low) * uint(a_.u_.low); -- -- temp.u = uint(res_low1.u_.high) + uint(b_.u_.low) * uint(a_.u_.high); -- res_low1.u_.high = temp.u_.low; -- res_high1.u_.low = temp.u_.high; -- res_high1.u_.high = 0; -- -- res_low2.u_.low = 0; -- temp.u = uint(b_.u_.high) * uint(a_.u_.low); -- res_low2.u_.high = temp.u_.low; -- -- res_high2.u = uint(b_.u_.high) * uint(a_.u_.high) + uint(temp.u_.high); -- -- uint c = AddTwoWords(res_low1.u, res_low2.u, 0, &res_low2.u); -- AddTwoWords(res_high1.u, res_high2.u, c, &res_high2.u); // there is no carry from here -- -- *result_high = res_high2.u; -- *result_low = res_low2.u; -- -- #endif -- } -- -- -- -- -- /*! -- * -- * Division -- * -- * -- */ -- -- -- /*! -- this method calculates 64bits word a:b / 32bits c (a higher, b lower word) -- r = a:b / c and rest - remainder -- -- * -- * WARNING: -- * the c has to be suitably large for the result being keeped in one word, -- * if c is equal zero there'll be a hardware interruption (0) -- * and probably the end of your program -- * -- */ -- template -- void UInt::DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest) -- { -- // (a < c ) for the result to be one word -- TTMATH_ASSERT( c != 0 && a < c ) -- -- #ifdef TTMATH_PLATFORM32 -- -- union -- { -- struct -- { -- uint low; // 32 bits -- uint high; // 32 bits -- } u_; -- -- ulint u; // 64 bits -- } ab; -- -- ab.u_.high = a; -- ab.u_.low = b; -- -- *r = uint(ab.u / c); -- *rest = uint(ab.u % c); -- -- #else -- -- uint_ c_; -- c_.u = c; -- -- -- if( a == 0 ) -- { -- *r = b / c; -- *rest = b % c; -- } -- else -- if( c_.u_.high == 0 ) -- { -- // higher half of 'c' is zero -- // then higher half of 'a' is zero too (look at the asserts at the beginning - 'a' is smaller than 'c') -- uint_ a_, b_, res_, temp1, temp2; -- -- a_.u = a; -- b_.u = b; -- -- temp1.u_.high = a_.u_.low; -- temp1.u_.low = b_.u_.high; -- -- res_.u_.high = (unsigned int)(temp1.u / c); -- temp2.u_.high = (unsigned int)(temp1.u % c); -- temp2.u_.low = b_.u_.low; -- -- res_.u_.low = (unsigned int)(temp2.u / c); -- *rest = temp2.u % c; -- -- *r = res_.u; -- } -- else -- { -- return DivTwoWords2(a, b, c, r, rest); -- } -- -- #endif -- } -- -- --#ifdef TTMATH_PLATFORM64 -- -- -- /*! -- this method is available only on 64bit platforms -- -- the same algorithm like the third division algorithm in ttmathuint.h -- but now with the radix=2^32 -- */ -- template -- void UInt::DivTwoWords2(uint a, uint b, uint c, uint * r, uint * rest) -- { -- // a is not zero -- // c_.u_.high is not zero -- -- uint_ a_, b_, c_, u_, q_; -- unsigned int u3; // 32 bit -- -- a_.u = a; -- b_.u = b; -- c_.u = c; -- -- // normalizing -- uint d = DivTwoWordsNormalize(a_, b_, c_); -- -- // loop from j=1 to j=0 -- // the first step (for j=2) is skipped because our result is only in one word, -- // (first 'q' were 0 and nothing would be changed) -- u_.u_.high = a_.u_.high; -- u_.u_.low = a_.u_.low; -- u3 = b_.u_.high; -- q_.u_.high = DivTwoWordsCalculate(u_, u3, c_); -- MultiplySubtract(u_, u3, q_.u_.high, c_); -- -- u_.u_.high = u_.u_.low; -- u_.u_.low = u3; -- u3 = b_.u_.low; -- q_.u_.low = DivTwoWordsCalculate(u_, u3, c_); -- MultiplySubtract(u_, u3, q_.u_.low, c_); -- -- *r = q_.u; -- -- // unnormalizing for the remainder -- u_.u_.high = u_.u_.low; -- u_.u_.low = u3; -- *rest = DivTwoWordsUnnormalize(u_.u, d); -- } -- -- -- -- -- template -- uint UInt::DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_) -- { -- uint d = 0; -- -- for( ; (c_.u & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d ) -- { -- c_.u = c_.u << 1; -- -- uint bc = b_.u & TTMATH_UINT_HIGHEST_BIT; // carry from 'b' -- -- b_.u = b_.u << 1; -- a_.u = a_.u << 1; // carry bits from 'a' are simply skipped -- -- if( bc ) -- a_.u = a_.u | 1; -- } -- -- return d; -- } -- -- -- template -- uint UInt::DivTwoWordsUnnormalize(uint u, uint d) -- { -- if( d == 0 ) -- return u; -- -- u = u >> d; -- -- return u; -- } -- -- -- template -- unsigned int UInt::DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_) -- { -- bool next_test; -- uint_ qp_, rp_, temp_; -- -- qp_.u = u_.u / uint(v_.u_.high); -- rp_.u = u_.u % uint(v_.u_.high); -- -- TTMATH_ASSERT( qp_.u_.high==0 || qp_.u_.high==1 ) -- -- do -- { -- bool decrease = false; -- -- if( qp_.u_.high == 1 ) -- decrease = true; -- else -- { -- temp_.u_.high = rp_.u_.low; -- temp_.u_.low = u3; -- -- if( qp_.u * uint(v_.u_.low) > temp_.u ) -- decrease = true; -- } -- -- next_test = false; -- -- if( decrease ) -- { -- --qp_.u; -- rp_.u += v_.u_.high; -- -- if( rp_.u_.high == 0 ) -- next_test = true; -- } -- } -- while( next_test ); -- -- return qp_.u_.low; -- } -- -- -- template -- void UInt::MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_) -- { -- uint_ temp_; -- -- uint res_high; -- uint res_low; -- -- MulTwoWords(v_.u, q, &res_high, &res_low); -- -- uint_ sub_res_high_; -- uint_ sub_res_low_; -- -- temp_.u_.high = u_.u_.low; -- temp_.u_.low = u3; -- -- uint c = SubTwoWords(temp_.u, res_low, 0, &sub_res_low_.u); -- -- temp_.u_.high = 0; -- temp_.u_.low = u_.u_.high; -- c = SubTwoWords(temp_.u, res_high, c, &sub_res_high_.u); -- -- if( c ) -- { -- --q; -- -- c = AddTwoWords(sub_res_low_.u, v_.u, 0, &sub_res_low_.u); -- AddTwoWords(sub_res_high_.u, 0, c, &sub_res_high_.u); -- } -- -- u_.u_.high = sub_res_high_.u_.low; -- u_.u_.low = sub_res_low_.u_.high; -- u3 = sub_res_low_.u_.low; -- } -- --#endif // #ifdef TTMATH_PLATFORM64 -- -- -- --} //namespace -- -- --#endif //ifdef TTMATH_NOASM --#endif -- -- -- -- -diff --git a/extern/ttmath/ttmathuint_x86.h b/extern/ttmath/ttmathuint_x86.h -deleted file mode 100644 -index 1dd087f524..0000000000 ---- a/extern/ttmath/ttmathuint_x86.h -+++ /dev/null -@@ -1,1602 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2009, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- -- --#ifndef headerfilettmathuint_x86 --#define headerfilettmathuint_x86 -- -- --#ifndef TTMATH_NOASM --#ifdef TTMATH_PLATFORM32 -- -- --/*! -- \file ttmathuint_x86.h -- \brief template class UInt with assembler code for 32bit x86 processors -- -- this file is included at the end of ttmathuint.h --*/ -- -- -- --/*! -- \brief a namespace for the TTMath library --*/ --namespace ttmath --{ -- -- /*! -- returning the string represents the currect type of the library -- we have following types: -- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) -- asm_gcc_32 - with asm code designed for GCC (32 bits) -- asm_vc_64 - with asm for VC (64 bit) -- asm_gcc_64 - with asm for GCC (64 bit) -- no_asm_32 - pure C++ version (32 bit) - without any asm code -- no_asm_64 - pure C++ version (64 bit) - without any asm code -- */ -- template -- const char * UInt::LibTypeStr() -- { -- #ifndef __GNUC__ -- static const char info[] = "asm_vc_32"; -- #endif -- -- #ifdef __GNUC__ -- static const char info[] = "asm_gcc_32"; -- #endif -- -- return info; -- } -- -- -- /*! -- returning the currect type of the library -- */ -- template -- LibTypeCode UInt::LibType() -- { -- #ifndef __GNUC__ -- LibTypeCode info = asm_vc_32; -- #endif -- -- #ifdef __GNUC__ -- LibTypeCode info = asm_gcc_32; -- #endif -- -- return info; -- } -- -- -- -- /*! -- * -- * basic mathematic functions -- * -- */ -- -- -- /*! -- adding ss2 to the this and adding carry if it's defined -- (this = this + ss2 + c) -- -- c must be zero or one (might be a bigger value than 1) -- function returns carry (1) (if it has been) -- */ -- template -- uint UInt::Add(const UInt & ss2, uint c) -- { -- uint b = value_size; -- uint * p1 = table; -- uint * p2 = const_cast(ss2.table); -- -- // we don't have to use TTMATH_REFERENCE_ASSERT here -- // this algorithm doesn't require it -- -- #ifndef __GNUC__ -- -- // this part might be compiled with for example visual c -- -- __asm -- { -- push eax -- push ebx -- push ecx -- push edx -- push esi -- -- mov ecx,[b] -- -- mov ebx,[p1] -- mov esi,[p2] -- -- xor edx,edx // edx=0 -- mov eax,[c] -- neg eax // CF=1 if rax!=0 , CF=0 if rax==0 -- -- ttmath_loop: -- mov eax,[esi+edx*4] -- adc [ebx+edx*4],eax -- -- inc edx -- dec ecx -- jnz ttmath_loop -- -- adc ecx, ecx -- mov [c], ecx -- -- pop esi -- pop edx -- pop ecx -- pop ebx -- pop eax -- } -- -- -- -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- // this part should be compiled with gcc -- -- __asm__ __volatile__( -- -- "xorl %%edx, %%edx \n" -- "negl %%eax \n" // CF=1 if rax!=0 , CF=0 if rax==0 -- -- "1: \n" -- "movl (%%esi,%%edx,4), %%eax \n" -- "adcl %%eax, (%%ebx,%%edx,4) \n" -- -- "incl %%edx \n" -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "adc %%ecx, %%ecx \n" -- -- : "=c" (c), "=a" (dummy), "=d" (dummy2) -- : "0" (b), "1" (c), "b" (p1), "S" (p2) -- : "cc", "memory" ); -- #endif -- -- TTMATH_LOGC("UInt::Add", c) -- -- return c; -- } -- -- -- -- /*! -- adding one word (at a specific position) -- and returning a carry (if it has been) -- -- e.g. -- -- if we've got (value_size=3): -- table[0] = 10; -- table[1] = 30; -- table[2] = 5; -- and we call: -- AddInt(2,1) -- then it'll be: -- table[0] = 10; -- table[1] = 30 + 2; -- table[2] = 5; -- -- of course if there was a carry from table[2] it would be returned -- */ -- template -- uint UInt::AddInt(uint value, uint index) -- { -- uint b = value_size; -- uint * p1 = table; -- uint c; -- -- TTMATH_ASSERT( index < value_size ) -- -- #ifndef __GNUC__ -- -- __asm -- { -- push eax -- push ebx -- push ecx -- push edx -- -- mov ecx, [b] -- sub ecx, [index] -- -- mov edx, [index] -- mov ebx, [p1] -- -- mov eax, [value] -- -- ttmath_loop: -- add [ebx+edx*4], eax -- jnc ttmath_end -- -- mov eax, 1 -- inc edx -- dec ecx -- jnz ttmath_loop -- -- ttmath_end: -- setc al -- movzx edx, al -- mov [c], edx -- -- pop edx -- pop ecx -- pop ebx -- pop eax -- } -- -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "subl %%edx, %%ecx \n" -- -- "1: \n" -- "addl %%eax, (%%ebx,%%edx,4) \n" -- "jnc 2f \n" -- -- "movl $1, %%eax \n" -- "incl %%edx \n" -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "2: \n" -- "setc %%al \n" -- "movzx %%al, %%edx \n" -- -- : "=d" (c), "=a" (dummy), "=c" (dummy2) -- : "0" (index), "1" (value), "2" (b), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::AddInt", c) -- -- return c; -- } -- -- -- -- -- /*! -- adding only two unsigned words to the existing value -- and these words begin on the 'index' position -- (it's used in the multiplication algorithm 2) -- -- index should be equal or smaller than value_size-2 (index <= value_size-2) -- x1 - lower word, x2 - higher word -- -- for example if we've got value_size equal 4 and: -- table[0] = 3 -- table[1] = 4 -- table[2] = 5 -- table[3] = 6 -- then let -- x1 = 10 -- x2 = 20 -- and -- index = 1 -- -- the result of this method will be: -- table[0] = 3 -- table[1] = 4 + x1 = 14 -- table[2] = 5 + x2 = 25 -- table[3] = 6 -- -- and no carry at the end of table[3] -- -- (of course if there was a carry in table[2](5+20) then -- this carry would be passed to the table[3] etc.) -- */ -- template -- uint UInt::AddTwoInts(uint x2, uint x1, uint index) -- { -- uint b = value_size; -- uint * p1 = table; -- uint c; -- -- TTMATH_ASSERT( index < value_size - 1 ) -- -- #ifndef __GNUC__ -- __asm -- { -- push eax -- push ebx -- push ecx -- push edx -- -- mov ecx, [b] -- sub ecx, [index] -- -- mov ebx, [p1] -- mov edx, [index] -- -- mov eax, [x1] -- add [ebx+edx*4], eax -- inc edx -- dec ecx -- -- mov eax, [x2] -- -- ttmath_loop: -- adc [ebx+edx*4], eax -- jnc ttmath_end -- -- mov eax, 0 -- inc edx -- dec ecx -- jnz ttmath_loop -- -- ttmath_end: -- setc al -- movzx edx, al -- mov [c], edx -- -- pop edx -- pop ecx -- pop ebx -- pop eax -- -- } -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "subl %%edx, %%ecx \n" -- -- "addl %%esi, (%%ebx,%%edx,4) \n" -- "incl %%edx \n" -- "decl %%ecx \n" -- -- "1: \n" -- "adcl %%eax, (%%ebx,%%edx,4) \n" -- "jnc 2f \n" -- -- "mov $0, %%eax \n" -- "incl %%edx \n" -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "2: \n" -- "setc %%al \n" -- "movzx %%al, %%eax \n" -- -- : "=a" (c), "=c" (dummy), "=d" (dummy2) -- : "0" (x2), "1" (b), "2" (index), "b" (p1), "S" (x1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::AddTwoInts", c) -- -- return c; -- } -- -- -- -- /*! -- this static method addes one vector to the other -- 'ss1' is larger in size or equal to 'ss2' -- -- ss1 points to the first (larger) vector -- ss2 points to the second vector -- ss1_size - size of the ss1 (and size of the result too) -- ss2_size - size of the ss2 -- result - is the result vector (which has size the same as ss1: ss1_size) -- -- Example: ss1_size is 5, ss2_size is 3 -- ss1: ss2: result (output): -- 5 1 5+1 -- 4 3 4+3 -- 2 7 2+7 -- 6 6 -- 9 9 -- of course the carry is propagated and will be returned from the last item -- (this method is used by the Karatsuba multiplication algorithm) -- */ -- template -- uint UInt::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) -- { -- TTMATH_ASSERT( ss1_size >= ss2_size ) -- -- uint rest = ss1_size - ss2_size; -- uint c; -- -- #ifndef __GNUC__ -- -- // this part might be compiled with for example visual c -- __asm -- { -- pushad -- -- mov ecx, [ss2_size] -- xor edx, edx // edx = 0, cf = 0 -- -- mov esi, [ss1] -- mov ebx, [ss2] -- mov edi, [result] -- -- ttmath_loop: -- mov eax, [esi+edx*4] -- adc eax, [ebx+edx*4] -- mov [edi+edx*4], eax -- -- inc edx -- dec ecx -- jnz ttmath_loop -- -- adc ecx, ecx // ecx has the cf state -- -- mov ebx, [rest] -- or ebx, ebx -- jz ttmath_end -- -- xor ebx, ebx // ebx = 0 -- neg ecx // setting cf from ecx -- mov ecx, [rest] // ecx is != 0 -- -- ttmath_loop2: -- mov eax, [esi+edx*4] -- adc eax, ebx -- mov [edi+edx*4], eax -- -- inc edx -- dec ecx -- jnz ttmath_loop2 -- -- adc ecx, ecx -- -- ttmath_end: -- mov [c], ecx -- -- popad -- } -- -- #endif -- -- -- #ifdef __GNUC__ -- -- // this part should be compiled with gcc -- uint dummy1, dummy2, dummy3; -- -- __asm__ __volatile__( -- "push %%edx \n" -- "xor %%edx, %%edx \n" // edx = 0, cf = 0 -- "1: \n" -- "mov (%%esi,%%edx,4), %%eax \n" -- "adc (%%ebx,%%edx,4), %%eax \n" -- "mov %%eax, (%%edi,%%edx,4) \n" -- -- "inc %%edx \n" -- "dec %%ecx \n" -- "jnz 1b \n" -- -- "adc %%ecx, %%ecx \n" // ecx has the cf state -- "pop %%eax \n" // eax = rest -- -- "or %%eax, %%eax \n" -- "jz 3f \n" -- -- "xor %%ebx, %%ebx \n" // ebx = 0 -- "neg %%ecx \n" // setting cf from ecx -- "mov %%eax, %%ecx \n" // ecx=rest and is != 0 -- "2: \n" -- "mov (%%esi, %%edx, 4), %%eax \n" -- "adc %%ebx, %%eax \n" -- "mov %%eax, (%%edi, %%edx, 4) \n" -- -- "inc %%edx \n" -- "dec %%ecx \n" -- "jnz 2b \n" -- -- "adc %%ecx, %%ecx \n" -- "3: \n" -- -- : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3) -- : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size) -- -- return c; -- } -- -- -- /*! -- subtracting ss2 from the 'this' and subtracting -- carry if it has been defined -- (this = this - ss2 - c) -- -- c must be zero or one (might be a bigger value than 1) -- function returns carry (1) (if it has been) -- */ -- template -- uint UInt::Sub(const UInt & ss2, uint c) -- { -- uint b = value_size; -- uint * p1 = table; -- uint * p2 = const_cast(ss2.table); -- -- // we don't have to use TTMATH_REFERENCE_ASSERT here -- // this algorithm doesn't require it -- -- #ifndef __GNUC__ -- -- __asm -- { -- push eax -- push ebx -- push ecx -- push edx -- push esi -- -- mov ecx,[b] -- -- mov ebx,[p1] -- mov esi,[p2] -- -- xor edx,edx // edx=0 -- mov eax,[c] -- neg eax // CF=1 if rax!=0 , CF=0 if rax==0 -- -- ttmath_loop: -- mov eax,[esi+edx*4] -- sbb [ebx+edx*4],eax -- -- inc edx -- dec ecx -- jnz ttmath_loop -- -- adc ecx, ecx -- mov [c], ecx -- -- pop esi -- pop edx -- pop ecx -- pop ebx -- pop eax -- } -- -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "xorl %%edx, %%edx \n" -- "negl %%eax \n" // CF=1 if rax!=0 , CF=0 if rax==0 -- -- "1: \n" -- "movl (%%esi,%%edx,4), %%eax \n" -- "sbbl %%eax, (%%ebx,%%edx,4) \n" -- -- "incl %%edx \n" -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "adc %%ecx, %%ecx \n" -- -- : "=c" (c), "=a" (dummy), "=d" (dummy2) -- : "0" (b), "1" (c), "b" (p1), "S" (p2) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Sub", c) -- -- return c; -- } -- -- -- -- -- /*! -- this method subtracts one word (at a specific position) -- and returns a carry (if it was) -- -- e.g. -- -- if we've got (value_size=3): -- table[0] = 10; -- table[1] = 30; -- table[2] = 5; -- and we call: -- SubInt(2,1) -- then it'll be: -- table[0] = 10; -- table[1] = 30 - 2; -- table[2] = 5; -- -- of course if there was a carry from table[2] it would be returned -- */ -- template -- uint UInt::SubInt(uint value, uint index) -- { -- uint b = value_size; -- uint * p1 = table; -- uint c; -- -- TTMATH_ASSERT( index < value_size ) -- -- #ifndef __GNUC__ -- -- __asm -- { -- push eax -- push ebx -- push ecx -- push edx -- -- mov ecx, [b] -- sub ecx, [index] -- -- mov edx, [index] -- mov ebx, [p1] -- -- mov eax, [value] -- -- ttmath_loop: -- sub [ebx+edx*4], eax -- jnc ttmath_end -- -- mov eax, 1 -- inc edx -- dec ecx -- jnz ttmath_loop -- -- ttmath_end: -- setc al -- movzx edx, al -- mov [c], edx -- -- pop edx -- pop ecx -- pop ebx -- pop eax -- } -- -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "subl %%edx, %%ecx \n" -- -- "1: \n" -- "subl %%eax, (%%ebx,%%edx,4) \n" -- "jnc 2f \n" -- -- "movl $1, %%eax \n" -- "incl %%edx \n" -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "2: \n" -- "setc %%al \n" -- "movzx %%al, %%edx \n" -- -- : "=d" (c), "=a" (dummy), "=c" (dummy2) -- : "0" (index), "1" (value), "2" (b), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::SubInt", c) -- -- return c; -- } -- -- -- -- /*! -- this static method subtractes one vector from the other -- 'ss1' is larger in size or equal to 'ss2' -- -- ss1 points to the first (larger) vector -- ss2 points to the second vector -- ss1_size - size of the ss1 (and size of the result too) -- ss2_size - size of the ss2 -- result - is the result vector (which has size the same as ss1: ss1_size) -- -- Example: ss1_size is 5, ss2_size is 3 -- ss1: ss2: result (output): -- 5 1 5-1 -- 4 3 4-3 -- 2 7 2-7 -- 6 6-1 (the borrow from previous item) -- 9 9 -- return (carry): 0 -- of course the carry (borrow) is propagated and will be returned from the last item -- (this method is used by the Karatsuba multiplication algorithm) -- */ -- template -- uint UInt::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) -- { -- TTMATH_ASSERT( ss1_size >= ss2_size ) -- -- uint rest = ss1_size - ss2_size; -- uint c; -- -- #ifndef __GNUC__ -- -- // this part might be compiled with for example visual c -- -- /* -- the asm code is nearly the same as in AddVector -- only two instructions 'adc' are changed to 'sbb' -- */ -- __asm -- { -- pushad -- -- mov ecx, [ss2_size] -- xor edx, edx // edx = 0, cf = 0 -- -- mov esi, [ss1] -- mov ebx, [ss2] -- mov edi, [result] -- -- ttmath_loop: -- mov eax, [esi+edx*4] -- sbb eax, [ebx+edx*4] -- mov [edi+edx*4], eax -- -- inc edx -- dec ecx -- jnz ttmath_loop -- -- adc ecx, ecx // ecx has the cf state -- -- mov ebx, [rest] -- or ebx, ebx -- jz ttmath_end -- -- xor ebx, ebx // ebx = 0 -- neg ecx // setting cf from ecx -- mov ecx, [rest] // ecx is != 0 -- -- ttmath_loop2: -- mov eax, [esi+edx*4] -- sbb eax, ebx -- mov [edi+edx*4], eax -- -- inc edx -- dec ecx -- jnz ttmath_loop2 -- -- adc ecx, ecx -- -- ttmath_end: -- mov [c], ecx -- -- popad -- } -- -- #endif -- -- -- #ifdef __GNUC__ -- -- // this part should be compiled with gcc -- uint dummy1, dummy2, dummy3; -- -- __asm__ __volatile__( -- "push %%edx \n" -- "xor %%edx, %%edx \n" // edx = 0, cf = 0 -- "1: \n" -- "mov (%%esi,%%edx,4), %%eax \n" -- "sbb (%%ebx,%%edx,4), %%eax \n" -- "mov %%eax, (%%edi,%%edx,4) \n" -- -- "inc %%edx \n" -- "dec %%ecx \n" -- "jnz 1b \n" -- -- "adc %%ecx, %%ecx \n" // ecx has the cf state -- "pop %%eax \n" // eax = rest -- -- "or %%eax, %%eax \n" -- "jz 3f \n" -- -- "xor %%ebx, %%ebx \n" // ebx = 0 -- "neg %%ecx \n" // setting cf from ecx -- "mov %%eax, %%ecx \n" // ecx=rest and is != 0 -- "2: \n" -- "mov (%%esi, %%edx, 4), %%eax \n" -- "sbb %%ebx, %%eax \n" -- "mov %%eax, (%%edi, %%edx, 4) \n" -- -- "inc %%edx \n" -- "dec %%ecx \n" -- "jnz 2b \n" -- -- "adc %%ecx, %%ecx \n" -- "3: \n" -- -- : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3) -- : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size) -- -- return c; -- } -- -- -- -- /*! -- this method moves all bits into the left hand side -- return value <- this <- c -- -- the lowest *bit* will be held the 'c' and -- the state of one additional bit (on the left hand side) -- will be returned -- -- for example: -- let this is 001010000 -- after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0 -- */ -- template -- uint UInt::Rcl2_one(uint c) -- { -- uint b = value_size; -- uint * p1 = table; -- -- #ifndef __GNUC__ -- __asm -- { -- push ebx -- push ecx -- push edx -- -- mov ebx, [p1] -- xor edx, edx -- mov ecx, [c] -- neg ecx -- mov ecx, [b] -- -- ttmath_loop: -- rcl dword ptr [ebx+edx*4], 1 -- -- inc edx -- dec ecx -- jnz ttmath_loop -- -- adc ecx, ecx -- mov [c], ecx -- -- pop edx -- pop ecx -- pop ebx -- } -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "xorl %%edx, %%edx \n" // edx=0 -- "negl %%eax \n" // CF=1 if eax!=0 , CF=0 if eax==0 -- -- "1: \n" -- "rcll $1, (%%ebx, %%edx, 4) \n" -- -- "incl %%edx \n" -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "adcl %%ecx, %%ecx \n" -- -- : "=c" (c), "=a" (dummy), "=d" (dummy2) -- : "0" (b), "1" (c), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Rcl2_one", c) -- -- return c; -- } -- -- -- -- /*! -- this method moves all bits into the right hand side -- c -> this -> return value -- -- the highest *bit* will be held the 'c' and -- the state of one additional bit (on the right hand side) -- will be returned -- -- for example: -- let this is 000000010 -- after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0 -- */ -- template -- uint UInt::Rcr2_one(uint c) -- { -- uint b = value_size; -- uint * p1 = table; -- -- #ifndef __GNUC__ -- __asm -- { -- push ebx -- push ecx -- -- mov ebx, [p1] -- mov ecx, [c] -- neg ecx -- mov ecx, [b] -- -- ttmath_loop: -- rcr dword ptr [ebx+ecx*4-4], 1 -- -- dec ecx -- jnz ttmath_loop -- -- adc ecx, ecx -- mov [c], ecx -- -- pop ecx -- pop ebx -- } -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy; -- -- __asm__ __volatile__( -- -- "negl %%eax \n" // CF=1 if eax!=0 , CF=0 if eax==0 -- -- "1: \n" -- "rcrl $1, -4(%%ebx, %%ecx, 4) \n" -- -- "decl %%ecx \n" -- "jnz 1b \n" -- -- "adcl %%ecx, %%ecx \n" -- -- : "=c" (c), "=a" (dummy) -- : "0" (b), "1" (c), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Rcr2_one", c) -- -- return c; -- } -- -- -- --#ifdef _MSC_VER --#pragma warning (disable : 4731) --//warning C4731: frame pointer register 'ebp' modified by inline assembly code --#endif -- -- -- -- /*! -- this method moves all bits into the left hand side -- return value <- this <- c -- -- the lowest *bits* will be held the 'c' and -- the state of one additional bit (on the left hand side) -- will be returned -- -- for example: -- let this is 001010000 -- after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1 -- */ -- template -- uint UInt::Rcl2(uint bits, uint c) -- { -- TTMATH_ASSERT( bits>0 && bits edx -> cf) (cl times) -- "movl %%edx, %%ebp \n" // ebp = edx = mask -- "movl %%esi, %%ecx \n" -- -- "xorl %%edx, %%edx \n" -- "movl %%edx, %%esi \n" -- "orl %%eax, %%eax \n" -- "cmovnz %%ebp, %%esi \n" // if(c) esi=mask else esi=0 -- -- "1: \n" -- "roll %%cl, (%%ebx,%%edx,4) \n" -- -- "movl (%%ebx,%%edx,4), %%eax \n" -- "andl %%ebp, %%eax \n" -- "xorl %%eax, (%%ebx,%%edx,4) \n" -- "orl %%esi, (%%ebx,%%edx,4) \n" -- "movl %%eax, %%esi \n" -- -- "incl %%edx \n" -- "decl %%edi \n" -- "jnz 1b \n" -- -- "and $1, %%eax \n" -- -- "pop %%ebp \n" -- -- : "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3) -- : "0" (c), "1" (b), "b" (p1), "c" (bits) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Rcl2", c) -- -- return c; -- } -- -- -- -- -- /*! -- this method moves all bits into the right hand side -- C -> this -> return value -- -- the highest *bits* will be held the 'c' and -- the state of one additional bit (on the right hand side) -- will be returned -- -- for example: -- let this is 000000010 -- after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1 -- */ -- template -- uint UInt::Rcr2(uint bits, uint c) -- { -- TTMATH_ASSERT( bits>0 && bits -- sint UInt::FindLeadingBitInWord(uint x) -- { -- sint result; -- -- #ifndef __GNUC__ -- __asm -- { -- push eax -- push edx -- -- mov edx,-1 -- bsr eax,[x] -- cmovz eax,edx -- mov [result], eax -- -- pop edx -- pop eax -- } -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy; -- -- __asm__ ( -- -- "movl $-1, %1 \n" -- "bsrl %2, %0 \n" -- "cmovz %1, %0 \n" -- -- : "=r" (result), "=&r" (dummy) -- : "r" (x) -- : "cc" ); -- -- #endif -- -- return result; -- } -- -- -- -- /* -- this method returns the number of the smallest set bit in one 32-bit word -- if the 'x' is zero this method returns '-1' -- */ -- template -- sint UInt::FindLowestBitInWord(uint x) -- { -- sint result; -- -- #ifndef __GNUC__ -- __asm -- { -- push eax -- push edx -- -- mov edx,-1 -- bsf eax,[x] -- cmovz eax,edx -- mov [result], eax -- -- pop edx -- pop eax -- } -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy; -- -- __asm__ ( -- -- "movl $-1, %1 \n" -- "bsfl %2, %0 \n" -- "cmovz %1, %0 \n" -- -- : "=r" (result), "=&r" (dummy) -- : "r" (x) -- : "cc" ); -- -- #endif -- -- return result; -- } -- -- -- -- /*! -- this method sets a special bit in the 'value' -- and returns the last state of the bit (zero or one) -- -- bit is from <0,31> -- e.g. -- uint x = 100; -- uint bit = SetBitInWord(x, 3); -- now: x = 108 and bit = 0 -- */ -- template -- uint UInt::SetBitInWord(uint & value, uint bit) -- { -- TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT ) -- -- uint old_bit; -- uint v = value; -- -- #ifndef __GNUC__ -- __asm -- { -- push ebx -- push eax -- -- mov eax, [v] -- mov ebx, [bit] -- bts eax, ebx -- mov [v], eax -- -- setc bl -- movzx ebx, bl -- mov [old_bit], ebx -- -- pop eax -- pop ebx -- } -- #endif -- -- -- #ifdef __GNUC__ -- __asm__ ( -- -- "btsl %%ebx, %%eax \n" -- "setc %%bl \n" -- "movzx %%bl, %%ebx \n" -- -- : "=a" (v), "=b" (old_bit) -- : "0" (v), "1" (bit) -- : "cc" ); -- -- #endif -- -- value = v; -- -- return old_bit; -- } -- -- -- -- -- /*! -- multiplication: result_high:result_low = a * b -- result_high - higher word of the result -- result_low - lower word of the result -- -- this methos never returns a carry -- this method is used in the second version of the multiplication algorithms -- */ -- template -- void UInt::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low) -- { -- /* -- we must use these temporary variables in order to inform the compilator -- that value pointed with result1 and result2 has changed -- -- this has no effect in visual studio but it's useful when -- using gcc and options like -Ox -- */ -- uint result1_; -- uint result2_; -- -- #ifndef __GNUC__ -- -- __asm -- { -- push eax -- push edx -- -- mov eax, [a] -- mul dword ptr [b] -- -- mov [result2_], edx -- mov [result1_], eax -- -- pop edx -- pop eax -- } -- -- #endif -- -- -- #ifdef __GNUC__ -- -- __asm__ ( -- -- "mull %%edx \n" -- -- : "=a" (result1_), "=d" (result2_) -- : "0" (a), "1" (b) -- : "cc" ); -- -- #endif -- -- -- *result_low = result1_; -- *result_high = result2_; -- } -- -- -- -- -- -- /*! -- * -- * Division -- * -- * -- */ -- -- -- -- -- /*! -- this method calculates 64bits word a:b / 32bits c (a higher, b lower word) -- r = a:b / c and rest - remainder -- -- * -- * WARNING: -- * if r (one word) is too small for the result or c is equal zero -- * there'll be a hardware interruption (0) -- * and probably the end of your program -- * -- */ -- template -- void UInt::DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest) -- { -- uint r_; -- uint rest_; -- /* -- these variables have similar meaning like those in -- the multiplication algorithm MulTwoWords -- */ -- -- TTMATH_ASSERT( c != 0 ) -- -- #ifndef __GNUC__ -- __asm -- { -- push eax -- push edx -- -- mov edx, [a] -- mov eax, [b] -- div dword ptr [c] -- -- mov [r_], eax -- mov [rest_], edx -- -- pop edx -- pop eax -- } -- #endif -- -- -- #ifdef __GNUC__ -- -- __asm__ ( -- -- "divl %%ecx \n" -- -- : "=a" (r_), "=d" (rest_) -- : "0" (b), "1" (a), "c" (c) -- : "cc" ); -- -- #endif -- -- -- *r = r_; -- *rest = rest_; -- -- } -- -- -- --} //namespace -- -- -- --#endif //ifdef TTMATH_PLATFORM32 --#endif //ifndef TTMATH_NOASM --#endif -diff --git a/extern/ttmath/ttmathuint_x86_64.h b/extern/ttmath/ttmathuint_x86_64.h -deleted file mode 100644 -index 188fc5e7bd..0000000000 ---- a/extern/ttmath/ttmathuint_x86_64.h -+++ /dev/null -@@ -1,1146 +0,0 @@ --/* -- * This file is a part of TTMath Bignum Library -- * and is distributed under the (new) BSD licence. -- * Author: Tomasz Sowa -- */ -- --/* -- * Copyright (c) 2006-2010, Tomasz Sowa -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions are met: -- * -- * * Redistributions of source code must retain the above copyright notice, -- * this list of conditions and the following disclaimer. -- * -- * * Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * * Neither the name Tomasz Sowa nor the names of contributors to this -- * project may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -- * THE POSSIBILITY OF SUCH DAMAGE. -- */ -- -- --#ifndef headerfilettmathuint_x86_64 --#define headerfilettmathuint_x86_64 -- -- --#ifndef TTMATH_NOASM --#ifdef TTMATH_PLATFORM64 -- -- --/*! -- \file ttmathuint_x86_64.h -- \brief template class UInt with assembler code for 64bit x86_64 processors -- -- this file is included at the end of ttmathuint.h --*/ -- --#ifndef __GNUC__ --#include --#endif -- -- --namespace ttmath --{ -- -- #ifndef __GNUC__ -- -- extern "C" -- { -- uint __fastcall ttmath_adc_x64(uint* p1, const uint* p2, uint nSize, uint c); -- uint __fastcall ttmath_addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue); -- uint __fastcall ttmath_addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2); -- uint __fastcall ttmath_addvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result); -- uint __fastcall ttmath_sbb_x64(uint* p1, const uint* p2, uint nSize, uint c); -- uint __fastcall ttmath_subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue); -- uint __fastcall ttmath_subvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result); -- uint __fastcall ttmath_rcl_x64(uint* p1, uint nSize, uint nLowestBit); -- uint __fastcall ttmath_rcr_x64(uint* p1, uint nSize, uint nLowestBit); -- uint __fastcall ttmath_div_x64(uint* pnValHi, uint* pnValLo, uint nDiv); -- uint __fastcall ttmath_rcl2_x64(uint* p1, uint nSize, uint nBits, uint c); -- uint __fastcall ttmath_rcr2_x64(uint* p1, uint nSize, uint nBits, uint c); -- }; -- #endif -- -- -- /*! -- returning the string represents the currect type of the library -- we have following types: -- asm_vc_32 - with asm code designed for Microsoft Visual C++ (32 bits) -- asm_gcc_32 - with asm code designed for GCC (32 bits) -- asm_vc_64 - with asm for VC (64 bit) -- asm_gcc_64 - with asm for GCC (64 bit) -- no_asm_32 - pure C++ version (32 bit) - without any asm code -- no_asm_64 - pure C++ version (64 bit) - without any asm code -- */ -- template -- const char * UInt::LibTypeStr() -- { -- #ifndef __GNUC__ -- static const char info[] = "asm_vc_64"; -- #endif -- -- #ifdef __GNUC__ -- static const char info[] = "asm_gcc_64"; -- #endif -- -- return info; -- } -- -- -- /*! -- returning the currect type of the library -- */ -- template -- LibTypeCode UInt::LibType() -- { -- #ifndef __GNUC__ -- LibTypeCode info = asm_vc_64; -- #endif -- -- #ifdef __GNUC__ -- LibTypeCode info = asm_gcc_64; -- #endif -- -- return info; -- } -- -- -- /*! -- * -- * basic mathematic functions -- * -- */ -- -- -- -- /*! -- this method adding ss2 to the this and adding carry if it's defined -- (this = this + ss2 + c) -- -- ***this method is created only on a 64bit platform*** -- -- c must be zero or one (might be a bigger value than 1) -- function returns carry (1) (if it was) -- */ -- template -- uint UInt::Add(const UInt & ss2, uint c) -- { -- uint b = value_size; -- uint * p1 = table; -- const uint * p2 = ss2.table; -- -- // we don't have to use TTMATH_REFERENCE_ASSERT here -- // this algorithm doesn't require it -- -- #ifndef __GNUC__ -- c = ttmath_adc_x64(p1,p2,b,c); -- #endif -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- /* -- this part should be compiled with gcc -- */ -- __asm__ __volatile__( -- -- "xorq %%rdx, %%rdx \n" -- "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0 -- -- "1: \n" -- "movq (%%rsi,%%rdx,8), %%rax \n" -- "adcq %%rax, (%%rbx,%%rdx,8) \n" -- -- "incq %%rdx \n" -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "adcq %%rcx, %%rcx \n" -- -- : "=c" (c), "=a" (dummy), "=d" (dummy2) -- : "0" (b), "1" (c), "b" (p1), "S" (p2) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Add", c) -- -- return c; -- } -- -- -- -- /*! -- this method adds one word (at a specific position) -- and returns a carry (if it was) -- -- ***this method is created only on a 64bit platform*** -- -- -- if we've got (value_size=3): -- table[0] = 10; -- table[1] = 30; -- table[2] = 5; -- and we call: -- AddInt(2,1) -- then it'll be: -- table[0] = 10; -- table[1] = 30 + 2; -- table[2] = 5; -- -- of course if there was a carry from table[2] it would be returned -- */ -- template -- uint UInt::AddInt(uint value, uint index) -- { -- uint b = value_size; -- uint * p1 = table; -- uint c; -- -- TTMATH_ASSERT( index < value_size ) -- -- #ifndef __GNUC__ -- c = ttmath_addindexed_x64(p1,b,index,value); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "subq %%rdx, %%rcx \n" -- -- "1: \n" -- "addq %%rax, (%%rbx,%%rdx,8) \n" -- "jnc 2f \n" -- -- "movq $1, %%rax \n" -- "incq %%rdx \n" -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "2: \n" -- "setc %%al \n" -- "movzx %%al, %%rdx \n" -- -- : "=d" (c), "=a" (dummy), "=c" (dummy2) -- : "0" (index), "1" (value), "2" (b), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::AddInt", c) -- -- return c; -- } -- -- -- -- /*! -- this method adds only two unsigned words to the existing value -- and these words begin on the 'index' position -- (it's used in the multiplication algorithm 2) -- -- ***this method is created only on a 64bit platform*** -- -- index should be equal or smaller than value_size-2 (index <= value_size-2) -- x1 - lower word, x2 - higher word -- -- for example if we've got value_size equal 4 and: -- table[0] = 3 -- table[1] = 4 -- table[2] = 5 -- table[3] = 6 -- then let -- x1 = 10 -- x2 = 20 -- and -- index = 1 -- -- the result of this method will be: -- table[0] = 3 -- table[1] = 4 + x1 = 14 -- table[2] = 5 + x2 = 25 -- table[3] = 6 -- -- and no carry at the end of table[3] -- -- (of course if there was a carry in table[2](5+20) then -- this carry would be passed to the table[3] etc.) -- */ -- template -- uint UInt::AddTwoInts(uint x2, uint x1, uint index) -- { -- uint b = value_size; -- uint * p1 = table; -- uint c; -- -- TTMATH_ASSERT( index < value_size - 1 ) -- -- #ifndef __GNUC__ -- c = ttmath_addindexed2_x64(p1,b,index,x1,x2); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "subq %%rdx, %%rcx \n" -- -- "addq %%rsi, (%%rbx,%%rdx,8) \n" -- "incq %%rdx \n" -- "decq %%rcx \n" -- -- "1: \n" -- "adcq %%rax, (%%rbx,%%rdx,8) \n" -- "jnc 2f \n" -- -- "mov $0, %%rax \n" -- "incq %%rdx \n" -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "2: \n" -- "setc %%al \n" -- "movzx %%al, %%rax \n" -- -- : "=a" (c), "=c" (dummy), "=d" (dummy2) -- : "0" (x2), "1" (b), "2" (index), "b" (p1), "S" (x1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::AddTwoInts", c) -- -- return c; -- } -- -- -- -- /*! -- this static method addes one vector to the other -- 'ss1' is larger in size or equal to 'ss2' -- -- ss1 points to the first (larger) vector -- ss2 points to the second vector -- ss1_size - size of the ss1 (and size of the result too) -- ss2_size - size of the ss2 -- result - is the result vector (which has size the same as ss1: ss1_size) -- -- Example: ss1_size is 5, ss2_size is 3 -- ss1: ss2: result (output): -- 5 1 5+1 -- 4 3 4+3 -- 2 7 2+7 -- 6 6 -- 9 9 -- of course the carry is propagated and will be returned from the last item -- (this method is used by the Karatsuba multiplication algorithm) -- */ -- template -- uint UInt::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) -- { -- TTMATH_ASSERT( ss1_size >= ss2_size ) -- -- uint c; -- -- #ifndef __GNUC__ -- c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy1, dummy2, dummy3; -- uint rest = ss1_size - ss2_size; -- -- // this part should be compiled with gcc -- -- __asm__ __volatile__( -- "mov %%rdx, %%r8 \n" -- "xor %%rdx, %%rdx \n" // rdx = 0, cf = 0 -- "1: \n" -- "mov (%%rsi,%%rdx,8), %%rax \n" -- "adc (%%rbx,%%rdx,8), %%rax \n" -- "mov %%rax, (%%rdi,%%rdx,8) \n" -- -- "inc %%rdx \n" -- "dec %%rcx \n" -- "jnz 1b \n" -- -- "adc %%rcx, %%rcx \n" // rcx has the cf state -- -- "or %%r8, %%r8 \n" -- "jz 3f \n" -- -- "xor %%rbx, %%rbx \n" // ebx = 0 -- "neg %%rcx \n" // setting cf from rcx -- "mov %%r8, %%rcx \n" // rcx=rest and is != 0 -- "2: \n" -- "mov (%%rsi, %%rdx, 8), %%rax \n" -- "adc %%rbx, %%rax \n" -- "mov %%rax, (%%rdi, %%rdx, 8) \n" -- -- "inc %%rdx \n" -- "dec %%rcx \n" -- "jnz 2b \n" -- -- "adc %%rcx, %%rcx \n" -- "3: \n" -- -- : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3) -- : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result) -- : "%r8", "cc", "memory" ); -- -- #endif -- -- TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size) -- -- return c; -- } -- -- -- -- /*! -- this method's subtracting ss2 from the 'this' and subtracting -- carry if it has been defined -- (this = this - ss2 - c) -- -- ***this method is created only on a 64bit platform*** -- -- c must be zero or one (might be a bigger value than 1) -- function returns carry (1) (if it was) -- */ -- template -- uint UInt::Sub(const UInt & ss2, uint c) -- { -- uint b = value_size; -- uint * p1 = table; -- const uint * p2 = ss2.table; -- -- // we don't have to use TTMATH_REFERENCE_ASSERT here -- // this algorithm doesn't require it -- -- #ifndef __GNUC__ -- c = ttmath_sbb_x64(p1,p2,b,c); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "xorq %%rdx, %%rdx \n" -- "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0 -- -- "1: \n" -- "movq (%%rsi,%%rdx,8), %%rax \n" -- "sbbq %%rax, (%%rbx,%%rdx,8) \n" -- -- "incq %%rdx \n" -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "adcq %%rcx, %%rcx \n" -- -- : "=c" (c), "=a" (dummy), "=d" (dummy2) -- : "0" (b), "1" (c), "b" (p1), "S" (p2) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Sub", c) -- -- return c; -- } -- -- -- -- /*! -- this method subtracts one word (at a specific position) -- and returns a carry (if it was) -- -- ***this method is created only on a 64bit platform*** -- -- if we've got (value_size=3): -- table[0] = 10; -- table[1] = 30; -- table[2] = 5; -- and we call: -- SubInt(2,1) -- then it'll be: -- table[0] = 10; -- table[1] = 30 - 2; -- table[2] = 5; -- -- of course if there was a carry from table[2] it would be returned -- */ -- template -- uint UInt::SubInt(uint value, uint index) -- { -- uint b = value_size; -- uint * p1 = table; -- uint c; -- -- TTMATH_ASSERT( index < value_size ) -- -- #ifndef __GNUC__ -- c = ttmath_subindexed_x64(p1,b,index,value); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "subq %%rdx, %%rcx \n" -- -- "1: \n" -- "subq %%rax, (%%rbx,%%rdx,8) \n" -- "jnc 2f \n" -- -- "movq $1, %%rax \n" -- "incq %%rdx \n" -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "2: \n" -- "setc %%al \n" -- "movzx %%al, %%rdx \n" -- -- : "=d" (c), "=a" (dummy), "=c" (dummy2) -- : "0" (index), "1" (value), "2" (b), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::SubInt", c) -- -- return c; -- } -- -- -- /*! -- this static method subtractes one vector from the other -- 'ss1' is larger in size or equal to 'ss2' -- -- ss1 points to the first (larger) vector -- ss2 points to the second vector -- ss1_size - size of the ss1 (and size of the result too) -- ss2_size - size of the ss2 -- result - is the result vector (which has size the same as ss1: ss1_size) -- -- Example: ss1_size is 5, ss2_size is 3 -- ss1: ss2: result (output): -- 5 1 5-1 -- 4 3 4-3 -- 2 7 2-7 -- 6 6-1 (the borrow from previous item) -- 9 9 -- return (carry): 0 -- of course the carry (borrow) is propagated and will be returned from the last item -- (this method is used by the Karatsuba multiplication algorithm) -- */ -- template -- uint UInt::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result) -- { -- TTMATH_ASSERT( ss1_size >= ss2_size ) -- -- uint c; -- -- #ifndef __GNUC__ -- c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result); -- #endif -- -- -- #ifdef __GNUC__ -- -- // the asm code is nearly the same as in AddVector -- // only two instructions 'adc' are changed to 'sbb' -- -- uint dummy1, dummy2, dummy3; -- uint rest = ss1_size - ss2_size; -- -- __asm__ __volatile__( -- "mov %%rdx, %%r8 \n" -- "xor %%rdx, %%rdx \n" // rdx = 0, cf = 0 -- "1: \n" -- "mov (%%rsi,%%rdx,8), %%rax \n" -- "sbb (%%rbx,%%rdx,8), %%rax \n" -- "mov %%rax, (%%rdi,%%rdx,8) \n" -- -- "inc %%rdx \n" -- "dec %%rcx \n" -- "jnz 1b \n" -- -- "adc %%rcx, %%rcx \n" // rcx has the cf state -- -- "or %%r8, %%r8 \n" -- "jz 3f \n" -- -- "xor %%rbx, %%rbx \n" // ebx = 0 -- "neg %%rcx \n" // setting cf from rcx -- "mov %%r8, %%rcx \n" // rcx=rest and is != 0 -- "2: \n" -- "mov (%%rsi, %%rdx, 8), %%rax \n" -- "sbb %%rbx, %%rax \n" -- "mov %%rax, (%%rdi, %%rdx, 8) \n" -- -- "inc %%rdx \n" -- "dec %%rcx \n" -- "jnz 2b \n" -- -- "adc %%rcx, %%rcx \n" -- "3: \n" -- -- : "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3) -- : "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result) -- : "%r8", "cc", "memory" ); -- -- #endif -- -- TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size) -- -- return c; -- } -- -- -- /*! -- this method moves all bits into the left hand side -- return value <- this <- c -- -- the lowest *bit* will be held the 'c' and -- the state of one additional bit (on the left hand side) -- will be returned -- -- for example: -- let this is 001010000 -- after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0 -- -- ***this method is created only on a 64bit platform*** -- */ -- template -- uint UInt::Rcl2_one(uint c) -- { -- sint b = value_size; -- uint * p1 = table; -- -- -- #ifndef __GNUC__ -- c = ttmath_rcl_x64(p1,b,c); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy, dummy2; -- -- __asm__ __volatile__( -- -- "xorq %%rdx, %%rdx \n" // rdx=0 -- "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0 -- -- "1: \n" -- "rclq $1, (%%rbx, %%rdx, 8) \n" -- -- "incq %%rdx \n" -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "adcq %%rcx, %%rcx \n" -- -- : "=c" (c), "=a" (dummy), "=d" (dummy2) -- : "0" (b), "1" (c), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Rcl2_one", c) -- -- return c; -- } -- -- -- /*! -- this method moves all bits into the right hand side -- c -> this -> return value -- -- the highest *bit* will be held the 'c' and -- the state of one additional bit (on the right hand side) -- will be returned -- -- for example: -- let this is 000000010 -- after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0 -- -- ***this method is created only on a 64bit platform*** -- */ -- template -- uint UInt::Rcr2_one(uint c) -- { -- sint b = value_size; -- uint * p1 = table; -- -- -- #ifndef __GNUC__ -- c = ttmath_rcr_x64(p1,b,c); -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy; -- -- __asm__ __volatile__( -- -- "negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0 -- -- "1: \n" -- "rcrq $1, -8(%%rbx, %%rcx, 8) \n" -- -- "decq %%rcx \n" -- "jnz 1b \n" -- -- "adcq %%rcx, %%rcx \n" -- -- : "=c" (c), "=a" (dummy) -- : "0" (b), "1" (c), "b" (p1) -- : "cc", "memory" ); -- -- #endif -- -- TTMATH_LOGC("UInt::Rcr2_one", c) -- -- return c; -- } -- -- -- -- /*! -- this method moves all bits into the left hand side -- return value <- this <- c -- -- the lowest *bits* will be held the 'c' and -- the state of one additional bit (on the left hand side) -- will be returned -- -- for example: -- let this is 001010000 -- after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1 -- -- ***this method is created only on a 64bit platform*** -- */ -- template -- uint UInt::Rcl2(uint bits, uint c) -- { -- TTMATH_ASSERT( bits>0 && bits this -> return value -- -- the highest *bits* will be held the 'c' and -- the state of one additional bit (on the right hand side) -- will be returned -- -- for example: -- let this is 000000010 -- after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1 -- -- ***this method is created only on a 64bit platform*** -- */ -- template -- uint UInt::Rcr2(uint bits, uint c) -- { -- TTMATH_ASSERT( bits>0 && bits -- sint UInt::FindLeadingBitInWord(uint x) -- { -- sint result; -- -- -- #ifndef __GNUC__ -- -- unsigned long nIndex = 0; -- -- if( _BitScanReverse64(&nIndex,x) == 0 ) -- result = -1; -- else -- result = nIndex; -- -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy; -- -- __asm__ ( -- -- "movq $-1, %1 \n" -- "bsrq %2, %0 \n" -- "cmovz %1, %0 \n" -- -- : "=r" (result), "=&r" (dummy) -- : "r" (x) -- : "cc" ); -- -- #endif -- -- -- return result; -- } -- -- -- /* -- this method returns the number of the highest set bit in one 64-bit word -- if the 'x' is zero this method returns '-1' -- -- ***this method is created only on a 64bit platform*** -- */ -- template -- sint UInt::FindLowestBitInWord(uint x) -- { -- sint result; -- -- -- #ifndef __GNUC__ -- -- unsigned long nIndex = 0; -- -- if( _BitScanForward64(&nIndex,x) == 0 ) -- result = -1; -- else -- result = nIndex; -- -- #endif -- -- -- #ifdef __GNUC__ -- uint dummy; -- -- __asm__ ( -- -- "movq $-1, %1 \n" -- "bsfq %2, %0 \n" -- "cmovz %1, %0 \n" -- -- : "=r" (result), "=&r" (dummy) -- : "r" (x) -- : "cc" ); -- -- #endif -- -- -- return result; -- } -- -- -- /*! -- this method sets a special bit in the 'value' -- and returns the last state of the bit (zero or one) -- -- ***this method is created only on a 64bit platform*** -- -- bit is from <0,63> -- -- e.g. -- uint x = 100; -- uint bit = SetBitInWord(x, 3); -- now: x = 108 and bit = 0 -- */ -- template -- uint UInt::SetBitInWord(uint & value, uint bit) -- { -- TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT ) -- -- uint old_bit; -- uint v = value; -- -- -- #ifndef __GNUC__ -- old_bit = _bittestandset64((__int64*)&value,bit) != 0; -- #endif -- -- -- #ifdef __GNUC__ -- -- __asm__ ( -- -- "btsq %%rbx, %%rax \n" -- "setc %%bl \n" -- "movzx %%bl, %%rbx \n" -- -- : "=a" (v), "=b" (old_bit) -- : "0" (v), "1" (bit) -- : "cc" ); -- -- #endif -- -- value = v; -- -- return old_bit; -- } -- -- -- /*! -- * -- * Multiplication -- * -- * -- */ -- -- -- /*! -- multiplication: result_high:result_low = a * b -- result_high - higher word of the result -- result_low - lower word of the result -- -- this methos never returns a carry -- this method is used in the second version of the multiplication algorithms -- -- ***this method is created only on a 64bit platform*** -- */ -- template -- void UInt::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low) -- { -- /* -- we must use these temporary variables in order to inform the compilator -- that value pointed with result1 and result2 has changed -- -- this has no effect in visual studio but it's usefull when -- using gcc and options like -O -- */ -- uint result1_; -- uint result2_; -- -- -- #ifndef __GNUC__ -- result1_ = _umul128(a,b,&result2_); -- #endif -- -- -- #ifdef __GNUC__ -- -- __asm__ ( -- -- "mulq %%rdx \n" -- -- : "=a" (result1_), "=d" (result2_) -- : "0" (a), "1" (b) -- : "cc" ); -- -- #endif -- -- -- *result_low = result1_; -- *result_high = result2_; -- } -- -- -- -- -- /*! -- * -- * Division -- * -- * -- */ -- -- -- /*! -- this method calculates 64bits word a:b / 32bits c (a higher, b lower word) -- r = a:b / c and rest - remainder -- -- ***this method is created only on a 64bit platform*** -- -- * -- * WARNING: -- * if r (one word) is too small for the result or c is equal zero -- * there'll be a hardware interruption (0) -- * and probably the end of your program -- * -- */ -- template -- void UInt::DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest) -- { -- uint r_; -- uint rest_; -- /* -- these variables have similar meaning like those in -- the multiplication algorithm MulTwoWords -- */ -- -- TTMATH_ASSERT( c != 0 ) -- -- -- #ifndef __GNUC__ -- -- ttmath_div_x64(&a,&b,c); -- r_ = a; -- rest_ = b; -- -- #endif -- -- -- #ifdef __GNUC__ -- -- __asm__ ( -- -- "divq %%rcx \n" -- -- : "=a" (r_), "=d" (rest_) -- : "d" (a), "a" (b), "c" (c) -- : "cc" ); -- -- #endif -- -- -- *r = r_; -- *rest = rest_; -- } -- --} //namespace -- -- --#endif //ifdef TTMATH_PLATFORM64 --#endif //ifndef TTMATH_NOASM --#endif -- -- -diff --git a/extern/ttmath/ttmathuint_x86_64_msvc.asm b/extern/ttmath/ttmathuint_x86_64_msvc.asm -deleted file mode 100644 -index aae113f636..0000000000 ---- a/extern/ttmath/ttmathuint_x86_64_msvc.asm -+++ /dev/null -@@ -1,548 +0,0 @@ --; --; This file is a part of TTMath Bignum Library --; and is distributed under the (new) BSD licence. --; Author: Christian Kaiser --; -- --; --; Copyright (c) 2009, Christian Kaiser --; All rights reserved. --; --; Redistribution and use in source and binary forms, with or without --; modification, are permitted provided that the following conditions are met: --; --; * Redistributions of source code must retain the above copyright notice, --; this list of conditions and the following disclaimer. --; --; * Redistributions in binary form must reproduce the above copyright --; notice, this list of conditions and the following disclaimer in the --; documentation and/or other materials provided with the distribution. --; --; * Neither the name Christian Kaiser nor the names of contributors to this --; project may be used to endorse or promote products derived --; from this software without specific prior written permission. --; --; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE --; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE --; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE --; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF --; THE POSSIBILITY OF SUCH DAMAGE. --; -- --; --; compile with debug info: ml64.exe /c /Zd /Zi ttmathuint_x86_64_msvc.asm --; compile without debug info: ml64.exe /c ttmathuint_x86_64_msvc.asm --; this creates ttmathuint_x86_64_msvc.obj file which can be linked with your program --; -- --PUBLIC ttmath_adc_x64 --PUBLIC ttmath_addindexed_x64 --PUBLIC ttmath_addindexed2_x64 --PUBLIC ttmath_addvector_x64 -- --PUBLIC ttmath_sbb_x64 --PUBLIC ttmath_subindexed_x64 --PUBLIC ttmath_subvector_x64 -- --PUBLIC ttmath_rcl_x64 --PUBLIC ttmath_rcr_x64 -- --PUBLIC ttmath_rcl2_x64 --PUBLIC ttmath_rcr2_x64 -- --PUBLIC ttmath_div_x64 -- --; --; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx --; --; "rax, rcx, rdx, r8-r11 are volatile." --; "rbx, rbp, rdi, rsi, r12-r15 are nonvolatile." --; -- -- --.CODE -- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_adc_x64 PROC -- ; rcx = p1 -- ; rdx = p2 -- ; r8 = nSize -- ; r9 = nCarry -- -- xor rax, rax -- xor r11, r11 -- sub rax, r9 ; sets CARRY if r9 != 0 -- -- ALIGN 16 -- loop1: -- mov rax,qword ptr [rdx + r11 * 8] -- adc qword ptr [rcx + r11 * 8], rax -- lea r11, [r11+1] -- dec r8 -- jnz loop1 -- -- setc al -- movzx rax, al -- -- ret -- --ttmath_adc_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_addindexed_x64 PROC -- -- ; rcx = p1 -- ; rdx = nSize -- ; r8 = nPos -- ; r9 = nValue -- -- xor rax, rax ; rax = result -- sub rdx, r8 ; rdx = remaining count of uints -- -- add qword ptr [rcx + r8 * 8], r9 -- jc next1 -- -- ret -- --next1: -- mov r9, 1 -- -- ALIGN 16 --loop1: -- dec rdx -- jz done_with_cy -- lea r8, [r8+1] -- add qword ptr [rcx + r8 * 8], r9 -- jc loop1 -- -- ret -- --done_with_cy: -- lea rax, [rax+1] ; rax = 1 -- -- ret -- --ttmath_addindexed_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_addindexed2_x64 PROC -- -- ; rcx = p1 (pointer) -- ; rdx = b (value size) -- ; r8 = nPos -- ; r9 = nValue1 -- ; [rsp+0x28] = nValue2 -- -- xor rax, rax ; return value -- mov r11, rcx ; table -- sub rdx, r8 ; rdx = remaining count of uints -- mov r10, [rsp+028h] ; r10 = nValue2 -- -- add qword ptr [r11 + r8 * 8], r9 -- lea r8, [r8+1] -- lea rdx, [rdx-1] -- adc qword ptr [r11 + r8 * 8], r10 -- jc next -- ret -- -- ALIGN 16 --loop1: -- lea r8, [r8+1] -- add qword ptr [r11 + r8 * 8], 1 -- jc next -- ret -- --next: -- dec rdx ; does not modify CY too... -- jnz loop1 -- lea rax, [rax+1] -- ret -- --ttmath_addindexed2_x64 ENDP -- -- -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- -- --ttmath_addvector_x64 PROC -- ; rcx = ss1 -- ; rdx = ss2 -- ; r8 = ss1_size -- ; r9 = ss2_size -- ; [rsp+0x28] = result -- -- mov r10, [rsp+028h] -- sub r8, r9 -- xor r11, r11 ; r11=0, cf=0 -- -- ALIGN 16 -- loop1: -- mov rax, qword ptr [rcx + r11 * 8] -- adc rax, qword ptr [rdx + r11 * 8] -- mov qword ptr [r10 + r11 * 8], rax -- inc r11 -- dec r9 -- jnz loop1 -- -- adc r9, r9 ; r9 has the cf state -- -- or r8, r8 -- jz done -- -- neg r9 ; setting cf from r9 -- mov r9, 0 ; don't use xor here (cf is used) -- loop2: -- mov rax, qword ptr [rcx + r11 * 8] -- adc rax, r9 -- mov qword ptr [r10 + r11 * 8], rax -- inc r11 -- dec r8 -- jnz loop2 -- -- adc r8, r8 -- mov rax, r8 -- -- ret -- --done: -- mov rax, r9 -- ret -- --ttmath_addvector_x64 ENDP -- -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_sbb_x64 PROC -- -- ; rcx = p1 -- ; rdx = p2 -- ; r8 = nCount -- ; r9 = nCarry -- -- xor rax, rax -- xor r11, r11 -- sub rax, r9 ; sets CARRY if r9 != 0 -- -- ALIGN 16 -- loop1: -- mov rax,qword ptr [rdx + r11 * 8] -- sbb qword ptr [rcx + r11 * 8], rax -- lea r11, [r11+1] -- dec r8 -- jnz loop1 -- -- setc al -- movzx rax, al -- -- ret -- --ttmath_sbb_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_subindexed_x64 PROC -- ; rcx = p1 -- ; rdx = nSize -- ; r8 = nPos -- ; r9 = nValue -- -- sub rdx, r8 ; rdx = remaining count of uints -- -- ALIGN 16 --loop1: -- sub qword ptr [rcx + r8 * 8], r9 -- jnc done -- -- lea r8, [r8+1] -- mov r9, 1 -- dec rdx -- jnz loop1 -- -- mov rax, 1 -- ret -- --done: -- xor rax, rax -- ret -- --ttmath_subindexed_x64 ENDP -- -- -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --; the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb' -- --ttmath_subvector_x64 PROC -- ; rcx = ss1 -- ; rdx = ss2 -- ; r8 = ss1_size -- ; r9 = ss2_size -- ; [rsp+0x28] = result -- -- mov r10, [rsp+028h] -- sub r8, r9 -- xor r11, r11 ; r11=0, cf=0 -- -- ALIGN 16 -- loop1: -- mov rax, qword ptr [rcx + r11 * 8] -- sbb rax, qword ptr [rdx + r11 * 8] -- mov qword ptr [r10 + r11 * 8], rax -- inc r11 -- dec r9 -- jnz loop1 -- -- adc r9, r9 ; r9 has the cf state -- -- or r8, r8 -- jz done -- -- neg r9 ; setting cf from r9 -- mov r9, 0 ; don't use xor here (cf is used) -- loop2: -- mov rax, qword ptr [rcx + r11 * 8] -- sbb rax, r9 -- mov qword ptr [r10 + r11 * 8], rax -- inc r11 -- dec r8 -- jnz loop2 -- -- adc r8, r8 -- mov rax, r8 -- -- ret -- --done: -- mov rax, r9 -- ret -- --ttmath_subvector_x64 ENDP -- -- -- -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_rcl_x64 PROC -- ; rcx = p1 -- ; rdx = b -- ; r8 = nLowestBit -- -- mov r11, rcx ; table -- xor r10, r10 -- neg r8 ; CY set if r8 <> 0 -- -- ALIGN 16 --loop1: -- rcl qword ptr [r11 + r10 * 8], 1 -- lea r10, [r10+1] -- dec rdx -- jnz loop1 -- -- setc al -- movzx rax, al -- -- ret -- --ttmath_rcl_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_rcr_x64 PROC -- ; rcx = p1 -- ; rdx = nSize -- ; r8 = nLowestBit -- -- xor r10, r10 -- neg r8 ; CY set if r8 <> 0 -- -- ALIGN 16 --loop1: -- rcr qword ptr -8[rcx + rdx * 8], 1 -- dec rdx -- jnz loop1 -- -- setc al -- movzx rax, al -- -- ret -- --ttmath_rcr_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_div_x64 PROC -- -- ; rcx = &Hi -- ; rdx = &Lo -- ; r8 = nDiv -- -- mov r11, rcx -- mov r10, rdx -- -- mov rdx, qword ptr [r11] -- mov rax, qword ptr [r10] -- div r8 -- mov qword ptr [r10], rdx ; remainder -- mov qword ptr [r11], rax ; value -- -- ret -- --ttmath_div_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_rcl2_x64 PROC -- ; rcx = p1 -- ; rdx = nSize -- ; r8 = bits -- ; r9 = c -- -- push rbx -- -- mov r10, rcx ; r10 = p1 -- xor rax, rax -- -- mov rcx, 64 -- sub rcx, r8 -- -- mov r11, -1 -- shr r11, cl ; r11 = mask -- -- mov rcx, r8 ; rcx = count of bits -- -- mov rbx, rax ; rbx = old value = 0 -- or r9, r9 -- cmovnz rbx, r11 ; if (c) then old value = mask -- -- mov r9, rax ; r9 = index (0..nSize-1) -- -- ALIGN 16 --loop1: -- rol qword ptr [r10+r9*8], cl -- mov rax, qword ptr [r10+r9*8] -- and rax, r11 -- xor qword ptr [r10+r9*8], rax -- or qword ptr [r10+r9*8], rbx -- mov rbx, rax -- -- lea r9, [r9+1] -- dec rdx -- -- jnz loop1 -- -- and rax, 1 -- pop rbx -- ret -- --ttmath_rcl2_x64 ENDP -- --;---------------------------------------- -- -- ALIGN 8 -- --;---------------------------------------- -- --ttmath_rcr2_x64 PROC -- ; rcx = p1 -- ; rdx = nSize -- ; r8 = bits -- ; r9 = c -- -- push rbx -- mov r10, rcx ; r10 = p1 -- xor rax, rax -- -- mov rcx, 64 -- sub rcx, r8 -- -- mov r11, -1 -- shl r11, cl ; r11 = mask -- -- mov rcx, r8 ; rcx = count of bits -- -- mov rbx, rax ; rbx = old value = 0 -- or r9, r9 -- cmovnz rbx, r11 ; if (c) then old value = mask -- -- mov r9, rdx ; r9 = index (0..nSize-1) -- lea r9, [r9-1] -- -- ALIGN 16 --loop1: -- ror qword ptr [r10+r9*8], cl -- mov rax, qword ptr [r10+r9*8] -- and rax, r11 -- xor qword ptr [r10+r9*8], rax -- or qword ptr [r10+r9*8], rbx -- mov rbx, rax -- -- lea r9, [r9-1] -- dec rdx -- -- jnz loop1 -- -- rol rax, 1 -- and rax, 1 -- pop rbx -- -- ret -- --ttmath_rcr2_x64 ENDP -- --END -diff --git a/src/common/Int128.cpp b/src/common/Int128.cpp -index d3158dddeb..88414b041d 100644 ---- a/src/common/Int128.cpp -+++ b/src/common/Int128.cpp -@@ -56,60 +56,18 @@ const CInt128 minus1(-1); - - namespace Firebird { - --Int128 Int128::set(SLONG value, int scale) --{ -- v = ttmath::sint(value); -- setScale(scale); -- return *this; --} -- --Int128 Int128::set(SINT64 value, int scale) --{ --#ifdef TTMATH_PLATFORM32 -- v = ttmath::slint(value); --#else -- v = ttmath::sint(value); --#endif -- setScale(scale); -- return *this; --} -- - Int128 Int128::set(const char* value) - { - // This is simplified method - it does not perform all what's needed for CVT_decompose -- v.FromString(value); -- return *this; --} -- --Int128 Int128::set(double value) --{ -- bool sgn = false; -- if (value < 0.0) -- { -- value = -value; -- sgn = true; -- } -- -- double parts[4]; -- for (int i = 0; i < 4; ++i) -+ for (v = 0; ; ++value) - { -- parts[i] = value; -- value /= p2_32; -- } -- fb_assert(value < 1.0); -+ if (*value < '0' or *value > '9') -+ break; - -- unsigned dwords[4]; -- value = 0.0; -- for (int i = 4; i--;) -- { -- dwords[i] = (parts[i] - value); -- value += p2_32 * dwords[i]; -+ v *= 10; -+ v += (*value - '0'); - } - -- setTable32(dwords); -- if (sgn) -- v.ChangeSign(); -- - return *this; - } - -@@ -122,14 +80,14 @@ Int128 Int128::set(DecimalStatus decSt, Decimal128 value) - value.getBcd(&bcd); - fb_assert(bcd.exp == 0); - -- v.SetZero(); -+ v = 0; - for (unsigned b = 0; b < sizeof(bcd.bcd); ++b) - { -- v.MulInt(10); -- v.AddInt(bcd.bcd[b]); -+ v *= 10; -+ v += bcd.bcd[b]; - } - if (bcd.sign < 0) -- v.ChangeSign(); -+ v = -v; - - return *this; - } -@@ -138,9 +96,13 @@ void Int128::setScale(int scale) - { - if (scale > 0) - { -- ttmath::sint rem = 0; -+ int rem = 0; - while (scale--) -- v.DivInt(10, scale == 0 ? &rem : nullptr); -+ { -+ if (scale == 0) -+ rem = int(v % 10); -+ v /= 10; -+ } - - if (rem > 4) - v++; -@@ -152,21 +114,11 @@ void Int128::setScale(int scale) - while (scale++) { - if (v > i128limit.v || v < -i128limit.v) - (Arg::Gds(isc_arith_except) << Arg::Gds(isc_numeric_out_of_range)).raise(); -- v.MulInt(10); -+ v *= 10; - } - } - } - --int Int128::toInteger(int scale) const --{ -- Int128 tmp(*this); -- tmp.setScale(scale); -- int rc; -- if (tmp.v.ToInt(rc)) -- overflow(); -- return rc; --} -- - void Int128::toString(int scale, unsigned length, char* to) const - { - string buffer; -@@ -181,10 +133,22 @@ void Int128::toString(int scale, unsigned length, char* to) const - - void Int128::toString(int scale, string& to) const - { -- v.ToStringBase(to); -- bool sgn = to[0] == '-'; -+ to.erase(); -+ absl::int128 vv = v; -+ -+ bool sgn = (vv < 0); - if (sgn) -- to.erase(0, 1); -+ vv = -vv; -+ -+ while (vv > 0) -+ { -+ int dig = int(vv % 10); -+ to.insert(string::size_type(0), string::size_type(1), char(dig + '0')); -+ vv /= 10; -+ } -+ -+ if (to.isEmpty()) -+ to = "0"; - - if (scale) - { -@@ -220,78 +184,23 @@ void Int128::toString(int scale, string& to) const - to.insert(0, "-"); - } - --SINT64 Int128::toInt64(int scale) const --{ -- Int128 tmp(*this); -- tmp.setScale(scale); -- if (tmp.v < i64min.v || tmp.v > i64max.v) -- overflow(); -- -- unsigned dwords[4]; -- tmp.getTable32(dwords); -- SINT64 rc = int(dwords[1]); -- rc <<= 32; -- rc += dwords[0]; -- -- return rc; --} -- --double Int128::toDouble() const --{ -- unsigned dwords[4]; -- getTable32(dwords); -- double rc = int(dwords[3]); -- for (int i = 3; i--;) -- { -- rc *= p2_32; -- rc += dwords[i]; -- } -- -- return rc; --} -- --int Int128::compare(Int128 tgt) const --{ -- return v < tgt.v ? -1 : v > tgt.v ? 1 : 0; --} -- - Int128 Int128::abs() const - { -- Int128 rc(*this); -- if (rc.v.Abs()) -+ if (compare(MIN_Int128) == 0) - overflow(); -- return rc; --} - --Int128 Int128::neg() const --{ -- Int128 rc(*this); -- if (rc.v.ChangeSign()) -- overflow(); -- return rc; --} -- --Int128 Int128::add(Int128 op2) const --{ -- Int128 rc(*this); -- if (rc.v.Add(op2.v)) -- overflow(); -+ Int128 rc; -+ rc.v = v < 0 ? -v : v; - return rc; - } - --Int128 Int128::sub(Int128 op2) const -+Int128 Int128::neg() const - { -- Int128 rc(*this); -- if (rc.v.Sub(op2.v)) -+ if (compare(MIN_Int128) == 0) - overflow(); -- return rc; --} - --Int128 Int128::mul(Int128 op2) const --{ -- Int128 rc(*this); -- if (rc.v.Mul(op2.v)) -- overflow(); -+ Int128 rc; -+ rc.v = -v; - return rc; - } - -@@ -300,210 +209,37 @@ Int128 Int128::div(Int128 op2, int scale) const - if (compare(MIN_Int128) == 0 && op2.compare(minus1) == 0) - Arg::Gds(isc_exception_integer_overflow).raise(); - -+ if (op2.v == 0) -+ zerodivide(); -+ - static const CInt128 MIN_BY10(MIN_Int128 / 10); - static const CInt128 MAX_BY10(MAX_Int128 / 10); - - // Scale op1 by as many of the needed powers of 10 as possible without an overflow. -- CInt128 op1(*this); -+ Int128 op1(*this); - int sign1 = op1.sign(); - while ((scale < 0) && (sign1 >= 0 ? op1.compare(MAX_BY10) <= 0 : op1.compare(MIN_BY10) >= 0)) - { -- op1 *= 10; -+ op1.v *= 10; - ++scale; - } - - // Scale op2 shifting it to the right as long as only zeroes are thrown away. -- CInt128 tmp(op2); - while (scale < 0) - { -- ttmath::sint rem = 0; -- tmp.v.DivInt(10, &rem); -+ int rem = int(v % 10); - if (rem) - break; -- op2 = tmp; -+ op2.v /= 10; - ++scale; - } - -- if (op1.v.Div(op2.v)) -- zerodivide(); -+ op1.v /= op2.v; - - op1.setScale(scale); - return op1; - } - --Int128 Int128::mod(Int128 op2) const --{ -- Int128 tmp(*this); -- Int128 rc; -- if (tmp.v.Div(op2.v, rc.v)) -- zerodivide(); -- return rc; --} -- --int Int128::sign() const --{ -- return v.IsSign() ? -1 : v.IsZero() ? 0 : 1; --} -- --UCHAR* Int128::getBytes() --{ -- return (UCHAR*)(v.table); --} -- --void Int128::getTable32(unsigned* dwords) const --{ -- static_assert((sizeof(v.table[0]) == 4) || (sizeof(v.table[0]) == 8), -- "Unsupported size of integer in ttmath"); -- -- if (sizeof(v.table[0]) == 4) -- { -- for (int i = 0; i < 4; ++i) -- dwords[i] = v.table[i]; -- } -- else if (sizeof(v.table[0]) == 8) -- { -- for (int i = 0; i < 2; ++i) -- { -- dwords[i * 2] = v.table[i] & 0xFFFFFFFF; -- dwords[i * 2 + 1] = (v.table[i] >> 32) & 0xFFFFFFFF; -- } -- } --} -- --void Int128::setTable32(const unsigned* dwords) --{ -- static_assert((sizeof(v.table[0]) == 4) || (sizeof(v.table[0]) == 8), -- "Unsupported size of integer in ttmath"); -- -- if (sizeof(v.table[0]) == 4) -- { -- for (int i = 0; i < 4; ++i) -- v.table[i] = dwords[i]; -- } -- else if (sizeof(v.table[0]) == 8) -- { -- for (int i = 0; i < 2; ++i) -- { -- v.table[i] = dwords[i * 2 + 1]; -- v.table[i] <<= 32; -- v.table[i] += dwords[i * 2]; -- } -- } --} -- --Int128 Int128::operator&=(FB_UINT64 mask) --{ -- v.table[0] &= mask; -- unsigned i = 1; -- if (sizeof(v.table[0]) == 4) -- { -- i = 2; -- v.table[1] &= (mask >> 32); -- } -- -- for (; i < FB_NELEM(v.table); ++i) -- v.table[i] = 0; -- return *this; --} -- --Int128 Int128::operator&=(ULONG mask) --{ -- v.table[0] &= mask; -- -- for (unsigned i = 1; i < FB_NELEM(v.table); ++i) -- v.table[i] = 0; -- return *this; --} -- --Int128 Int128::operator/(unsigned value) const --{ -- Int128 rc(*this); -- rc.v.DivInt(value); -- return rc; --} -- --Int128 Int128::operator<<(int value) const --{ -- Int128 rc(*this); -- rc.v <<= value; -- return rc; --} -- --Int128 Int128::operator>>(int value) const --{ -- Int128 rc(*this); -- rc.v >>= value; -- return rc; --} -- --Int128 Int128::operator&=(Int128 value) --{ -- v &= value.v; -- return *this; --} -- --Int128 Int128::operator|=(Int128 value) --{ -- v |= value.v; -- return *this; --} -- --Int128 Int128::operator^=(Int128 value) --{ -- v ^= value.v; -- return *this; --} -- --Int128 Int128::operator~() const --{ -- Int128 rc(*this); -- rc.v.BitNot(); -- return rc; --} -- --Int128 Int128::operator-() const --{ -- return neg(); --} -- --Int128 Int128::operator+=(unsigned value) --{ -- v.AddInt(value); -- return *this; --} -- --Int128 Int128::operator-=(unsigned value) --{ -- v.SubInt(value); -- return *this; --} -- --Int128 Int128::operator*=(unsigned value) --{ -- v.MulInt(value); -- return *this; --} -- --bool Int128::operator>(Int128 value) const --{ -- return v > value.v; --} -- --bool Int128::operator>=(Int128 value) const --{ -- return v >= value.v; --} -- --bool Int128::operator==(Int128 value) const --{ -- return v == value.v; --} -- --bool Int128::operator!=(Int128 value) const --{ -- return v != value.v; --} -- - void Int128::zerodivide() - { - (Arg::Gds(isc_arith_except) << Arg::Gds(isc_exception_integer_divide_by_zero)).raise(); -@@ -533,10 +269,10 @@ CInt128::CInt128(minmax mm) - switch(mm) - { - case MkMax: -- v.SetMax(); -+ v = absl::Int128Max(); - break; - case MkMin: -- v.SetMin(); -+ v = absl::Int128Min(); - break; - } - } -diff --git a/src/common/Int128.h b/src/common/Int128.h -index 5fde931ff9..432023d176 100644 ---- a/src/common/Int128.h -+++ b/src/common/Int128.h -@@ -36,7 +36,7 @@ - - #include "classes/fb_string.h" - --#include "../../extern/ttmath/ttmath.h" -+#include "absl/numeric/int128.h" - - namespace Firebird { - -@@ -53,10 +53,29 @@ public: - return set(SLONG(value), scale); - } - #endif -- Int128 set(SLONG value, int scale); -- Int128 set(SINT64 value, int scale); -- Int128 set(double value); -+ -+ Int128 set(SLONG value, int scale) -+ { -+ v = value; -+ setScale(scale); -+ return *this; -+ } -+ -+ Int128 set(SINT64 value, int scale) -+ { -+ v = value; -+ setScale(scale); -+ return *this; -+ } -+ -+ Int128 set(double value) -+ { -+ v = absl::int128(value); -+ return *this; -+ } -+ - Int128 set(DecimalStatus decSt, Decimal128 value); -+ - Int128 set(Int128 value) - { - v = value.v; -@@ -73,49 +92,217 @@ public: - const char* show(); - #endif - -- int toInteger(int scale) const; -- SINT64 toInt64(int scale) const; -+ int toInteger(int scale) const -+ { -+ Int128 tmp(*this); -+ tmp.setScale(scale); -+ int rc = int(tmp.v); -+ if (tmp.v != rc) -+ overflow(); -+ return rc; -+ } -+ -+ SINT64 toInt64(int scale) const -+ { -+ Int128 tmp(*this); -+ tmp.setScale(scale); -+ SINT64 rc = SINT64(tmp.v); -+ if (tmp.v != rc) -+ overflow(); -+ return rc; -+ } -+ - void toString(int scale, unsigned length, char* to) const; - void toString(int scale, string& to) const; -- double toDouble() const; -- -- Int128 operator&=(FB_UINT64 mask); -- Int128 operator&=(ULONG mask); -- Int128 operator-() const; -- Int128 operator/(unsigned value) const; -- Int128 operator+=(unsigned value); -- Int128 operator-=(unsigned value); -- Int128 operator*=(unsigned value); -- -- Int128 operator<<(int value) const; -- Int128 operator>>(int value) const; -- -- int compare(Int128 tgt) const; -- bool operator>(Int128 value) const; -- bool operator>=(Int128 value) const; -- bool operator==(Int128 value) const; -- bool operator!=(Int128 value) const; -- Int128 operator&=(Int128 value); -- Int128 operator|=(Int128 value); -- Int128 operator^=(Int128 value); -- Int128 operator~() const; -- int sign() const; -+ -+ double toDouble() const -+ { -+ return double(v); -+ } -+ -+ Int128 operator&=(FB_UINT64 mask) -+ { -+ v &= mask; -+ return *this; -+ } -+ -+ Int128 operator&=(ULONG mask) -+ { -+ v &= mask; -+ return *this; -+ } -+ -+ Int128 operator-() const -+ { -+ Int128 rc; -+ rc.v = -v; -+ return rc; -+ } -+ -+ Int128 operator/(unsigned value) const -+ { -+ Int128 rc; -+ rc.v = v / value; -+ return rc; -+ } -+ -+ Int128 operator+=(unsigned value) -+ { -+ v += value; -+ return *this; -+ } -+ -+ Int128 operator-=(unsigned value) -+ { -+ v -= value; -+ return *this; -+ } -+ -+ Int128 operator*=(unsigned value) -+ { -+ v *= value; -+ return *this; -+ } -+ -+ Int128 operator<<(int value) const -+ { -+ Int128 rc; -+ rc.v = v << value; -+ return rc; -+ } -+ -+ Int128 operator>>(int value) const -+ { -+ Int128 rc; -+ rc.v = v >> value; -+ return rc; -+ } -+ -+ int compare(Int128 tgt) const -+ { -+ return v < tgt.v ? -1 : v > tgt.v ? 1 : 0; -+ } -+ -+ bool operator>(Int128 value) const -+ { -+ return v > value.v; -+ } -+ -+ bool operator>=(Int128 value) const -+ { -+ return v >= value.v; -+ } -+ -+ bool operator==(Int128 value) const -+ { -+ return v == value.v; -+ } -+ -+ bool operator!=(Int128 value) const -+ { -+ return v != value.v; -+ } -+ -+ Int128 operator&=(Int128 value) -+ { -+ v &= value.v; -+ return *this; -+ } -+ -+ Int128 operator|=(Int128 value) -+ { -+ v |= value.v; -+ return *this; -+ } -+ -+ Int128 operator^=(Int128 value) -+ { -+ v ^= value.v; -+ return *this; -+ } -+ -+ Int128 operator~() const -+ { -+ Int128 rc; -+ rc.v = ~v; -+ return rc; -+ } -+ -+ int sign() const -+ { -+ return v < 0 ? -1 : v == 0 ? 0 : 1; -+ } - - Int128 abs() const; - Int128 neg() const; -- Int128 add(Int128 op2) const; -- Int128 sub(Int128 op2) const; -- Int128 mul(Int128 op2) const; -+ -+ Int128 add(Int128 op2) const -+ { -+ Int128 rc; -+ rc.v = v + op2.v; -+ -+ // see comment ArithmeticNode::add2() -+ if (sign() == op2.sign() && op2.sign() != rc.sign()) -+ overflow(); -+ -+ return rc; -+ } -+ -+ Int128 sub(Int128 op2) const -+ { -+ Int128 rc; -+ rc.v = v - op2.v; -+ -+ // see comment ArithmeticNode::add2() -+ if (sign() != op2.sign() && op2.sign() == rc.sign()) -+ overflow(); -+ -+ return rc; -+ } -+ -+ Int128 mul(Int128 op2) const -+ { -+ Int128 rc; -+ rc.v = v * op2.v; -+ -+ if (rc.v / v != op2.v) -+ overflow(); -+ -+ return rc; -+ } -+ - Int128 div(Int128 op2, int scale) const; -- Int128 mod(Int128 op2) const; - -- void getTable32(unsigned* dwords) const; // internal data in per-32bit form -- void setTable32(const unsigned* dwords); -+ Int128 mod(Int128 op2) const -+ { -+ if (op2.v == 0) -+ zerodivide(); -+ -+ Int128 rc; -+ rc.v = v % op2.v; -+ return rc; -+ } -+ -+ // returns internal data in per-32bit form -+ void getTable32(unsigned* dwords) const -+ { -+ absl::int128 vv = v; -+ for (int i = 0; i < 4; ++i) -+ { -+ dwords[i] = unsigned(vv); -+ vv >>= 32; -+ } -+ } -+ - void setScale(int scale); -- UCHAR* getBytes(); -+ -+ UCHAR* getBytes() -+ { -+ return (UCHAR*)(&v); -+ } - - protected: -- ttmath::Int v; -+ absl::int128 v; - - static void overflow(); - static void zerodivide(); -@@ -143,10 +330,10 @@ class I128limit : public Int128 - public: - I128limit() - { -- v.SetOne(); -+ v = 1; - for (int i = 0; i < 126; ++i) -- v.MulInt(2); -- v.DivInt(5); -+ v *= 2; -+ v *= 5; - } - }; - -diff --git a/src/jrd/align.h b/src/jrd/align.h -index aa4631488d..c94f0f4da3 100644 ---- a/src/jrd/align.h -+++ b/src/jrd/align.h -@@ -114,7 +114,7 @@ static const USHORT type_alignments[DTYPE_TYPE_MAX] = - sizeof(UCHAR), /* dtype_boolean */ - sizeof(Firebird::Decimal64),/* dtype_dec64 */ - sizeof(Firebird::Decimal64),/* dtype_dec128 */ -- sizeof(Firebird::Decimal64),/* dtype_int128 */ -+ sizeof(SINT64), /* dtype_int128 */ - sizeof(GDS_TIME), /* dtype_sql_time_tz */ - sizeof(GDS_DATE), /* dtype_timestamp_tz */ - sizeof(GDS_TIME), /* dtype_ex_time_tz */ diff --git a/SPECS/firebird.spec b/SPECS/firebird.spec index 252ad89..3fb41aa 100644 --- a/SPECS/firebird.spec +++ b/SPECS/firebird.spec @@ -1,4 +1,4 @@ -%global upversion 4.0.0.2496 +%global upversion 4.0.4.3010 %global pkgversion Firebird-%{upversion}-0 %global major 4.0 @@ -10,13 +10,13 @@ Name: firebird Version: %{upversion} -Release: 2%{?dist} +Release: 4%{?dist} Summary: SQL relational database management system License: Interbase URL: http://www.firebirdsql.org/ -Source0: https://github.com/FirebirdSQL/firebird/releases/download/v4.0.0/%{pkgversion}.tar.xz +Source0: https://github.com/FirebirdSQL/firebird/releases/download/v4.0.3/%{pkgversion}.tar.xz Source1: firebird-logrotate Source2: README.Fedora Source3: firebird.service @@ -30,8 +30,14 @@ Patch203: no-copy-from-icu.patch Patch205: cloop-honour-build-flags.patch # from upstream -Patch303: fix_build_on_big_endian_platforms.patch -Patch304: ttmath-abseil.4.0.0.patch +Patch301: c++17.patch +Patch302: noexcept.patch +Patch303: autoconf.patch +Patch401: btyacc-honour-build-flags.patch +Patch402: firebird-configure-c99.patch + +# not yet upstream +Patch501: examples-honour-build-flags.patch BuildRequires: autoconf BuildRequires: automake @@ -42,7 +48,7 @@ BuildRequires: libicu-devel BuildRequires: libedit-devel BuildRequires: gcc-c++ BuildRequires: libstdc++-static -BuildRequires: systemd-units +BuildRequires: systemd-rpm-macros BuildRequires: chrpath BuildRequires: zlib-devel BuildRequires: procmail @@ -55,10 +61,7 @@ Requires(postun): /usr/sbin/userdel Requires(postun): /usr/sbin/groupdel Requires(pre): /usr/sbin/groupadd Requires(pre): /usr/sbin/useradd -Requires(post): systemd-units -Requires(preun): systemd-units -Requires(postun): systemd-units -Requires: logrotate +Recommends: logrotate Requires: libfbclient2 = %{version}-%{release} Requires: libib-util = %{version}-%{release} Requires: %{name}-utils = %{version}-%{release} @@ -193,13 +196,15 @@ in production systems, under a variety of names, since 1981. %prep %setup -q -n %{pkgversion} -%patch101 -p1 -%patch203 -p1 -%patch205 -p1 -%ifarch s390x -%patch303 -p1 -%patch304 -p1 -%endif +%patch -P101 -p1 +%patch -P203 -p1 +%patch -P205 -p1 +%patch -P301 -p1 +%patch -P302 -p1 +%patch -P303 -p1 +%patch -P401 -p1 +%patch -P402 -p1 +%patch -P501 -p1 %build @@ -223,7 +228,7 @@ NOCONFIGURE=1 ./autogen.sh --with-fbsecure-db=%{_localstatedir}/lib/%{name}/secdb \ --with-fbmsg=%{_localstatedir}/lib/%{name}/system \ --with-fblog=%{_localstatedir}/log/%{name} \ - --with-fbglock=/run/%{name} \ + --with-fbglock=%{_rundir}/%{name} \ --with-fbplugins=%{_libdir}/%{name}/plugins \ --with-fbtzdata=%{_localstatedir}/lib/%{name}/tzdata @@ -375,59 +380,221 @@ fi %changelog -* Sat Nov 18 2023 Arkady L. Shane - 4.0.0.2496-2 -- Rebuilt for MSVSphere 9.2 +* Wed Jan 15 2025 Eduard Basov - 4.0.4.3010-4 +- Rebuild For MSVSphere 10 + +* Wed Jul 17 2024 Fedora Release Engineering - 4.0.4.3010-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Wed Jan 24 2024 Fedora Release Engineering - 4.0.4.3010-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 4.0.4.3010-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Thu Nov 09 2023 Philippe Makowski - 4.0.4.3010-0 +- Update to 4.0.4 (#2247832) + +* Tue Aug 08 2023 Philippe Makowski - 4.0.3.2975-0 +- Update to 4.0.3 (#2228171) + +* Wed Jul 19 2023 Fedora Release Engineering - 4.0.2.2816-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Thu Jan 19 2023 Fedora Release Engineering - 4.0.2.2816-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Thu Dec 1 2022 Florian Weimer - 4.0.2.2816-3 +- Port configure script to C99 + +* Thu Nov 24 2022 Philippe Makowski - 4.0.2.2816-2 +- Patch for autoconf 2.72 (#2144802) + +* Fri Aug 12 2022 Philippe Makowski - 4.0.2.2816-1 +- Update to 4.0.2 (#2033945) + +* Thu Jul 21 2022 Fedora Release Engineering - 4.0.0.2496-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Fri May 13 2022 Philippe Makowski - 4.0.0.2496-7 +- Remove Standard output type syslog (#2035798) + +* Thu Jan 20 2022 Fedora Release Engineering - 4.0.0.2496-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild -* Fri Aug 20 2021 Philippe Makowski - 4.0.0.2496-2 +* Sun Oct 10 2021 Kalev Lember - 4.0.0.2496-5 +- Recommend logrotate rather than hard requiring + +* Fri Oct 08 2021 Kalev Lember - 4.0.0.2496-4 +- BuildRequire systemd-rpm-macros instead of systemd-units +- Remove requires on systemd-units as per updated guidelines + +* Fri Aug 20 2021 Philippe Makowski - 4.0.0.2496-3 - Fix build on s390x (#1969393) +* Wed Jul 21 2021 Fedora Release Engineering - 4.0.0.2496-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Tue Jun 08 2021 Philippe Makowski - 4.0.0.2496-1 - Update to 4.0.0 (#1963311) +* Mon May 10 2021 Jeff Law - 3.0.7.33374-5 +- Re-enable LTO + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 3.0.7.33374-4 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + +* Tue Jan 26 2021 Fedora Release Engineering - 3.0.7.33374-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Oct 27 2020 Jeff Law - 3.0.7.33374-2 +- Force C++14 as this code is not C++17 ready + * Fri Oct 23 2020 Philippe Makowski - 3.0.7.33374-1 - new upstream release fix #1887991 +* Mon Aug 10 2020 Jeff Law - 3.0.6.33328-4 +- Disable LTO on s390x for now + +* Sat Aug 01 2020 Fedora Release Engineering - 3.0.6.33328-3 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 3.0.6.33328-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Wed Jul 08 2020 Philippe Makowski - 3.0.6.33328-1 - new upstream release fix #1850675 - + +* Tue Jan 28 2020 Fedora Release Engineering - 3.0.5.33220-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Mon Jan 20 2020 Philippe Makowski - 3.0.5.33220-1 - new upstream release fix #1786885 -* Wed Sep 18 2019 Philippe Makowski - 3.0.4.33054-1 +* Mon Nov 4 2019 Philippe Makowski - 3.0.4.33054-5 +- Change firebird-superserver.service file permissions, fix #1768091 +- Set login shell to /sbin/nologin, fix #1764128 +- Remove BR libtermcap-devel + +* Wed Aug 21 2019 Philippe Makowski - 3.0.4.33054-4 +- Remove tmpfile, fix #1687058 + +* Thu Jul 25 2019 Fedora Release Engineering - 3.0.4.33054-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Thu Jan 31 2019 Fedora Release Engineering - 3.0.4.33054-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Nov 22 2018 Philippe Makowski - 3.0.4.33054-1 +- new upstream release + +* Fri Jul 13 2018 Fedora Release Engineering - 3.0.3.32900-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Sun Mar 18 2018 Richard W.M. Jones - 3.0.3.32900-2 +- Add support for riscv64. + +* Tue Feb 20 2018 Philippe Makowski - 3.0.3.32900-1 +- new upstream release. +- Drop obsolete ldconfig scriptlets. +- Fix tmpfiles path + +* Tue Feb 13 2018 Remi Collet - 3.0.2.32703-5 +- add shebang in fb_config, fix #1544837 + +* Wed Feb 07 2018 Fedora Release Engineering - 3.0.2.32703-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Aug 02 2017 Fedora Release Engineering - 3.0.2.32703-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.0.2.32703-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Mar 27 2017 Philippe Makowski - 3.0.2.32703-1 - new upstream release -* Thu Aug 22 2019 Philippe Makowski 2.5.9.27139.0-1 -- update to 2.5.9 (End of Series) +* Tue Feb 21 2017 Philippe Makowski - 3.0.1.32609-5 +- security fix (#1425333) + +* Fri Feb 10 2017 Fedora Release Engineering - 3.0.1.32609-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Tue Nov 15 2016 Philippe Makowski - 3.0.1.32609-3 +- add requires on libfbclient2-devel for firebird-devel #1394750 + +* Mon Oct 31 2016 Philippe Makowski - 3.0.1.32609-2 +- obsolete firebird-libfbembed #1388648 + +* Wed Oct 12 2016 Philippe Makowski - 3.0.1.32609-1 +- new upstream release -* Fri Aug 31 2018 Philippe Makowski 2.5.8.27089.0-1 -- update to 2.5.8 +* Fri Apr 15 2016 David Tardon - 2.5.5.26952.0-7 +- rebuild for ICU 57.1 -* Tue Feb 21 2017 Philippe Makowski 2.5.7.27050.0-1 -- update to 2.5.7 -- security fix (#1425332) +* Wed Mar 30 2016 Philippe Makowski - 2.5.5.26952.0-6 +- use _tmpfilesdir macro -* Thu Dec 29 2016 Philippe Makowski 2.5.6.27020.0-1 -- update to 2.5.6 +* Wed Mar 09 2016 Philippe Makowski - 2.5.5.26952.0-5 +- Resolves: rbhz#1307503 building with gcc6 -* Fri Feb 05 2016 Philippe Makowski - 2.5.5.26952.0-2 +* Sat Feb 20 2016 David Tardon - 2.5.5.26952.0-4 +- Resolves: rbhz#1309223 restore /usr/sbin/fb_config + +* Fri Feb 05 2016 Philippe Makowski - 2.5.5.26952.0-3 - move fb_config (#1297506) -- fix CVE-2016-1569 (#1297447 #1297450 #1297451) +- fixe CVE-2016-1569 (#1297447 #1297450 #1297451) + +* Wed Feb 03 2016 Fedora Release Engineering - 2.5.5.26952.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild * Thu Nov 19 2015 Philippe Makowski 2.5.5.26952.0-1 - update to 2.5.5 +* Wed Oct 28 2015 David Tardon - 2.5.4.26856.0-4 +- rebuild for ICU 56.1 + +* Wed Jun 17 2015 Fedora Release Engineering - 2.5.4.26856.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat May 02 2015 Kalev Lember - 2.5.4.26856.0-2 +- Rebuilt for GCC 5 C++11 ABI change + * Thu Apr 2 2015 Philippe Makowski 2.5.4.26856.0-1 -- update to 2.5.4 +- update to 2.5.4 + +* Mon Jan 26 2015 David Tardon - 2.5.3.26778.0-6 +- rebuild for ICU 54.1 -* Sun Dec 7 2014 Philippe Makowski 2.5.3.26778.0-2 +* Sun Dec 7 2014 Philippe Makowski 2.5.3.26778.0-5 - security fix firebird CORE-4630 +* Thu Oct 30 2014 Philippe Makowski 2.5.3.26778.0-4 +- Remove lib64 rpaths (#1154706) + +* Tue Aug 26 2014 David Tardon - 2.5.3.26778.0-3 +- rebuild for ICU 53.1 + +* Sat Aug 16 2014 Fedora Release Engineering - 2.5.3.26778.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + * Sat Jul 26 2014 Philippe Makowski - 2.5.3.26778.0-1 - update from upstream 2.5.3 - update arm64 patch -* Tue Jan 21 2014 Philippe Makowski 2.5.2.26539.0-8 -- add missing BR on libstdc++-static +* Sat Jun 07 2014 Fedora Release Engineering - 2.5.2.26539.0-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Feb 12 2014 Rex Dieter 2.5.2.26539.0-10 +- rebuild (libicu) + +* Sat Dec 07 2013 Philippe Makowski 2.5.2.26539.0-9 +- fix FTBFS if "-Werror=format-security" flag is used (bug #1037062) + +* Thu Aug 08 2013 Philippe Makowski 2.5.2.26539.0-8 +- add BR libatomic_ops-static (bug #993439) * Tue Jul 23 2013 Philippe Makowski 2.5.2.26539.0-7 - make fb_config executable (bug #985335) @@ -483,7 +650,7 @@ fi * Fri Apr 22 2011 Philippe Makowski 2.5.0.26074.0-8 - added patch from upstream to fix rh #697313 -* Mon Mar 07 2011 Caolรกn McNamara - 2.5.0.26074.0-7 +* Mon Mar 07 2011 Caolán McNamara - 2.5.0.26074.0-7 - rebuild for icu 4.6 * Tue Feb 08 2011 Fedora Release Engineering - 2.5.0.26074.0-6 @@ -499,7 +666,7 @@ fi * Wed Dec 22 2010 Philippe Makowski 2.5.0.26074.0-3 - Fix wrong assign file for classic and classic common -* Thu Dec 16 2010 Dan Horรกk 2.5.0.26074.0-2 +* Thu Dec 16 2010 Dan Horák 2.5.0.26074.0-2 - sync the s390(x) utilities list with other arches - add libatomic_ops-devel as BR: on non-x86 arches @@ -509,7 +676,7 @@ fi * Mon Nov 22 2010 Philippe Makowski 2.5.0.26074.0-0 - build with last upstream -* Tue Jun 29 2010 Dan Horรกk 2.1.3.18185.0-9 +* Tue Jun 29 2010 Dan Horák 2.1.3.18185.0-9 - update the s390(x) patch to match upstream * Fri Jun 04 2010 Philippe Makowski 2.1.3.18185.0-8 @@ -520,11 +687,11 @@ fi - Fix rh #563461 with backport mainstream patch CORE-2928 -* Fri Apr 02 2010 Caolรกn McNamara 2.1.3.18185.0-6 +* Fri Apr 02 2010 Caolán McNamara 2.1.3.18185.0-6 - rebuild for icu 4.4 * Sat Sep 05 2009 Karsten Hopp 2.1.3.18185.0-5 -- fix build on s390x for F-12 mass rebuild (Dan Horรกk) +- fix build on s390x for F-12 mass rebuild (Dan Horák) * Tue Aug 11 2009 Philippe Makowski 2.1.3.18185.0-4 - build it against system edit lib @@ -538,7 +705,7 @@ fi * Thu Jul 30 2009 Philippe Makowski 2.1.3.18185.0-1 - Update to 2.1.3.18185 - Fix rh #514463 -- Remove doc patch +- Remove doc patch - Apply backport initscript patch * Sat Jul 11 2009 Philippe Makowski 2.1.2.18118.0-11 @@ -584,7 +751,7 @@ fi * Sat Mar 28 2009 Philippe Makowski 2.1.1.17910.0-5 - Major packaging restructuring - + * Sat Mar 21 2009 Philippe Makowski 2.1.1.17190.0-4 - Create a doc package - major cleaning to avoid rpmlint errors @@ -616,4 +783,3 @@ fi * Thu Sep 13 2007 Arkady L. Shane 2.0.1.12855.0-1 - Initial build for Fedora - cleanup Mandriva spec -