Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Algol68
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C with Coccinelle
C++ with Coccinelle
C++ (Circle)
CIRCT
Clean
Clojure
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
GLSL
Go
Haskell
HLSL
Helion
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Mojo
Nim
Numba
Nix
Objective-C
Objective-C++
OCaml
Odin
OpenCL C
Pascal
Pony
PTX
Python
Racket
Raku
Ruby
Rust
Sail
Snowball
Scala
Slang
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
Triton
TypeScript Native
V
Vala
Visual Basic
Vyper
WASM
Yul (Solidity IR)
Zig
Javascript
GIMPLE
Ygen
sway
c++ source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
6502-c++ 11.1.0
ARM GCC 10.2.0
ARM GCC 10.3.0
ARM GCC 10.4.0
ARM GCC 10.5.0
ARM GCC 11.1.0
ARM GCC 11.2.0
ARM GCC 11.3.0
ARM GCC 11.4.0
ARM GCC 12.1.0
ARM GCC 12.2.0
ARM GCC 12.3.0
ARM GCC 12.4.0
ARM GCC 12.5.0
ARM GCC 13.1.0
ARM GCC 13.2.0
ARM GCC 13.2.0 (unknown-eabi)
ARM GCC 13.3.0
ARM GCC 13.3.0 (unknown-eabi)
ARM GCC 13.4.0
ARM GCC 13.4.0 (unknown-eabi)
ARM GCC 14.1.0
ARM GCC 14.1.0 (unknown-eabi)
ARM GCC 14.2.0
ARM GCC 14.2.0 (unknown-eabi)
ARM GCC 14.3.0
ARM GCC 14.3.0 (unknown-eabi)
ARM GCC 15.1.0
ARM GCC 15.1.0 (unknown-eabi)
ARM GCC 15.2.0
ARM GCC 15.2.0 (unknown-eabi)
ARM GCC 4.5.4
ARM GCC 4.6.4
ARM GCC 5.4
ARM GCC 6.3.0
ARM GCC 6.4.0
ARM GCC 7.3.0
ARM GCC 7.5.0
ARM GCC 8.2.0
ARM GCC 8.5.0
ARM GCC 9.3.0
ARM GCC 9.4.0
ARM GCC 9.5.0
ARM GCC trunk
ARM gcc 10.2.1 (none)
ARM gcc 10.3.1 (2021.07 none)
ARM gcc 10.3.1 (2021.10 none)
ARM gcc 11.2.1 (none)
ARM gcc 5.4.1 (none)
ARM gcc 7.2.1 (none)
ARM gcc 8.2 (WinCE)
ARM gcc 8.3.1 (none)
ARM gcc 9.2.1 (none)
ARM msvc v19.0 (ex-WINE)
ARM msvc v19.10 (ex-WINE)
ARM msvc v19.14 (ex-WINE)
ARM64 Morello gcc 10.1 Alpha 2
ARM64 gcc 10.2
ARM64 gcc 10.3
ARM64 gcc 10.4
ARM64 gcc 10.5.0
ARM64 gcc 11.1
ARM64 gcc 11.2
ARM64 gcc 11.3
ARM64 gcc 11.4.0
ARM64 gcc 12.1
ARM64 gcc 12.2.0
ARM64 gcc 12.3.0
ARM64 gcc 12.4.0
ARM64 gcc 12.5.0
ARM64 gcc 13.1.0
ARM64 gcc 13.2.0
ARM64 gcc 13.3.0
ARM64 gcc 13.4.0
ARM64 gcc 14.1.0
ARM64 gcc 14.2.0
ARM64 gcc 14.3.0
ARM64 gcc 15.1.0
ARM64 gcc 15.2.0
ARM64 gcc 4.9.4
ARM64 gcc 5.4
ARM64 gcc 5.5.0
ARM64 gcc 6.3
ARM64 gcc 6.4
ARM64 gcc 7.3
ARM64 gcc 7.5
ARM64 gcc 8.2
ARM64 gcc 8.5
ARM64 gcc 9.3
ARM64 gcc 9.4
ARM64 gcc 9.5
ARM64 gcc trunk
ARM64 msvc v19.14 (ex-WINE)
AVR gcc 10.3.0
AVR gcc 11.1.0
AVR gcc 12.1.0
AVR gcc 12.2.0
AVR gcc 12.3.0
AVR gcc 12.4.0
AVR gcc 12.5.0
AVR gcc 13.1.0
AVR gcc 13.2.0
AVR gcc 13.3.0
AVR gcc 13.4.0
AVR gcc 14.1.0
AVR gcc 14.2.0
AVR gcc 14.3.0
AVR gcc 15.1.0
AVR gcc 15.2.0
AVR gcc 4.5.4
AVR gcc 4.6.4
AVR gcc 5.4.0
AVR gcc 9.2.0
AVR gcc 9.3.0
Arduino Mega (1.8.9)
Arduino Uno (1.8.9)
BPF clang (trunk)
BPF clang 13.0.0
BPF clang 14.0.0
BPF clang 15.0.0
BPF clang 16.0.0
BPF clang 17.0.1
BPF clang 18.1.0
BPF clang 19.1.0
BPF clang 20.1.0
BPF clang 21.1.0
EDG (experimental reflection)
EDG 6.5
EDG 6.5 (GNU mode gcc 13)
EDG 6.6
EDG 6.6 (GNU mode gcc 13)
EDG 6.7
EDG 6.7 (GNU mode gcc 14)
FRC 2019
FRC 2020
FRC 2023
HPPA gcc 14.2.0
HPPA gcc 14.3.0
HPPA gcc 15.1.0
HPPA gcc 15.2.0
KVX ACB 4.1.0 (GCC 7.5.0)
KVX ACB 4.1.0-cd1 (GCC 7.5.0)
KVX ACB 4.10.0 (GCC 10.3.1)
KVX ACB 4.11.1 (GCC 10.3.1)
KVX ACB 4.12.0 (GCC 11.3.0)
KVX ACB 4.2.0 (GCC 7.5.0)
KVX ACB 4.3.0 (GCC 7.5.0)
KVX ACB 4.4.0 (GCC 7.5.0)
KVX ACB 4.6.0 (GCC 9.4.1)
KVX ACB 4.8.0 (GCC 9.4.1)
KVX ACB 4.9.0 (GCC 9.4.1)
KVX ACB 5.0.0 (GCC 12.2.1)
KVX ACB 5.2.0 (GCC 13.2.1)
LoongArch64 clang (trunk)
LoongArch64 clang 17.0.1
LoongArch64 clang 18.1.0
LoongArch64 clang 19.1.0
LoongArch64 clang 20.1.0
LoongArch64 clang 21.1.0
M68K gcc 13.1.0
M68K gcc 13.2.0
M68K gcc 13.3.0
M68K gcc 13.4.0
M68K gcc 14.1.0
M68K gcc 14.2.0
M68K gcc 14.3.0
M68K gcc 15.1.0
M68K gcc 15.2.0
M68k clang (trunk)
MRISC32 gcc (trunk)
MSP430 gcc 4.5.3
MSP430 gcc 5.3.0
MSP430 gcc 6.2.1
MinGW clang 14.0.3
MinGW clang 14.0.6
MinGW clang 15.0.7
MinGW clang 16.0.0
MinGW clang 16.0.2
MinGW gcc 11.3.0
MinGW gcc 12.1.0
MinGW gcc 12.2.0
MinGW gcc 13.1.0
MinGW gcc 14.3.0
MinGW gcc 15.2.0
RISC-V (32-bits) gcc (trunk)
RISC-V (32-bits) gcc 10.2.0
RISC-V (32-bits) gcc 10.3.0
RISC-V (32-bits) gcc 11.2.0
RISC-V (32-bits) gcc 11.3.0
RISC-V (32-bits) gcc 11.4.0
RISC-V (32-bits) gcc 12.1.0
RISC-V (32-bits) gcc 12.2.0
RISC-V (32-bits) gcc 12.3.0
RISC-V (32-bits) gcc 12.4.0
RISC-V (32-bits) gcc 12.5.0
RISC-V (32-bits) gcc 13.1.0
RISC-V (32-bits) gcc 13.2.0
RISC-V (32-bits) gcc 13.3.0
RISC-V (32-bits) gcc 13.4.0
RISC-V (32-bits) gcc 14.1.0
RISC-V (32-bits) gcc 14.2.0
RISC-V (32-bits) gcc 14.3.0
RISC-V (32-bits) gcc 15.1.0
RISC-V (32-bits) gcc 15.2.0
RISC-V (32-bits) gcc 8.2.0
RISC-V (32-bits) gcc 8.5.0
RISC-V (32-bits) gcc 9.4.0
RISC-V (64-bits) gcc (trunk)
RISC-V (64-bits) gcc 10.2.0
RISC-V (64-bits) gcc 10.3.0
RISC-V (64-bits) gcc 11.2.0
RISC-V (64-bits) gcc 11.3.0
RISC-V (64-bits) gcc 11.4.0
RISC-V (64-bits) gcc 12.1.0
RISC-V (64-bits) gcc 12.2.0
RISC-V (64-bits) gcc 12.3.0
RISC-V (64-bits) gcc 12.4.0
RISC-V (64-bits) gcc 12.5.0
RISC-V (64-bits) gcc 13.1.0
RISC-V (64-bits) gcc 13.2.0
RISC-V (64-bits) gcc 13.3.0
RISC-V (64-bits) gcc 13.4.0
RISC-V (64-bits) gcc 14.1.0
RISC-V (64-bits) gcc 14.2.0
RISC-V (64-bits) gcc 14.3.0
RISC-V (64-bits) gcc 15.1.0
RISC-V (64-bits) gcc 15.2.0
RISC-V (64-bits) gcc 8.2.0
RISC-V (64-bits) gcc 8.5.0
RISC-V (64-bits) gcc 9.4.0
RISC-V rv32gc clang (trunk)
RISC-V rv32gc clang 10.0.0
RISC-V rv32gc clang 10.0.1
RISC-V rv32gc clang 11.0.0
RISC-V rv32gc clang 11.0.1
RISC-V rv32gc clang 12.0.0
RISC-V rv32gc clang 12.0.1
RISC-V rv32gc clang 13.0.0
RISC-V rv32gc clang 13.0.1
RISC-V rv32gc clang 14.0.0
RISC-V rv32gc clang 15.0.0
RISC-V rv32gc clang 16.0.0
RISC-V rv32gc clang 17.0.1
RISC-V rv32gc clang 18.1.0
RISC-V rv32gc clang 19.1.0
RISC-V rv32gc clang 20.1.0
RISC-V rv32gc clang 21.1.0
RISC-V rv32gc clang 9.0.0
RISC-V rv32gc clang 9.0.1
RISC-V rv64gc clang (trunk)
RISC-V rv64gc clang 10.0.0
RISC-V rv64gc clang 10.0.1
RISC-V rv64gc clang 11.0.0
RISC-V rv64gc clang 11.0.1
RISC-V rv64gc clang 12.0.0
RISC-V rv64gc clang 12.0.1
RISC-V rv64gc clang 13.0.0
RISC-V rv64gc clang 13.0.1
RISC-V rv64gc clang 14.0.0
RISC-V rv64gc clang 15.0.0
RISC-V rv64gc clang 16.0.0
RISC-V rv64gc clang 17.0.1
RISC-V rv64gc clang 18.1.0
RISC-V rv64gc clang 19.1.0
RISC-V rv64gc clang 20.1.0
RISC-V rv64gc clang 21.1.0
RISC-V rv64gc clang 9.0.0
RISC-V rv64gc clang 9.0.1
Raspbian Buster
Raspbian Stretch
SPARC LEON gcc 12.2.0
SPARC LEON gcc 12.3.0
SPARC LEON gcc 12.4.0
SPARC LEON gcc 12.5.0
SPARC LEON gcc 13.1.0
SPARC LEON gcc 13.2.0
SPARC LEON gcc 13.3.0
SPARC LEON gcc 13.4.0
SPARC LEON gcc 14.1.0
SPARC LEON gcc 14.2.0
SPARC LEON gcc 14.3.0
SPARC LEON gcc 15.1.0
SPARC LEON gcc 15.2.0
SPARC gcc 12.2.0
SPARC gcc 12.3.0
SPARC gcc 12.4.0
SPARC gcc 12.5.0
SPARC gcc 13.1.0
SPARC gcc 13.2.0
SPARC gcc 13.3.0
SPARC gcc 13.4.0
SPARC gcc 14.1.0
SPARC gcc 14.2.0
SPARC gcc 14.3.0
SPARC gcc 15.1.0
SPARC gcc 15.2.0
SPARC64 gcc 12.2.0
SPARC64 gcc 12.3.0
SPARC64 gcc 12.4.0
SPARC64 gcc 12.5.0
SPARC64 gcc 13.1.0
SPARC64 gcc 13.2.0
SPARC64 gcc 13.3.0
SPARC64 gcc 13.4.0
SPARC64 gcc 14.1.0
SPARC64 gcc 14.2.0
SPARC64 gcc 14.3.0
SPARC64 gcc 15.1.0
SPARC64 gcc 15.2.0
TI C6x gcc 12.2.0
TI C6x gcc 12.3.0
TI C6x gcc 12.4.0
TI C6x gcc 12.5.0
TI C6x gcc 13.1.0
TI C6x gcc 13.2.0
TI C6x gcc 13.3.0
TI C6x gcc 13.4.0
TI C6x gcc 14.1.0
TI C6x gcc 14.2.0
TI C6x gcc 14.3.0
TI C6x gcc 15.1.0
TI C6x gcc 15.2.0
TI CL430 21.6.1
Tricore gcc 11.3.0 (EEESlab)
VAX gcc NetBSDELF 10.4.0
VAX gcc NetBSDELF 10.5.0 (Nov 15 03:50:22 2023)
VAX gcc NetBSDELF 12.4.0 (Apr 16 05:27 2025)
WebAssembly clang (trunk)
Xtensa ESP32 gcc 11.2.0 (2022r1)
Xtensa ESP32 gcc 12.2.0 (20230208)
Xtensa ESP32 gcc 14.2.0 (20241119)
Xtensa ESP32 gcc 8.2.0 (2019r2)
Xtensa ESP32 gcc 8.2.0 (2020r1)
Xtensa ESP32 gcc 8.2.0 (2020r2)
Xtensa ESP32 gcc 8.4.0 (2020r3)
Xtensa ESP32 gcc 8.4.0 (2021r1)
Xtensa ESP32 gcc 8.4.0 (2021r2)
Xtensa ESP32-S2 gcc 11.2.0 (2022r1)
Xtensa ESP32-S2 gcc 12.2.0 (20230208)
Xtensa ESP32-S2 gcc 14.2.0 (20241119)
Xtensa ESP32-S2 gcc 8.2.0 (2019r2)
Xtensa ESP32-S2 gcc 8.2.0 (2020r1)
Xtensa ESP32-S2 gcc 8.2.0 (2020r2)
Xtensa ESP32-S2 gcc 8.4.0 (2020r3)
Xtensa ESP32-S2 gcc 8.4.0 (2021r1)
Xtensa ESP32-S2 gcc 8.4.0 (2021r2)
Xtensa ESP32-S3 gcc 11.2.0 (2022r1)
Xtensa ESP32-S3 gcc 12.2.0 (20230208)
Xtensa ESP32-S3 gcc 14.2.0 (20241119)
Xtensa ESP32-S3 gcc 8.4.0 (2020r3)
Xtensa ESP32-S3 gcc 8.4.0 (2021r1)
Xtensa ESP32-S3 gcc 8.4.0 (2021r2)
arm64 msvc v19.20 VS16.0
arm64 msvc v19.21 VS16.1
arm64 msvc v19.22 VS16.2
arm64 msvc v19.23 VS16.3
arm64 msvc v19.24 VS16.4
arm64 msvc v19.25 VS16.5
arm64 msvc v19.27 VS16.7
arm64 msvc v19.28 VS16.8
arm64 msvc v19.28 VS16.9
arm64 msvc v19.29 VS16.10
arm64 msvc v19.29 VS16.11
arm64 msvc v19.30 VS17.0
arm64 msvc v19.31 VS17.1
arm64 msvc v19.32 VS17.2
arm64 msvc v19.33 VS17.3
arm64 msvc v19.34 VS17.4
arm64 msvc v19.35 VS17.5
arm64 msvc v19.36 VS17.6
arm64 msvc v19.37 VS17.7
arm64 msvc v19.38 VS17.8
arm64 msvc v19.39 VS17.9
arm64 msvc v19.40 VS17.10
arm64 msvc v19.41 VS17.11
arm64 msvc v19.42 VS17.12
arm64 msvc v19.43 VS17.13
arm64 msvc v19.44 VS17.14
arm64 msvc v19.latest
armv7-a clang (trunk)
armv7-a clang 10.0.0
armv7-a clang 10.0.1
armv7-a clang 11.0.0
armv7-a clang 11.0.1
armv7-a clang 12.0.0
armv7-a clang 12.0.1
armv7-a clang 13.0.0
armv7-a clang 13.0.1
armv7-a clang 14.0.0
armv7-a clang 15.0.0
armv7-a clang 16.0.0
armv7-a clang 17.0.1
armv7-a clang 18.1.0
armv7-a clang 19.1.0
armv7-a clang 20.1.0
armv7-a clang 21.1.0
armv7-a clang 9.0.0
armv7-a clang 9.0.1
armv8-a clang (all architectural features, trunk)
armv8-a clang (trunk)
armv8-a clang 10.0.0
armv8-a clang 10.0.1
armv8-a clang 11.0.0
armv8-a clang 11.0.1
armv8-a clang 12.0.0
armv8-a clang 13.0.0
armv8-a clang 14.0.0
armv8-a clang 15.0.0
armv8-a clang 16.0.0
armv8-a clang 17.0.1
armv8-a clang 18.1.0
armv8-a clang 19.1.0
armv8-a clang 20.1.0
armv8-a clang 21.1.0
armv8-a clang 9.0.0
armv8-a clang 9.0.1
clad trunk (clang 21.1.0)
clad v1.10 (clang 20.1.0)
clad v1.8 (clang 18.1.0)
clad v1.9 (clang 19.1.0)
clad v2.00 (clang 20.1.0)
clad v2.1 (clang 21.1.0)
clang-cl 18.1.0
ellcc 0.1.33
ellcc 0.1.34
ellcc 2017-07-16
ez80-clang 15.0.0
ez80-clang 15.0.7
hexagon-clang 16.0.5
llvm-mos atari2600-3e
llvm-mos atari2600-4k
llvm-mos atari2600-common
llvm-mos atari5200-supercart
llvm-mos atari8-cart-megacart
llvm-mos atari8-cart-std
llvm-mos atari8-cart-xegs
llvm-mos atari8-common
llvm-mos atari8-dos
llvm-mos c128
llvm-mos c64
llvm-mos commodore
llvm-mos cpm65
llvm-mos cx16
llvm-mos dodo
llvm-mos eater
llvm-mos mega65
llvm-mos nes
llvm-mos nes-action53
llvm-mos nes-cnrom
llvm-mos nes-gtrom
llvm-mos nes-mmc1
llvm-mos nes-mmc3
llvm-mos nes-nrom
llvm-mos nes-unrom
llvm-mos nes-unrom-512
llvm-mos osi-c1p
llvm-mos pce
llvm-mos pce-cd
llvm-mos pce-common
llvm-mos pet
llvm-mos rp6502
llvm-mos rpc8e
llvm-mos supervision
llvm-mos vic20
loongarch64 gcc 12.2.0
loongarch64 gcc 12.3.0
loongarch64 gcc 12.4.0
loongarch64 gcc 12.5.0
loongarch64 gcc 13.1.0
loongarch64 gcc 13.2.0
loongarch64 gcc 13.3.0
loongarch64 gcc 13.4.0
loongarch64 gcc 14.1.0
loongarch64 gcc 14.2.0
loongarch64 gcc 14.3.0
loongarch64 gcc 15.1.0
loongarch64 gcc 15.2.0
mips clang 13.0.0
mips clang 14.0.0
mips clang 15.0.0
mips clang 16.0.0
mips clang 17.0.1
mips clang 18.1.0
mips clang 19.1.0
mips clang 20.1.0
mips clang 21.1.0
mips gcc 11.2.0
mips gcc 12.1.0
mips gcc 12.2.0
mips gcc 12.3.0
mips gcc 12.4.0
mips gcc 12.5.0
mips gcc 13.1.0
mips gcc 13.2.0
mips gcc 13.3.0
mips gcc 13.4.0
mips gcc 14.1.0
mips gcc 14.2.0
mips gcc 14.3.0
mips gcc 15.1.0
mips gcc 15.2.0
mips gcc 4.9.4
mips gcc 5.4
mips gcc 5.5.0
mips gcc 9.3.0 (codescape)
mips gcc 9.5.0
mips64 (el) gcc 12.1.0
mips64 (el) gcc 12.2.0
mips64 (el) gcc 12.3.0
mips64 (el) gcc 12.4.0
mips64 (el) gcc 12.5.0
mips64 (el) gcc 13.1.0
mips64 (el) gcc 13.2.0
mips64 (el) gcc 13.3.0
mips64 (el) gcc 13.4.0
mips64 (el) gcc 14.1.0
mips64 (el) gcc 14.2.0
mips64 (el) gcc 14.3.0
mips64 (el) gcc 15.1.0
mips64 (el) gcc 15.2.0
mips64 (el) gcc 4.9.4
mips64 (el) gcc 5.4.0
mips64 (el) gcc 5.5.0
mips64 (el) gcc 9.5.0
mips64 clang 13.0.0
mips64 clang 14.0.0
mips64 clang 15.0.0
mips64 clang 16.0.0
mips64 clang 17.0.1
mips64 clang 18.1.0
mips64 clang 19.1.0
mips64 clang 20.1.0
mips64 clang 21.1.0
mips64 gcc 11.2.0
mips64 gcc 12.1.0
mips64 gcc 12.2.0
mips64 gcc 12.3.0
mips64 gcc 12.4.0
mips64 gcc 12.5.0
mips64 gcc 13.1.0
mips64 gcc 13.2.0
mips64 gcc 13.3.0
mips64 gcc 13.4.0
mips64 gcc 14.1.0
mips64 gcc 14.2.0
mips64 gcc 14.3.0
mips64 gcc 15.1.0
mips64 gcc 15.2.0
mips64 gcc 4.9.4
mips64 gcc 5.4.0
mips64 gcc 5.5.0
mips64 gcc 9.5.0
mips64el clang 13.0.0
mips64el clang 14.0.0
mips64el clang 15.0.0
mips64el clang 16.0.0
mips64el clang 17.0.1
mips64el clang 18.1.0
mips64el clang 19.1.0
mips64el clang 20.1.0
mips64el clang 21.1.0
mipsel clang 13.0.0
mipsel clang 14.0.0
mipsel clang 15.0.0
mipsel clang 16.0.0
mipsel clang 17.0.1
mipsel clang 18.1.0
mipsel clang 19.1.0
mipsel clang 20.1.0
mipsel clang 21.1.0
mipsel gcc 12.1.0
mipsel gcc 12.2.0
mipsel gcc 12.3.0
mipsel gcc 12.4.0
mipsel gcc 12.5.0
mipsel gcc 13.1.0
mipsel gcc 13.2.0
mipsel gcc 13.3.0
mipsel gcc 13.4.0
mipsel gcc 14.1.0
mipsel gcc 14.2.0
mipsel gcc 14.3.0
mipsel gcc 15.1.0
mipsel gcc 15.2.0
mipsel gcc 4.9.4
mipsel gcc 5.4.0
mipsel gcc 5.5.0
mipsel gcc 9.5.0
nanoMIPS gcc 6.3.0 (mtk)
power gcc 11.2.0
power gcc 12.1.0
power gcc 12.2.0
power gcc 12.3.0
power gcc 12.4.0
power gcc 12.5.0
power gcc 13.1.0
power gcc 13.2.0
power gcc 13.3.0
power gcc 13.4.0
power gcc 14.1.0
power gcc 14.2.0
power gcc 14.3.0
power gcc 15.1.0
power gcc 15.2.0
power gcc 4.8.5
power64 AT12.0 (gcc8)
power64 AT13.0 (gcc9)
power64 gcc 11.2.0
power64 gcc 12.1.0
power64 gcc 12.2.0
power64 gcc 12.3.0
power64 gcc 12.4.0
power64 gcc 12.5.0
power64 gcc 13.1.0
power64 gcc 13.2.0
power64 gcc 13.3.0
power64 gcc 13.4.0
power64 gcc 14.1.0
power64 gcc 14.2.0
power64 gcc 14.3.0
power64 gcc 15.1.0
power64 gcc 15.2.0
power64 gcc trunk
power64le AT12.0 (gcc8)
power64le AT13.0 (gcc9)
power64le clang (trunk)
power64le gcc 11.2.0
power64le gcc 12.1.0
power64le gcc 12.2.0
power64le gcc 12.3.0
power64le gcc 12.4.0
power64le gcc 12.5.0
power64le gcc 13.1.0
power64le gcc 13.2.0
power64le gcc 13.3.0
power64le gcc 13.4.0
power64le gcc 14.1.0
power64le gcc 14.2.0
power64le gcc 14.3.0
power64le gcc 15.1.0
power64le gcc 15.2.0
power64le gcc 6.3.0
power64le gcc trunk
powerpc64 clang (trunk)
qnx 8.0.0
s390x gcc 11.2.0
s390x gcc 12.1.0
s390x gcc 12.2.0
s390x gcc 12.3.0
s390x gcc 12.4.0
s390x gcc 12.5.0
s390x gcc 13.1.0
s390x gcc 13.2.0
s390x gcc 13.3.0
s390x gcc 13.4.0
s390x gcc 14.1.0
s390x gcc 14.2.0
s390x gcc 14.3.0
s390x gcc 15.1.0
s390x gcc 15.2.0
sh gcc 12.2.0
sh gcc 12.3.0
sh gcc 12.4.0
sh gcc 12.5.0
sh gcc 13.1.0
sh gcc 13.2.0
sh gcc 13.3.0
sh gcc 13.4.0
sh gcc 14.1.0
sh gcc 14.2.0
sh gcc 14.3.0
sh gcc 15.1.0
sh gcc 15.2.0
sh gcc 4.9.4
sh gcc 9.5.0
vast (trunk)
x64 msvc v19.0 (ex-WINE)
x64 msvc v19.10 (ex-WINE)
x64 msvc v19.14 (ex-WINE)
x64 msvc v19.20 VS16.0
x64 msvc v19.21 VS16.1
x64 msvc v19.22 VS16.2
x64 msvc v19.23 VS16.3
x64 msvc v19.24 VS16.4
x64 msvc v19.25 VS16.5
x64 msvc v19.27 VS16.7
x64 msvc v19.28 VS16.8
x64 msvc v19.28 VS16.9
x64 msvc v19.29 VS16.10
x64 msvc v19.29 VS16.11
x64 msvc v19.30 VS17.0
x64 msvc v19.31 VS17.1
x64 msvc v19.32 VS17.2
x64 msvc v19.33 VS17.3
x64 msvc v19.34 VS17.4
x64 msvc v19.35 VS17.5
x64 msvc v19.36 VS17.6
x64 msvc v19.37 VS17.7
x64 msvc v19.38 VS17.8
x64 msvc v19.39 VS17.9
x64 msvc v19.40 VS17.10
x64 msvc v19.41 VS17.11
x64 msvc v19.42 VS17.12
x64 msvc v19.43 VS17.13
x64 msvc v19.44 VS17.14
x64 msvc v19.latest
x86 djgpp 4.9.4
x86 djgpp 5.5.0
x86 djgpp 6.4.0
x86 djgpp 7.2.0
x86 g++ 1.27
x86 msvc v19.0 (ex-WINE)
x86 msvc v19.10 (ex-WINE)
x86 msvc v19.14 (ex-WINE)
x86 msvc v19.20 VS16.0
x86 msvc v19.21 VS16.1
x86 msvc v19.22 VS16.2
x86 msvc v19.23 VS16.3
x86 msvc v19.24 VS16.4
x86 msvc v19.25 VS16.5
x86 msvc v19.27 VS16.7
x86 msvc v19.28 VS16.8
x86 msvc v19.28 VS16.9
x86 msvc v19.29 VS16.10
x86 msvc v19.29 VS16.11
x86 msvc v19.30 VS17.0
x86 msvc v19.31 VS17.1
x86 msvc v19.32 VS17.2
x86 msvc v19.33 VS17.3
x86 msvc v19.34 VS17.4
x86 msvc v19.35 VS17.5
x86 msvc v19.36 VS17.6
x86 msvc v19.37 VS17.7
x86 msvc v19.38 VS17.8
x86 msvc v19.39 VS17.9
x86 msvc v19.40 VS17.10
x86 msvc v19.41 VS17.11
x86 msvc v19.42 VS17.12
x86 msvc v19.43 VS17.13
x86 msvc v19.44 VS17.14
x86 msvc v19.latest
x86 nvc++ 22.11
x86 nvc++ 22.7
x86 nvc++ 22.9
x86 nvc++ 23.1
x86 nvc++ 23.11
x86 nvc++ 23.3
x86 nvc++ 23.5
x86 nvc++ 23.7
x86 nvc++ 23.9
x86 nvc++ 24.1
x86 nvc++ 24.11
x86 nvc++ 24.3
x86 nvc++ 24.5
x86 nvc++ 24.7
x86 nvc++ 24.9
x86 nvc++ 25.1
x86 nvc++ 25.3
x86 nvc++ 25.5
x86 nvc++ 25.7
x86 nvc++ 25.9
x86-64 Zapcc 190308
x86-64 clang (-fimplicit-constexpr)
x86-64 clang (Chris Bazley N3089)
x86-64 clang (EricWF contracts)
x86-64 clang (amd-staging)
x86-64 clang (assertions trunk)
x86-64 clang (clangir)
x86-64 clang (experimental -Wlifetime)
x86-64 clang (experimental P1061)
x86-64 clang (experimental P1144)
x86-64 clang (experimental P1221)
x86-64 clang (experimental P2561)
x86-64 clang (experimental P2998)
x86-64 clang (experimental P3068)
x86-64 clang (experimental P3309)
x86-64 clang (experimental P3334)
x86-64 clang (experimental P3367)
x86-64 clang (experimental P3372)
x86-64 clang (experimental P3385)
x86-64 clang (experimental P3776)
x86-64 clang (experimental metaprogramming - P2632)
x86-64 clang (old concepts branch)
x86-64 clang (p1974)
x86-64 clang (pattern matching - P2688)
x86-64 clang (reflection - C++26)
x86-64 clang (reflection - TS)
x86-64 clang (resugar)
x86-64 clang (string interpolation - P3412)
x86-64 clang (thephd.dev)
x86-64 clang (trunk)
x86-64 clang (variadic friends - P2893)
x86-64 clang (widberg)
x86-64 clang 10.0.0
x86-64 clang 10.0.0 (assertions)
x86-64 clang 10.0.1
x86-64 clang 11.0.0
x86-64 clang 11.0.0 (assertions)
x86-64 clang 11.0.1
x86-64 clang 12.0.0
x86-64 clang 12.0.0 (assertions)
x86-64 clang 12.0.1
x86-64 clang 13.0.0
x86-64 clang 13.0.0 (assertions)
x86-64 clang 13.0.1
x86-64 clang 14.0.0
x86-64 clang 14.0.0 (assertions)
x86-64 clang 15.0.0
x86-64 clang 15.0.0 (assertions)
x86-64 clang 16.0.0
x86-64 clang 16.0.0 (assertions)
x86-64 clang 17.0.1
x86-64 clang 17.0.1 (assertions)
x86-64 clang 18.1.0
x86-64 clang 18.1.0 (assertions)
x86-64 clang 19.1.0
x86-64 clang 19.1.0 (assertions)
x86-64 clang 2.6.0 (assertions)
x86-64 clang 2.7.0 (assertions)
x86-64 clang 2.8.0 (assertions)
x86-64 clang 2.9.0 (assertions)
x86-64 clang 20.1.0
x86-64 clang 20.1.0 (assertions)
x86-64 clang 21.1.0
x86-64 clang 21.1.0 (assertions)
x86-64 clang 3.0.0
x86-64 clang 3.0.0 (assertions)
x86-64 clang 3.1
x86-64 clang 3.1 (assertions)
x86-64 clang 3.2
x86-64 clang 3.2 (assertions)
x86-64 clang 3.3
x86-64 clang 3.3 (assertions)
x86-64 clang 3.4 (assertions)
x86-64 clang 3.4.1
x86-64 clang 3.5
x86-64 clang 3.5 (assertions)
x86-64 clang 3.5.1
x86-64 clang 3.5.2
x86-64 clang 3.6
x86-64 clang 3.6 (assertions)
x86-64 clang 3.7
x86-64 clang 3.7 (assertions)
x86-64 clang 3.7.1
x86-64 clang 3.8
x86-64 clang 3.8 (assertions)
x86-64 clang 3.8.1
x86-64 clang 3.9.0
x86-64 clang 3.9.0 (assertions)
x86-64 clang 3.9.1
x86-64 clang 4.0.0
x86-64 clang 4.0.0 (assertions)
x86-64 clang 4.0.1
x86-64 clang 5.0.0
x86-64 clang 5.0.0 (assertions)
x86-64 clang 5.0.1
x86-64 clang 5.0.2
x86-64 clang 6.0.0
x86-64 clang 6.0.0 (assertions)
x86-64 clang 6.0.1
x86-64 clang 7.0.0
x86-64 clang 7.0.0 (assertions)
x86-64 clang 7.0.1
x86-64 clang 7.1.0
x86-64 clang 8.0.0
x86-64 clang 8.0.0 (assertions)
x86-64 clang 8.0.1
x86-64 clang 9.0.0
x86-64 clang 9.0.0 (assertions)
x86-64 clang 9.0.1
x86-64 clang rocm-4.5.2
x86-64 clang rocm-5.0.2
x86-64 clang rocm-5.1.3
x86-64 clang rocm-5.2.3
x86-64 clang rocm-5.3.3
x86-64 clang rocm-5.7.0
x86-64 clang rocm-6.0.2
x86-64 clang rocm-6.1.2
x86-64 clang rocm-6.2.4
x86-64 clang rocm-6.3.3
x86-64 clang rocm-6.4.0
x86-64 clang rocm-7.0.1
x86-64 gcc (C++26 contracts + GNU extensions)
x86-64 gcc (C++26 contracts)
x86-64 gcc (C++26 reflection)
x86-64 gcc (P2034 lambdas)
x86-64 gcc (Thomas Healy)
x86-64 gcc (contract labels)
x86-64 gcc (contracts natural syntax)
x86-64 gcc (contracts)
x86-64 gcc (coroutines)
x86-64 gcc (modules)
x86-64 gcc (trunk)
x86-64 gcc 10.1
x86-64 gcc 10.2
x86-64 gcc 10.3
x86-64 gcc 10.3 (assertions)
x86-64 gcc 10.4
x86-64 gcc 10.4 (assertions)
x86-64 gcc 10.5
x86-64 gcc 10.5 (assertions)
x86-64 gcc 11.1
x86-64 gcc 11.1 (assertions)
x86-64 gcc 11.2
x86-64 gcc 11.2 (assertions)
x86-64 gcc 11.3
x86-64 gcc 11.3 (assertions)
x86-64 gcc 11.4
x86-64 gcc 11.4 (assertions)
x86-64 gcc 12.1
x86-64 gcc 12.1 (assertions)
x86-64 gcc 12.2
x86-64 gcc 12.2 (assertions)
x86-64 gcc 12.3
x86-64 gcc 12.3 (assertions)
x86-64 gcc 12.4
x86-64 gcc 12.4 (assertions)
x86-64 gcc 12.5
x86-64 gcc 12.5 (assertions)
x86-64 gcc 13.1
x86-64 gcc 13.1 (assertions)
x86-64 gcc 13.2
x86-64 gcc 13.2 (assertions)
x86-64 gcc 13.3
x86-64 gcc 13.3 (assertions)
x86-64 gcc 13.4
x86-64 gcc 13.4 (assertions)
x86-64 gcc 14.1
x86-64 gcc 14.1 (assertions)
x86-64 gcc 14.2
x86-64 gcc 14.2 (assertions)
x86-64 gcc 14.3
x86-64 gcc 14.3 (assertions)
x86-64 gcc 15.1
x86-64 gcc 15.1 (assertions)
x86-64 gcc 15.2
x86-64 gcc 15.2 (assertions)
x86-64 gcc 3.4.6
x86-64 gcc 4.0.4
x86-64 gcc 4.1.2
x86-64 gcc 4.4.7
x86-64 gcc 4.5.3
x86-64 gcc 4.6.4
x86-64 gcc 4.7.1
x86-64 gcc 4.7.2
x86-64 gcc 4.7.3
x86-64 gcc 4.7.4
x86-64 gcc 4.8.1
x86-64 gcc 4.8.2
x86-64 gcc 4.8.3
x86-64 gcc 4.8.4
x86-64 gcc 4.8.5
x86-64 gcc 4.9.0
x86-64 gcc 4.9.1
x86-64 gcc 4.9.2
x86-64 gcc 4.9.3
x86-64 gcc 4.9.4
x86-64 gcc 5.1
x86-64 gcc 5.2
x86-64 gcc 5.3
x86-64 gcc 5.4
x86-64 gcc 5.5
x86-64 gcc 6.1
x86-64 gcc 6.2
x86-64 gcc 6.3
x86-64 gcc 6.4
x86-64 gcc 6.5
x86-64 gcc 7.1
x86-64 gcc 7.2
x86-64 gcc 7.3
x86-64 gcc 7.4
x86-64 gcc 7.5
x86-64 gcc 8.1
x86-64 gcc 8.2
x86-64 gcc 8.3
x86-64 gcc 8.4
x86-64 gcc 8.5
x86-64 gcc 9.1
x86-64 gcc 9.2
x86-64 gcc 9.3
x86-64 gcc 9.4
x86-64 gcc 9.5
x86-64 icc 13.0.1
x86-64 icc 16.0.3
x86-64 icc 17.0.0
x86-64 icc 18.0.0
x86-64 icc 19.0.0
x86-64 icc 19.0.1
x86-64 icc 2021.1.2
x86-64 icc 2021.10.0
x86-64 icc 2021.2.0
x86-64 icc 2021.3.0
x86-64 icc 2021.4.0
x86-64 icc 2021.5.0
x86-64 icc 2021.6.0
x86-64 icc 2021.7.0
x86-64 icc 2021.7.1
x86-64 icc 2021.8.0
x86-64 icc 2021.9.0
x86-64 icx 2021.1.2
x86-64 icx 2021.2.0
x86-64 icx 2021.3.0
x86-64 icx 2021.4.0
x86-64 icx 2022.0.0
x86-64 icx 2022.1.0
x86-64 icx 2022.2.0
x86-64 icx 2022.2.1
x86-64 icx 2023.0.0
x86-64 icx 2023.1.0
x86-64 icx 2023.2.1
x86-64 icx 2024.0.0
x86-64 icx 2024.1.0
x86-64 icx 2024.2.0
x86-64 icx 2024.2.1
x86-64 icx 2025.0.0
x86-64 icx 2025.0.1
x86-64 icx 2025.0.3
x86-64 icx 2025.0.4
x86-64 icx 2025.1.0
x86-64 icx 2025.1.1
x86-64 icx 2025.2.0
x86-64 icx 2025.2.1
x86-64 icx 2025.2.1
z180-clang 15.0.0
z180-clang 15.0.7
z80-clang 15.0.0
z80-clang 15.0.7
zig c++ 0.10.0
zig c++ 0.11.0
zig c++ 0.12.0
zig c++ 0.12.1
zig c++ 0.13.0
zig c++ 0.14.0
zig c++ 0.14.1
zig c++ 0.15.1
zig c++ 0.15.2
zig c++ 0.6.0
zig c++ 0.7.0
zig c++ 0.7.1
zig c++ 0.8.0
zig c++ 0.9.0
zig c++ trunk
Options
Source code
# 1 "<built-in>" # 1 "core.c" //#include <time.h> #if 0 #include <errno.h> #endif # 9 "core.c" # 1 "/usr/include/errno.h" 1 3 4 #ifndef _SYS_ERRNO_H_ #define _SYS_ERRNO_H_ #if 0 #include <sys/cdefs.h> #endif # 41 "/usr/include/errno.h" 3 4 # 1 "/usr/include/sys/cdefs.h" 1 3 4 #ifndef _SYS_CDEFS_H_ #define _SYS_CDEFS_H_ #ifndef __has_attribute #define __has_attribute(x) 0 #endif # 45 "/usr/include/sys/cdefs.h" 3 4 #ifndef __has_extension #define __has_extension __has_feature #endif # 48 "/usr/include/sys/cdefs.h" 3 4 #ifndef __has_feature #define __has_feature(x) 0 #endif # 51 "/usr/include/sys/cdefs.h" 3 4 #ifndef __has_include #define __has_include(x) 0 #endif # 54 "/usr/include/sys/cdefs.h" 3 4 #ifndef __has_builtin #define __has_builtin(x) 0 #endif # 57 "/usr/include/sys/cdefs.h" 3 4 #if defined(__GNUC__) && !defined(__INTEL_COMPILER) #define __GNUC_PREREQ__(ma, mi) \ (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) #else # 65 "/usr/include/sys/cdefs.h" 3 4 #define __GNUC_PREREQ__(ma, mi) 0 #endif # 67 "/usr/include/sys/cdefs.h" 3 4 #if defined(__cplusplus) #if __GNUC_PREREQ__(4, 0) #define __BEGIN_DECLS _Pragma("GCC visibility push(default)") extern "C" { #define __END_DECLS } _Pragma("GCC visibility pop") #else # 73 "/usr/include/sys/cdefs.h" 3 4 #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #endif # 76 "/usr/include/sys/cdefs.h" 3 4 #else # 77 "/usr/include/sys/cdefs.h" 3 4 #define __BEGIN_DECLS #define __END_DECLS #endif # 80 "/usr/include/sys/cdefs.h" 3 4 #define __VM_CACHELINE_SIZE 64 #define __VM_CACHELINE_MASK (__VM_CACHELINE_SIZE - 1) #define __VM_CACHELINE_ALIGN(n) \ (((n) + __VM_CACHELINE_MASK) & ~__VM_CACHELINE_MASK) #if defined(__STDC__) || defined(__cplusplus) #define __P(protos) protos #define __CONCAT1(x,y) x ## y #define __CONCAT(x,y) __CONCAT1(x,y) #define __STRING(x) #x #define __XSTRING(x) __STRING(x) #define __const const #define __signed signed #define __volatile volatile #if defined(__cplusplus) #define __inline inline #else # 123 "/usr/include/sys/cdefs.h" 3 4 #ifndef __GNUC__ #define __inline #endif # 126 "/usr/include/sys/cdefs.h" 3 4 #endif # 127 "/usr/include/sys/cdefs.h" 3 4 #else # 129 "/usr/include/sys/cdefs.h" 3 4 #define __P(protos) () #define __CONCAT(x,y) xy #define __STRING(x) "x" #ifndef __GNUC__ #define __const #define __inline #define __signed #define __volatile #ifndef NO_ANSI_KEYWORDS #define const #define inline #define signed #define volatile #endif # 152 "/usr/include/sys/cdefs.h" 3 4 #endif # 153 "/usr/include/sys/cdefs.h" 3 4 #endif # 154 "/usr/include/sys/cdefs.h" 3 4 #define __weak_symbol __attribute__((__weak__)) #if __GNUC_PREREQ__(2, 7) #define __dead2 __attribute__((__noreturn__)) #define __pure2 __attribute__((__const__)) #define __unused __attribute__((__unused__)) #define __packed __attribute__((__packed__)) #define __aligned(x) __attribute__((__aligned__(x))) #define __section(x) __attribute__((__section__(x))) #define __read_mostly __section(".data.read_mostly") #define __read_frequently __section(".data.read_frequently") #define __exclusive_cache_line __aligned(__VM_CACHELINE_SIZE*2) \ __section(".data.exclusive_cache_line") #else # 176 "/usr/include/sys/cdefs.h" 3 4 #define __dead2 #define __pure2 #define __unused #endif # 180 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(2, 96) #define __malloclike __attribute__((__malloc__)) #define __pure __attribute__((__pure__)) #else # 185 "/usr/include/sys/cdefs.h" 3 4 #define __malloclike #define __pure __pure2 #endif # 188 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(3, 1) #define __always_inline __attribute__((__always_inline__)) #define __noinline __attribute__((__noinline__)) #else # 193 "/usr/include/sys/cdefs.h" 3 4 #define __always_inline #define __noinline #endif # 196 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(3, 3) #define __nonnull(...) __attribute__((__nonnull__(__VA_ARGS__))) #define __used __attribute__((__used__)) #else # 201 "/usr/include/sys/cdefs.h" 3 4 #define __nonnull(...) #define __used __unused #endif # 204 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(3, 4) #define __heedresult __attribute__((__warn_unused_result__)) #else # 208 "/usr/include/sys/cdefs.h" 3 4 #define __heedresult #endif # 210 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(4, 1) #define __returns_twice __attribute__((__returns_twice__)) #else # 214 "/usr/include/sys/cdefs.h" 3 4 #define __returns_twice #endif # 216 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(4, 3) || __has_attribute(__alloc_size__) #define __alloc_size(x) __attribute__((__alloc_size__(x))) #define __alloc_size2(n, x) __attribute__((__alloc_size__(n, x))) #else # 221 "/usr/include/sys/cdefs.h" 3 4 #define __alloc_size(x) #define __alloc_size2(n, x) #endif # 224 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(4, 9) || __has_attribute(__alloc_align__) #define __alloc_align(x) __attribute__((__alloc_align__(x))) #else # 228 "/usr/include/sys/cdefs.h" 3 4 #define __alloc_align(x) #endif # 230 "/usr/include/sys/cdefs.h" 3 4 #if !__GNUC_PREREQ__(2, 7) && __STDC_VERSION__ < 199901 #define __func__ NULL #endif # 234 "/usr/include/sys/cdefs.h" 3 4 #if (__GNUC_PREREQ__(2, 0) && !defined(__STRICT_ANSI__)) || \ __STDC_VERSION__ >= 199901 #define __LONG_LONG_SUPPORTED #endif # 239 "/usr/include/sys/cdefs.h" 3 4 #if defined(__cplusplus) && __cplusplus >= 201103L #define __LONG_LONG_SUPPORTED #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS #endif # 246 "/usr/include/sys/cdefs.h" 3 4 #ifndef __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS #endif # 249 "/usr/include/sys/cdefs.h" 3 4 #endif # 250 "/usr/include/sys/cdefs.h" 3 4 #if !__GNUC_PREREQ__(2, 95) #if __STDC_VERSION__ < 199901 #define __restrict #else # 261 "/usr/include/sys/cdefs.h" 3 4 #define __restrict restrict #endif # 263 "/usr/include/sys/cdefs.h" 3 4 #endif # 264 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(3, 1) && !defined(__GNUG__) #define __restrict_arr __restrict #else # 271 "/usr/include/sys/cdefs.h" 3 4 #ifdef __GNUC__ #define __restrict_arr #else # 274 "/usr/include/sys/cdefs.h" 3 4 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901 #define __restrict_arr restrict #else # 277 "/usr/include/sys/cdefs.h" 3 4 #define __restrict_arr #endif # 279 "/usr/include/sys/cdefs.h" 3 4 #endif # 280 "/usr/include/sys/cdefs.h" 3 4 #endif # 281 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(2, 96) #define __predict_true(exp) __builtin_expect((exp), 1) #define __predict_false(exp) __builtin_expect((exp), 0) #else # 314 "/usr/include/sys/cdefs.h" 3 4 #define __predict_true(exp) (exp) #define __predict_false(exp) (exp) #endif # 317 "/usr/include/sys/cdefs.h" 3 4 #if !__GNUC_PREREQ__(2, 7) #define __printflike(fmtarg, firstvararg) #define __scanflike(fmtarg, firstvararg) #define __printf0like(fmtarg, firstvararg) #define __format_arg(fmtarg) #define __strfmonlike(fmtarg, firstvararg) #define __strftimelike(fmtarg, firstvararg) #elif __GNUC_PREREQ__(3, 0) # 335 "/usr/include/sys/cdefs.h" 3 4 #define __printflike(fmtarg, firstvararg) \ __attribute__((__nonnull__(fmtarg), \ __format__ (__printf__, fmtarg, firstvararg))) #define __printf0like(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) #define __scanflike(fmtarg, firstvararg) \ __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) #define __format_arg(fmtarg) \ __attribute__((__format_arg__ (fmtarg))) #define __strfmonlike(fmtarg, firstvararg) \ __attribute__((__format__ (__strfmon__, fmtarg, firstvararg))) #define __strftimelike(fmtarg, firstvararg) \ __attribute__((__format__ (__strftime__, fmtarg, firstvararg))) #else # 350 "/usr/include/sys/cdefs.h" 3 4 #define __printflike(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) #define __printf0like(fmtarg, firstvararg) \ __attribute__((__format__ (__printf0__, fmtarg, firstvararg))) #define __scanflike(fmtarg, firstvararg) \ __attribute__((__format__ (__scanf__, fmtarg, firstvararg))) #define __format_arg(fmtarg) \ __attribute__((__format_arg__ (fmtarg))) #define __strfmonlike(fmtarg, firstvararg) \ __attribute__((__format__ (__strfmon__, fmtarg, firstvararg))) #define __strftimelike(fmtarg, firstvararg) \ __attribute__((__format__ (__strftime__, fmtarg, firstvararg))) #endif # 363 "/usr/include/sys/cdefs.h" 3 4 #if !__GNUC_PREREQ__(3, 0) #define __ARRAY_ZERO 0 #else # 367 "/usr/include/sys/cdefs.h" 3 4 #define __ARRAY_ZERO #endif # 369 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(4, 0) #define __dso_public __attribute__((__visibility__("default"))) #define __dso_hidden __attribute__((__visibility__("hidden"))) #else # 374 "/usr/include/sys/cdefs.h" 3 4 #define __dso_public #define __dso_hidden #endif # 377 "/usr/include/sys/cdefs.h" 3 4 #if __GNUC_PREREQ__(4, 3) #define __constructor(prio) __attribute__((constructor(prio))) #else # 385 "/usr/include/sys/cdefs.h" 3 4 #define __constructor(prio) __attribute__((constructor)) #endif # 387 "/usr/include/sys/cdefs.h" 3 4 #ifdef __GNUC__ #define __cachealign __attribute__((__aligned__(__VM_CACHELINE_SIZE))) #define __usereg __attribute__((__regparm__(3))) #else # 421 "/usr/include/sys/cdefs.h" 3 4 #define __cachealign #define __usereg #endif # 424 "/usr/include/sys/cdefs.h" 3 4 #ifdef __GNUC__ #define __strong_reference(sym,aliassym) \ extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))) #define __weak_reference(sym,aliassym) \ __strong_reference(sym,aliassym) __attribute__ ((__weak__)) #define __weak_reference_asm(sym,alias) \ __asm__(".weak " #alias); \ __asm__(".equ " #alias ", " #sym) #define __warn_references(sym,msg) \ __asm__(".section .gnu.warning." #sym); \ __asm__(".asciz \"" msg "\""); \ __asm__(".previous") #endif # 438 "/usr/include/sys/cdefs.h" 3 4 #if defined(__GNUC__) #define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"") #endif # 442 "/usr/include/sys/cdefs.h" 3 4 #ifndef __RCSID #define __RCSID(s) struct __hack #endif # 446 "/usr/include/sys/cdefs.h" 3 4 #ifndef __RCSID_SOURCE #define __RCSID_SOURCE(s) struct __hack #endif # 450 "/usr/include/sys/cdefs.h" 3 4 #ifndef __SCCSID #define __SCCSID(s) struct __hack #endif # 454 "/usr/include/sys/cdefs.h" 3 4 #ifndef __FBSDID #define __FBSDID(s) struct __hack #endif # 458 "/usr/include/sys/cdefs.h" 3 4 #ifndef __COPYRIGHT #define __COPYRIGHT(s) struct __hack #endif # 462 "/usr/include/sys/cdefs.h" 3 4 #ifndef __DECONST #define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) #endif # 466 "/usr/include/sys/cdefs.h" 3 4 #ifndef __DEVOLATILE #define __DEVOLATILE(type, var) ((type)(uintptr_t)(volatile void *)(var)) #endif # 470 "/usr/include/sys/cdefs.h" 3 4 #ifndef __DEQUALIFY #define __DEQUALIFY(type, var) ((type)(uintptr_t)(const volatile void *)(var)) #endif # 474 "/usr/include/sys/cdefs.h" 3 4 #if !__GNUC_PREREQ__(2, 95) #define __alignof(x) __offsetof(struct { char __a; x __b; }, __b) #endif # 482 "/usr/include/sys/cdefs.h" 3 4 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L #if !__has_extension(c_alignas) #if (defined(__cplusplus) && __cplusplus >= 201103L) || \ __has_extension(cxx_alignas) #define _Alignas(x) alignas(x) #else # 490 "/usr/include/sys/cdefs.h" 3 4 #define _Alignas(x) __aligned(x) #endif # 493 "/usr/include/sys/cdefs.h" 3 4 #endif # 494 "/usr/include/sys/cdefs.h" 3 4 #if defined(__cplusplus) && __cplusplus >= 201103L #define _Alignof(x) alignof(x) #else # 498 "/usr/include/sys/cdefs.h" 3 4 #define _Alignof(x) __alignof(x) #endif # 500 "/usr/include/sys/cdefs.h" 3 4 #if !defined(_Noreturn) #define _Noreturn __dead2 #endif # 504 "/usr/include/sys/cdefs.h" 3 4 #if !__has_extension(c_static_assert) #if (defined(__cplusplus) && __cplusplus >= 201103L) || \ __has_extension(cxx_static_assert) #define _Static_assert(x, y) static_assert(x, y) #elif !__GNUC_PREREQ__(4, 6) # 510 "/usr/include/sys/cdefs.h" 3 4 #define _Static_assert(x, y) struct __hack #ifdef _KERNEL #define CTASSERT(x) _CTASSERT(x, __LINE__) #define _CTASSERT(x, y) __CTASSERT(x, y) #define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] #endif # 516 "/usr/include/sys/cdefs.h" 3 4 #endif # 517 "/usr/include/sys/cdefs.h" 3 4 #endif # 518 "/usr/include/sys/cdefs.h" 3 4 #endif # 520 "/usr/include/sys/cdefs.h" 3 4 #if defined(_KERNEL) && !defined(CTASSERT) #define CTASSERT(x) _Static_assert(x, \ "compile-time assertion failed") #endif # 525 "/usr/include/sys/cdefs.h" 3 4 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define __generic(expr, t, yes, no) \ _Generic(expr, t: yes, default: no) #elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus) # 539 "/usr/include/sys/cdefs.h" 3 4 #define __generic(expr, t, yes, no) \ __builtin_choose_expr( \ __builtin_types_compatible_p(__typeof(expr), t), yes, no) #endif # 543 "/usr/include/sys/cdefs.h" 3 4 #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0) == 1 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199009 #endif # 570 "/usr/include/sys/cdefs.h" 3 4 #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0) == 2 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199209 #endif # 576 "/usr/include/sys/cdefs.h" 3 4 #ifdef _XOPEN_SOURCE #if _XOPEN_SOURCE - 0 >= 700 #define __XSI_VISIBLE 700 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809 #elif _XOPEN_SOURCE - 0 >= 600 # 584 "/usr/include/sys/cdefs.h" 3 4 #define __XSI_VISIBLE 600 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112 #elif _XOPEN_SOURCE - 0 >= 500 # 588 "/usr/include/sys/cdefs.h" 3 4 #define __XSI_VISIBLE 500 #undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199506 #endif # 592 "/usr/include/sys/cdefs.h" 3 4 #endif # 593 "/usr/include/sys/cdefs.h" 3 4 #if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) #define _POSIX_C_SOURCE 198808 #endif # 601 "/usr/include/sys/cdefs.h" 3 4 #ifdef _POSIX_C_SOURCE #if (_POSIX_C_SOURCE - 0) >= 200809 #define __POSIX_VISIBLE 200809 #define __ISO_C_VISIBLE 1999 #elif (_POSIX_C_SOURCE - 0) >= 200112 # 606 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 200112 #define __ISO_C_VISIBLE 1999 #elif (_POSIX_C_SOURCE - 0) >= 199506 # 609 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 199506 #define __ISO_C_VISIBLE 1990 #elif (_POSIX_C_SOURCE - 0) >= 199309 # 612 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 199309 #define __ISO_C_VISIBLE 1990 #elif (_POSIX_C_SOURCE - 0) >= 199209 # 615 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 199209 #define __ISO_C_VISIBLE 1990 #elif (_POSIX_C_SOURCE - 0) >= 199009 # 618 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 199009 #define __ISO_C_VISIBLE 1990 #else # 621 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 198808 #define __ISO_C_VISIBLE 0 #endif # 624 "/usr/include/sys/cdefs.h" 3 4 #else # 625 "/usr/include/sys/cdefs.h" 3 4 #if defined(_ANSI_SOURCE) #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 1990 #elif defined(_C99_SOURCE) # 643 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 1999 #elif defined(_C11_SOURCE) # 648 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 0 #define __XSI_VISIBLE 0 #define __BSD_VISIBLE 0 #define __ISO_C_VISIBLE 2011 #else # 653 "/usr/include/sys/cdefs.h" 3 4 #define __POSIX_VISIBLE 200809 #define __XSI_VISIBLE 700 #define __BSD_VISIBLE 1 #define __ISO_C_VISIBLE 2011 #endif # 658 "/usr/include/sys/cdefs.h" 3 4 #endif # 659 "/usr/include/sys/cdefs.h" 3 4 #define __GLOBL1(sym) __asm__(".globl " #sym) #define __GLOBL(sym) __GLOBL1(sym) #endif # 669 "/usr/include/sys/cdefs.h" 3 4 # 42 "/usr/include/errno.h" 2 3 4 #if !defined(_KERNEL) || defined(_KERNEL_VIRTUAL) __BEGIN_DECLS extern __thread int errno; __END_DECLS static __inline int *__error(void) { return (&errno); } #define errno (* __error()) #endif # 55 "/usr/include/errno.h" 3 4 #define EPERM 1 #define ENOENT 2 #define ESRCH 3 #define EINTR 4 #define EIO 5 #define ENXIO 6 #define E2BIG 7 #define ENOEXEC 8 #define EBADF 9 #define ECHILD 10 #define EDEADLK 11 #define ENOMEM 12 #define EACCES 13 #define EFAULT 14 #if __BSD_VISIBLE #define ENOTBLK 15 #endif # 74 "/usr/include/errno.h" 3 4 #define EBUSY 16 #define EEXIST 17 #define EXDEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 #define EDOM 33 #define ERANGE 34 #define EAGAIN 35 #define EWOULDBLOCK EAGAIN #define EINPROGRESS 36 #define EALREADY 37 #define ENOTSOCK 38 #define EDESTADDRREQ 39 #define EMSGSIZE 40 #define EPROTOTYPE 41 #define ENOPROTOOPT 42 #define EPROTONOSUPPORT 43 #if __BSD_VISIBLE #define ESOCKTNOSUPPORT 44 #endif # 112 "/usr/include/errno.h" 3 4 #define EOPNOTSUPP 45 #define ENOTSUP EOPNOTSUPP #if __BSD_VISIBLE #define EPFNOSUPPORT 46 #endif # 117 "/usr/include/errno.h" 3 4 #define EAFNOSUPPORT 47 #define EADDRINUSE 48 #define EADDRNOTAVAIL 49 #define ENETDOWN 50 #define ENETUNREACH 51 #define ENETRESET 52 #define ECONNABORTED 53 #define ECONNRESET 54 #define ENOBUFS 55 #define EISCONN 56 #define ENOTCONN 57 #if __BSD_VISIBLE #define ESHUTDOWN 58 #define ETOOMANYREFS 59 #endif # 134 "/usr/include/errno.h" 3 4 #define ETIMEDOUT 60 #define ECONNREFUSED 61 #define ELOOP 62 #define ENAMETOOLONG 63 #define EHOSTDOWN 64 #define EHOSTUNREACH 65 #define ENOTEMPTY 66 #if __BSD_VISIBLE #define EPROCLIM 67 #define EUSERS 68 #endif # 150 "/usr/include/errno.h" 3 4 #define EDQUOT 69 #define ESTALE 70 #if __BSD_VISIBLE #define EREMOTE 71 #define EBADRPC 72 #define ERPCMISMATCH 73 #define EPROGUNAVAIL 74 #define EPROGMISMATCH 75 #define EPROCUNAVAIL 76 #endif # 162 "/usr/include/errno.h" 3 4 #define ENOLCK 77 #define ENOSYS 78 #if __BSD_VISIBLE #define EFTYPE 79 #define EAUTH 80 #define ENEEDAUTH 81 #endif # 171 "/usr/include/errno.h" 3 4 #define EIDRM 82 #define ENOMSG 83 #define EOVERFLOW 84 #define ECANCELED 85 #define EILSEQ 86 #if __BSD_VISIBLE #define ENOATTR 87 #define EDOOFUS 88 #endif # 180 "/usr/include/errno.h" 3 4 #define EBADMSG 89 #define EMULTIHOP 90 #define ENOLINK 91 #define EPROTO 92 #if __BSD_VISIBLE #define ENOMEDIUM 93 #define EASYNC 99 #define ELAST 99 #endif # 195 "/usr/include/errno.h" 3 4 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) #define ERESTART (-1) #define EJUSTRETURN (-2) #define ENOIOCTL (-3) #define EMOUNTEXIT (-4) #endif # 203 "/usr/include/errno.h" 3 4 #endif # 205 "/usr/include/errno.h" 3 4 # 10 "core.c" 2 #if 0 #include <sys/ioctl.h> #endif # 10 "core.c" # 1 "/usr/include/sys/ioctl.h" 1 3 4 #ifndef _SYS_IOCTL_H_ #define _SYS_IOCTL_H_ #ifdef _KERNEL #warning "Don't #include ioctl.h in the kernel. Include xxxio.h instead." #endif # 44 "/usr/include/sys/ioctl.h" 3 4 #if 0 #include <sys/filio.h> #endif # 45 "/usr/include/sys/ioctl.h" 3 4 # 1 "/usr/include/sys/filio.h" 1 3 4 #ifndef _SYS_FILIO_H_ #define _SYS_FILIO_H_ #if 0 #include <sys/ioccom.h> #endif # 42 "/usr/include/sys/filio.h" 3 4 # 1 "/usr/include/sys/ioccom.h" 1 3 4 #ifndef _SYS_IOCCOM_H_ #define _SYS_IOCCOM_H_ #define IOCPARM_SHIFT 13 #define IOCPARM_MASK ((1 << IOCPARM_SHIFT) - 1) #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) #define IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) #define IOCGROUP(x) (((x) >> 8) & 0xff) #define IOCPARM_MAX ((1 << IOCPARM_SHIFT) - 1) #define IOC_VOID 0x20000000 #define IOC_OUT 0x40000000 #define IOC_IN 0x80000000 #define IOC_INOUT (IOC_IN|IOC_OUT) #define IOC_DIRMASK (IOC_VOID|IOC_OUT|IOC_IN) #define _IOC(inout,group,num,len) ((unsigned long) \ ((inout) | (((len) & IOCPARM_MASK) << 16) | ((group) << 8) | (num))) #define _IO(g,n) _IOC(IOC_VOID, (g), (n), 0) #define _IOWINT(g,n) _IOC(IOC_VOID, (g), (n), sizeof(int)) #define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) #define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) #define _IOWR(g,n,t) _IOC(IOC_INOUT, (g), (n), sizeof(t)) #if !defined(_KERNEL) || defined(_KERNEL_VIRTUAL) #if 0 #include <sys/cdefs.h> #endif # 65 "/usr/include/sys/ioccom.h" 3 4 # 66 "/usr/include/sys/ioccom.h" 3 4 __BEGIN_DECLS int ioctl(int, unsigned long, ...); __END_DECLS #endif # 72 "/usr/include/sys/ioccom.h" 3 4 #endif # 74 "/usr/include/sys/ioccom.h" 3 4 # 43 "/usr/include/sys/filio.h" 2 3 4 struct fiodname_args { void *name; unsigned int len; }; #define FIOCLEX _IO('f', 1) #define FIONCLEX _IO('f', 2) #define FIONREAD _IOR('f', 127, int) #define FIONBIO _IOW('f', 126, int) #define FIOASYNC _IOW('f', 125, int) #define FIOSETOWN _IOW('f', 124, int) #define FIOGETOWN _IOR('f', 123, int) #define FIODTYPE _IOR('f', 122, int) #define FIOGETLBA _IOR('f', 121, int) #define FIODNAME _IOW('f', 120, struct fiodname_args) #endif # 61 "/usr/include/sys/filio.h" 3 4 # 46 "/usr/include/sys/ioctl.h" 2 3 4 #if 0 #include <sys/sockio.h> #endif # 46 "/usr/include/sys/ioctl.h" 3 4 # 1 "/usr/include/sys/sockio.h" 1 3 4 #ifndef _SYS_SOCKIO_H_ #define _SYS_SOCKIO_H_ #if 0 #include <sys/ioccom.h> #endif # 36 "/usr/include/sys/sockio.h" 3 4 # 37 "/usr/include/sys/sockio.h" 3 4 #define SIOCSHIWAT _IOW('s', 0, int) #define SIOCGHIWAT _IOR('s', 1, int) #define SIOCSLOWAT _IOW('s', 2, int) #define SIOCGLOWAT _IOR('s', 3, int) #define SIOCATMARK _IOR('s', 7, int) #define SIOCSPGRP _IOW('s', 8, int) #define SIOCGPGRP _IOR('s', 9, int) #define SIOCGETVIFCNT _IOWR('r', 15, struct sioc_vif_req) #define SIOCGETSGCNT _IOWR('r', 16, struct sioc_sg_req) #define SIOCSIFADDR _IOW('i', 12, struct ifreq) #define SIOCGIFADDR _IOWR('i', 33, struct ifreq) #define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) #define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) #define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) #define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) #define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) #define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) #define SIOCGIFCONF _IOWR('i', 36, struct ifconf) #define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) #define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) #define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) #define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) #define SIOCDIFADDR _IOW('i', 25, struct ifreq) #define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq) #define SIOCALIFADDR _IOW('i', 27, struct if_laddrreq) #define SIOCGLIFADDR _IOWR('i', 28, struct if_laddrreq) #define SIOCDLIFADDR _IOW('i', 29, struct if_laddrreq) #define SIOCSIFCAP _IOW('i', 30, struct ifreq) #define SIOCGIFCAP _IOWR('i', 31, struct ifreq) #define SIOCGIFINDEX _IOWR('i', 32, struct ifreq) #define SIOCGIFDATA _IOWR('i', 38, struct ifreq) #define SIOCSIFNAME _IOW('i', 40, struct ifreq) #define SIOCADDMULTI _IOW('i', 49, struct ifreq) #define SIOCDELMULTI _IOW('i', 50, struct ifreq) #define SIOCGIFMTU _IOWR('i', 51, struct ifreq) #define SIOCSIFMTU _IOW('i', 52, struct ifreq) #define SIOCGIFPHYS _IOWR('i', 53, struct ifreq) #define SIOCSIFPHYS _IOW('i', 54, struct ifreq) #define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) #define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) #define SIOCSIFGENERIC _IOW('i', 57, struct ifreq) #define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) #define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) #define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) #define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) #define SIOCGIFPDSTADDR _IOWR('i', 72, struct ifreq) #define SIOCDIFPHYADDR _IOW('i', 73, struct ifreq) #define SIOCSLIFPHYADDR _IOW('i', 74, struct if_laddrreq) #define SIOCGLIFPHYADDR _IOWR('i', 75, struct if_laddrreq) #define SIOCGPRIVATE_0 _IOWR('i', 80, struct ifreq) #define SIOCGPRIVATE_1 _IOWR('i', 81, struct ifreq) #define SIOCSDRVSPEC _IOW('i', 123, struct ifdrv) #define SIOCGDRVSPEC _IOWR('i', 123, struct ifdrv) #define SIOCIFGCLONERS _IOWR('i', 120, struct if_clonereq) #define SIOCIFDESTROY _IOW('i', 121, struct ifreq) #define SIOCIFCREATE _IOWR('i', 122, struct ifreq) #define SIOCIFCREATE2 _IOWR('i', 124, struct ifreq) #define SIOCSIFPOLLCPU _IOW('i', 125, struct ifreq) #define SIOCGIFPOLLCPU _IOWR('i', 126, struct ifreq) #define SIOCSIFTSOLEN _IOW('i', 127, struct ifreq) #define SIOCGIFTSOLEN _IOWR('i', 128, struct ifreq) #define SIOCAIFGROUP _IOW('i', 135, struct ifgroupreq) #define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) #define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) #define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) #endif # 128 "/usr/include/sys/sockio.h" 3 4 # 47 "/usr/include/sys/ioctl.h" 2 3 4 #if 0 #include <sys/ttycom.h> #endif # 47 "/usr/include/sys/ioctl.h" 3 4 # 1 "/usr/include/sys/ttycom.h" 1 3 4 #ifndef _SYS_TTYCOM_H_ #define _SYS_TTYCOM_H_ #if 0 #include <sys/ioccom.h> #endif # 42 "/usr/include/sys/ttycom.h" 3 4 # 43 "/usr/include/sys/ttycom.h" 3 4 struct winsize { unsigned short ws_row; unsigned short ws_col; unsigned short ws_xpixel; unsigned short ws_ypixel; }; #define TIOCMODG _IOR('t', 3, int) #define TIOCMODS _IOW('t', 4, int) #define TIOCM_LE 0001 #define TIOCM_DTR 0002 #define TIOCM_RTS 0004 #define TIOCM_ST 0010 #define TIOCM_SR 0020 #define TIOCM_CTS 0040 #define TIOCM_CAR 0100 #define TIOCM_CD TIOCM_CAR #define TIOCM_RNG 0200 #define TIOCM_RI TIOCM_RNG #define TIOCM_DSR 0400 #define TIOCEXCL _IO('t', 13) #define TIOCNXCL _IO('t', 14) #define TIOCFLUSH _IOW('t', 16, int) #define TIOCGETA _IOR('t', 19, struct termios) #define TIOCSETA _IOW('t', 20, struct termios) #define TIOCSETAW _IOW('t', 21, struct termios) #define TIOCSETAF _IOW('t', 22, struct termios) #define TIOCGETD _IOR('t', 26, int) #define TIOCSETD _IOW('t', 27, int) #define TIOCSBRK _IO('t', 123) #define TIOCCBRK _IO('t', 122) #define TIOCSDTR _IO('t', 121) #define TIOCCDTR _IO('t', 120) #define TIOCGPGRP _IOR('t', 119, int) #define TIOCSPGRP _IOW('t', 118, int) #define TIOCOUTQ _IOR('t', 115, int) #define TIOCSTI _IOW('t', 114, char) #define TIOCNOTTY _IO('t', 113) #define TIOCPKT _IOW('t', 112, int) #define TIOCPKT_DATA 0x00 #define TIOCPKT_FLUSHREAD 0x01 #define TIOCPKT_FLUSHWRITE 0x02 #define TIOCPKT_STOP 0x04 #define TIOCPKT_START 0x08 #define TIOCPKT_NOSTOP 0x10 #define TIOCPKT_DOSTOP 0x20 #define TIOCPKT_IOCTL 0x40 #define TIOCSTOP _IO('t', 111) #define TIOCSTART _IO('t', 110) #define TIOCMSET _IOW('t', 109, int) #define TIOCMBIS _IOW('t', 108, int) #define TIOCMBIC _IOW('t', 107, int) #define TIOCMGET _IOR('t', 106, int) #define TIOCREMOTE _IOW('t', 105, int) #define TIOCGWINSZ _IOR('t', 104, struct winsize) #define TIOCSWINSZ _IOW('t', 103, struct winsize) #define TIOCUCNTL _IOW('t', 102, int) #define TIOCSTAT _IO('t', 101) #define UIOCCMD(n) _IO('u', n) #define TIOCGSID _IOR('t', 99, int) #define TIOCCONS _IOW('t', 98, int) #define TIOCSCTTY _IO('t', 97) #define TIOCEXT _IOW('t', 96, int) #define TIOCSIG _IO('t', 95) #define TIOCDRAIN _IO('t', 94) #define TIOCMSDTRWAIT _IOW('t', 91, int) #define TIOCMGDTRWAIT _IOR('t', 90, int) #define TIOCTIMESTAMP _IOR('t', 89, struct timeval) #define TIOCDCDTIMESTAMP _IOR('t', 88, struct timeval) #define TIOCSDRAINWAIT _IOW('t', 87, int) #define TIOCGDRAINWAIT _IOR('t', 86, int) #define TIOCISPTMASTER _IO('t', 85) #define TTYDISC 0 #define SLIPDISC 4 #define PPPDISC 5 #define NETGRAPHDISC 6 #define BTUARTDISC 7 #endif # 140 "/usr/include/sys/ttycom.h" 3 4 # 48 "/usr/include/sys/ioctl.h" 2 3 4 #endif # 50 "/usr/include/sys/ioctl.h" 3 4 # 11 "core.c" 2 #if 0 #include "helpers.h" #endif # 11 "core.c" # 1 "./helpers.h" 1 #if 0 #pragma once #endif # 9 "./helpers.h" #if 0 #include <stddef.h> #endif # 10 "./helpers.h" # 1 "/usr/include/stddef.h" 1 3 4 #ifndef _STDDEF_H_ #define _STDDEF_H_ #if 0 #include <sys/cdefs.h> #endif # 37 "/usr/include/stddef.h" 3 4 # 38 "/usr/include/stddef.h" 3 4 #if 0 #include <sys/_null.h> #endif # 38 "/usr/include/stddef.h" 3 4 # 1 "/usr/include/sys/_null.h" 1 3 4 #ifndef NULL #ifndef __cplusplus #define NULL ((void *)0) #elif defined(__GNUC__) && __GNUC__ >= 4 # 37 "/usr/include/sys/_null.h" 3 4 #define NULL __null #else # 39 "/usr/include/sys/_null.h" 3 4 #define NULL 0 #endif # 41 "/usr/include/sys/_null.h" 3 4 #endif # 42 "/usr/include/sys/_null.h" 3 4 # 39 "/usr/include/stddef.h" 2 3 4 #ifndef _SYS_STDINT_H_ #if 0 #include <sys/stdint.h> #endif # 40 "/usr/include/stddef.h" 3 4 # 1 "/usr/include/sys/stdint.h" 1 3 4 #ifndef _SYS_STDINT_H_ #define _SYS_STDINT_H_ #if 0 #include <sys/cdefs.h> #endif # 13 "/usr/include/sys/stdint.h" 3 4 # 14 "/usr/include/sys/stdint.h" 3 4 #if 0 #include <machine/stdint.h> #endif # 14 "/usr/include/sys/stdint.h" 3 4 # 1 "/usr/include/machine/stdint.h" 1 3 4 #ifndef _CPU_STDINT_H_ #define _CPU_STDINT_H_ #if 0 #include <sys/cdefs.h> #endif # 44 "/usr/include/machine/stdint.h" 3 4 # 45 "/usr/include/machine/stdint.h" 3 4 typedef __signed char __int8_t; typedef unsigned char __uint8_t; typedef short __int16_t; typedef unsigned short __uint16_t; typedef int __int32_t; typedef unsigned int __uint32_t; #if defined(__cplusplus) || __STDC_VERSION__ < 199901L && !__GNUC_PREREQ__(3, 0) typedef int __boolean_t; #else # 58 "/usr/include/machine/stdint.h" 3 4 typedef _Bool __boolean_t; #endif # 60 "/usr/include/machine/stdint.h" 3 4 #ifdef __LP64__ typedef long __int64_t; typedef unsigned long __uint64_t; #else # 65 "/usr/include/machine/stdint.h" 3 4 __extension__ typedef long long __int64_t; __extension__ typedef unsigned long long __uint64_t; #endif # 70 "/usr/include/machine/stdint.h" 3 4 typedef __int64_t __intmax_t; typedef __uint64_t __uintmax_t; #ifdef __LP64__ typedef __int64_t __intptr_t; typedef __uint64_t __uintptr_t; typedef __int64_t __ptrdiff_t; #else # 82 "/usr/include/machine/stdint.h" 3 4 typedef __int32_t __intptr_t; typedef __uint32_t __uintptr_t; typedef __int32_t __ptrdiff_t; #endif # 86 "/usr/include/machine/stdint.h" 3 4 typedef __int32_t __int_fast8_t; typedef __int32_t __int_fast16_t; typedef __int32_t __int_fast32_t; typedef __int64_t __int_fast64_t; typedef __int8_t __int_least8_t; typedef __int16_t __int_least16_t; typedef __int32_t __int_least32_t; typedef __int64_t __int_least64_t; typedef __uint32_t __uint_fast8_t; typedef __uint32_t __uint_fast16_t; typedef __uint32_t __uint_fast32_t; typedef __uint64_t __uint_fast64_t; typedef __uint8_t __uint_least8_t; typedef __uint16_t __uint_least16_t; typedef __uint32_t __uint_least32_t; typedef __uint64_t __uint_least64_t; #ifdef __LP64__ typedef __uint64_t __size_t; typedef __int64_t __ssize_t; typedef __int64_t __register_t; typedef __uint64_t __u_register_t; #else # 117 "/usr/include/machine/stdint.h" 3 4 typedef __uint32_t __size_t; typedef __int32_t __ssize_t; typedef __int32_t __register_t; typedef __uint32_t __u_register_t; #endif # 122 "/usr/include/machine/stdint.h" 3 4 typedef long __suseconds_t; typedef long __time_t; typedef int __timer_t; typedef __int32_t __sig_atomic_t; typedef unsigned long __clock_t; typedef unsigned long __clockid_t; typedef __uint32_t __socklen_t; typedef volatile int __atomic_intr_t; typedef __int64_t __rlim_t; #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) #define __offsetof(type, field) __builtin_offsetof(type, field) #else # 138 "/usr/include/machine/stdint.h" 3 4 #ifndef __cplusplus #define __offsetof(type, field) ((__size_t)(&((type *)0)->field)) #else # 141 "/usr/include/machine/stdint.h" 3 4 #define __offsetof(type, field) \ (__offsetof__ (reinterpret_cast <__size_t> \ (&reinterpret_cast <const volatile char &> \ (static_cast<type *> (0)->field)))) #endif # 146 "/usr/include/machine/stdint.h" 3 4 #endif # 147 "/usr/include/machine/stdint.h" 3 4 #endif # 149 "/usr/include/machine/stdint.h" 3 4 # 15 "/usr/include/sys/stdint.h" 2 3 4 #ifndef __cplusplus #if defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2 typedef unsigned short __wchar_t; #else # 33 "/usr/include/sys/stdint.h" 3 4 typedef int __wchar_t; #endif # 35 "/usr/include/sys/stdint.h" 3 4 #endif # 36 "/usr/include/sys/stdint.h" 3 4 #ifndef ___WINT_T_DECLARED typedef int __wint_t; #define ___WINT_T_DECLARED #endif # 40 "/usr/include/sys/stdint.h" 3 4 #ifndef ___RUNE_T_DECLARED typedef int __rune_t; #define ___RUNE_T_DECLARED #endif # 44 "/usr/include/sys/stdint.h" 3 4 typedef void *__wctrans_t; typedef void *__wctype_t; typedef union { __uint8_t __mbstate8[128]; __int64_t __mbstateL; } __mbstate_t; typedef __int64_t __off_t; typedef __int32_t __pid_t; #endif # 60 "/usr/include/sys/stdint.h" 3 4 # 41 "/usr/include/stddef.h" 2 3 4 #endif # 42 "/usr/include/stddef.h" 3 4 #ifndef _SIZE_T_DECLARED #define _SIZE_T_DECLARED typedef __size_t size_t; #endif # 47 "/usr/include/stddef.h" 3 4 #ifndef _PTRDIFF_T_DECLARED #define _PTRDIFF_T_DECLARED typedef __ptrdiff_t ptrdiff_t; #endif # 52 "/usr/include/stddef.h" 3 4 #if __BSD_VISIBLE #ifndef _RUNE_T_DECLARED #define _RUNE_T_DECLARED typedef __rune_t rune_t; #endif # 58 "/usr/include/stddef.h" 3 4 #endif # 59 "/usr/include/stddef.h" 3 4 #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED #define _WCHAR_T_DECLARED typedef __wchar_t wchar_t; #endif # 65 "/usr/include/stddef.h" 3 4 #endif # 66 "/usr/include/stddef.h" 3 4 #define offsetof(type, member) __offsetof(type, member) #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) || \ (defined(__cplusplus) && __cplusplus >= 201103L)) #ifndef _MAX_ALIGN_T_DECLARED #define _MAX_ALIGN_T_DECLARED typedef struct { long long __max_align_nonce1 __aligned(__alignof(long long)); long double __max_align_nonce2 __aligned(__alignof(long double)); } max_align_t; #endif # 78 "/usr/include/stddef.h" 3 4 #endif # 79 "/usr/include/stddef.h" 3 4 #endif # 81 "/usr/include/stddef.h" 3 4 # 11 "./helpers.h" 2 #if 0 #include <stdbool.h> #endif # 11 "./helpers.h" # 1 "/usr/include/stdbool.h" 1 3 4 #ifndef _STDBOOL_H_ #define _STDBOOL_H_ #define __bool_true_false_are_defined 1 #ifndef __cplusplus #if 0 #include <sys/cdefs.h> #endif # 36 "/usr/include/stdbool.h" 3 4 # 37 "/usr/include/stdbool.h" 3 4 #define false 0 #define true 1 #define bool _Bool #if __STDC_VERSION__ < 199901L && !__GNUC_PREREQ__(3, 0) typedef int _Bool; #endif # 45 "/usr/include/stdbool.h" 3 4 #endif # 47 "/usr/include/stdbool.h" 3 4 #endif # 49 "/usr/include/stdbool.h" 3 4 # 12 "./helpers.h" 2 #define AARRAY_h #if 0 #include "aArray.h" #endif # 13 "./helpers.h" # 1 "./aArray.h" 1 #if !defined(AARRAY_define) #if 0 #include <stdlib.h> #endif # 15 "./aArray.h" # 1 "/usr/include/stdlib.h" 1 3 4 #ifndef _STDLIB_H_ #define _STDLIB_H_ #if 0 #include <sys/cdefs.h> #endif # 36 "/usr/include/stdlib.h" 3 4 # 37 "/usr/include/stdlib.h" 3 4 #if 0 #include <sys/_null.h> #endif # 37 "/usr/include/stdlib.h" 3 4 # 38 "/usr/include/stdlib.h" 3 4 #if 0 #include <sys/types.h> #endif # 38 "/usr/include/stdlib.h" 3 4 # 1 "/usr/include/sys/types.h" 1 3 4 #ifndef _SYS_TYPES_H_ #define _SYS_TYPES_H_ #ifndef _SYS_CDEFS_H_ #if 0 #include <sys/cdefs.h> #endif # 42 "/usr/include/sys/types.h" 3 4 # 43 "/usr/include/sys/types.h" 3 4 #endif # 44 "/usr/include/sys/types.h" 3 4 #ifndef _STDINT_H_ #if 0 #include <stdint.h> #endif # 45 "/usr/include/sys/types.h" 3 4 # 1 "/usr/include/stdint.h" 1 3 4 #ifndef _STDINT_H_ #define _STDINT_H_ #if 0 #include <sys/stdint.h> #endif # 32 "/usr/include/stdint.h" 3 4 # 33 "/usr/include/stdint.h" 3 4 typedef __int8_t int8_t; typedef __int16_t int16_t; typedef __int32_t int32_t; typedef __int64_t int64_t; typedef __uint8_t uint8_t; typedef __uint16_t uint16_t; typedef __uint32_t uint32_t; typedef __uint64_t uint64_t; typedef __intptr_t intptr_t; typedef __uintptr_t uintptr_t; typedef __intmax_t intmax_t; typedef __uintmax_t uintmax_t; #ifndef _PTRDIFF_T_DECLARED #define _PTRDIFF_T_DECLARED typedef __ptrdiff_t ptrdiff_t; #endif # 54 "/usr/include/stdint.h" 3 4 typedef __int_fast8_t int_fast8_t; typedef __int_fast16_t int_fast16_t; typedef __int_fast32_t int_fast32_t; typedef __int_fast64_t int_fast64_t; typedef __int_least8_t int_least8_t; typedef __int_least16_t int_least16_t; typedef __int_least32_t int_least32_t; typedef __int_least64_t int_least64_t; typedef __uint_fast8_t uint_fast8_t; typedef __uint_fast16_t uint_fast16_t; typedef __uint_fast32_t uint_fast32_t; typedef __uint_fast64_t uint_fast64_t; typedef __uint_least8_t uint_least8_t; typedef __uint_least16_t uint_least16_t; typedef __uint_least32_t uint_least32_t; typedef __uint_least64_t uint_least64_t; #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) #if 0 #include <machine/int_const.h> #endif # 73 "/usr/include/stdint.h" 3 4 # 1 "/usr/include/machine/int_const.h" 1 3 4 #ifndef _CPU_INT_CONST_H_ #define _CPU_INT_CONST_H_ #define INT8_C(c) (c) #define INT16_C(c) (c) #define INT32_C(c) (c) #define INT64_C(c) (c ## L) #define UINT8_C(c) (c) #define UINT16_C(c) (c) #define UINT32_C(c) (c ## U) #define UINT64_C(c) (c ## UL) #define INTMAX_C(c) (c ## L) #define UINTMAX_C(c) (c ## UL) #endif # 56 "/usr/include/machine/int_const.h" 3 4 # 74 "/usr/include/stdint.h" 2 3 4 #endif # 75 "/usr/include/stdint.h" 3 4 #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) #if 0 #include <machine/int_limits.h> #endif # 77 "/usr/include/stdint.h" 3 4 # 1 "/usr/include/machine/int_limits.h" 1 3 4 #ifndef _CPU_INT_LIMITS_H_ #define _CPU_INT_LIMITS_H_ #define INT8_MIN (-0x7f-1) #define INT16_MIN (-0x7fff-1) #define INT32_MIN (-0x7fffffff-1) #define INT64_MIN (-0x7fffffffffffffffL-1) #define INT8_MAX 0x7f #define INT16_MAX 0x7fff #define INT32_MAX 0x7fffffff #define INT64_MAX 0x7fffffffffffffffL #define UINT8_MAX 0xff #define UINT16_MAX 0xffff #define UINT32_MAX 0xffffffffU #define UINT64_MAX 0xffffffffffffffffUL #define INTPTR_MIN INT64_MIN #define INTPTR_MAX INT64_MAX #define UINTPTR_MAX UINT64_MAX #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX #define PTRDIFF_MIN INT64_MIN #define PTRDIFF_MAX INT64_MAX #define SIG_ATOMIC_MIN INT32_MIN #define SIG_ATOMIC_MAX INT32_MAX #define SIZE_MAX UINT64_MAX #ifndef WCHAR_MIN #define WCHAR_MIN INT32_MIN #endif # 101 "/usr/include/machine/int_limits.h" 3 4 #ifndef WCHAR_MAX #define WCHAR_MAX INT32_MAX #endif # 104 "/usr/include/machine/int_limits.h" 3 4 #ifndef WINT_MIN #define WINT_MIN INT32_MIN #endif # 109 "/usr/include/machine/int_limits.h" 3 4 #ifndef WINT_MAX #define WINT_MAX INT32_MAX #endif # 112 "/usr/include/machine/int_limits.h" 3 4 #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST64_MIN INT64_MIN #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MAX INT64_MAX #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX #define INT_FAST8_MIN INT32_MIN #define INT_FAST16_MIN INT32_MIN #define INT_FAST32_MIN INT32_MIN #define INT_FAST64_MIN INT64_MIN #define INT_FAST8_MAX INT32_MAX #define INT_FAST16_MAX INT32_MAX #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MAX INT64_MAX #define UINT_FAST8_MAX UINT32_MAX #define UINT_FAST16_MAX UINT32_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX #endif # 158 "/usr/include/machine/int_limits.h" 3 4 # 78 "/usr/include/stdint.h" 2 3 4 #endif # 79 "/usr/include/stdint.h" 3 4 #endif # 81 "/usr/include/stdint.h" 3 4 # 46 "/usr/include/sys/types.h" 2 3 4 #endif # 47 "/usr/include/sys/types.h" 3 4 #if 0 #include <machine/endian.h> #endif # 47 "/usr/include/sys/types.h" 3 4 # 1 "/usr/include/machine/endian.h" 1 3 4 #ifndef _CPU_ENDIAN_H_ #define _CPU_ENDIAN_H_ #ifndef _KERNEL #if 0 #include <sys/cdefs.h> #endif # 37 "/usr/include/machine/endian.h" 3 4 # 38 "/usr/include/machine/endian.h" 3 4 #endif # 39 "/usr/include/machine/endian.h" 3 4 #if 0 #include <machine/stdint.h> #endif # 40 "/usr/include/machine/endian.h" 3 4 # 41 "/usr/include/machine/endian.h" 3 4 #define _QUAD_HIGHWORD 1 #define _QUAD_LOWWORD 0 #define _LITTLE_ENDIAN 1234 #define _BIG_ENDIAN 4321 #define _PDP_ENDIAN 3412 #define _BYTE_ORDER _LITTLE_ENDIAN #if __BSD_VISIBLE #define LITTLE_ENDIAN _LITTLE_ENDIAN #define BIG_ENDIAN _BIG_ENDIAN #define PDP_ENDIAN _PDP_ENDIAN #define BYTE_ORDER _BYTE_ORDER #endif # 68 "/usr/include/machine/endian.h" 3 4 #ifdef __GNUC__ #define __word_swap_int_var(x) \ __extension__ ({ register __uint32_t __X = (x); \ __asm ("rorl $16, %0" : "+r" (__X)); \ __X; }) #ifdef __OPTIMIZE__ #define __word_swap_int_const(x) \ ((((x) & 0xffff0000) >> 16) | \ (((x) & 0x0000ffff) << 16)) #define __word_swap_int(x) (__builtin_constant_p(x) ? \ __word_swap_int_const(x) : __word_swap_int_var(x)) #else # 85 "/usr/include/machine/endian.h" 3 4 #define __word_swap_int(x) __word_swap_int_var(x) #endif # 89 "/usr/include/machine/endian.h" 3 4 #define __byte_swap_int_var(x) \ __extension__ ({ register __uint32_t __X = (x); \ __asm ("bswap %0" : "+r" (__X)); \ __X; }) #ifdef __OPTIMIZE__ #define __byte_swap_int_const(x) \ ((((x) & 0xff000000) >> 24) | \ (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | \ (((x) & 0x000000ff) << 24)) #define __byte_swap_int(x) (__builtin_constant_p(x) ? \ __byte_swap_int_const(x) : __byte_swap_int_var(x)) #else # 106 "/usr/include/machine/endian.h" 3 4 #define __byte_swap_int(x) __byte_swap_int_var(x) #endif # 110 "/usr/include/machine/endian.h" 3 4 #define __byte_swap_long_var(x) \ __extension__ ({ register __uint64_t __X = (x); \ __asm ("bswap %0" : "+r" (__X)); \ __X; }) #define __byte_swap_long_const(x) \ (((x >> 56) | \ ((x >> 40) & 0xff00) | \ ((x >> 24) & 0xff0000) | \ ((x >> 8) & 0xff000000) | \ ((x << 8) & ((__uint64_t)0xff << 32)) | \ ((x << 24) & ((__uint64_t)0xff << 40)) | \ ((x << 40) & ((__uint64_t)0xff << 48)) | \ ((x << 56)))) #ifdef __i386__ #define __byte_swap_long(x) __byte_swap_long_const(x) #else # 131 "/usr/include/machine/endian.h" 3 4 #ifdef __OPTIMIZE__ #define __byte_swap_long(x) (__builtin_constant_p(x) ? \ __byte_swap_long_const(x) : __byte_swap_long_var(x)) #else # 136 "/usr/include/machine/endian.h" 3 4 #define __byte_swap_long(x) __byte_swap_long_var(x) #endif # 138 "/usr/include/machine/endian.h" 3 4 #endif # 140 "/usr/include/machine/endian.h" 3 4 #define __byte_swap_word_var(x) \ __extension__ ({ register __uint16_t __X = (x); \ __asm ("xchgb %h0, %b0" : "+Q" (__X)); \ __X; }) #ifdef __OPTIMIZE__ #define __byte_swap_word_const(x) \ ((((x) & 0xff00) >> 8) | \ (((x) & 0x00ff) << 8)) #define __byte_swap_word(x) (__builtin_constant_p(x) ? \ __byte_swap_word_const(x) : __byte_swap_word_var(x)) #else # 156 "/usr/include/machine/endian.h" 3 4 #define __byte_swap_word(x) __byte_swap_word_var(x) #endif # 160 "/usr/include/machine/endian.h" 3 4 static __inline __always_inline __uint64_t __bswap64(__uint64_t _x) { return (__byte_swap_long(_x)); } static __inline __always_inline __uint32_t __bswap32(__uint32_t _x) { return (__byte_swap_int(_x)); } static __inline __always_inline __uint16_t __bswap16(__uint16_t _x) { return (__byte_swap_word(_x)); } #define __htonl(x) __bswap32(x) #define __htons(x) __bswap16(x) #define __ntohl(x) __bswap32(x) #define __ntohs(x) __bswap16(x) #else # 188 "/usr/include/machine/endian.h" 3 4 #define _BYTEORDER_FUNC_DEFINED #endif # 197 "/usr/include/machine/endian.h" 3 4 #endif # 199 "/usr/include/machine/endian.h" 3 4 # 48 "/usr/include/sys/types.h" 2 3 4 #ifndef _MACHINE_TYPES_H_ #if 0 #include <machine/types.h> #endif # 49 "/usr/include/sys/types.h" 3 4 # 1 "/usr/include/machine/types.h" 1 3 4 #ifndef _MACHINE_TYPES_H_ #define _MACHINE_TYPES_H_ #if 0 #include <machine/stdint.h> #endif # 36 "/usr/include/machine/types.h" 3 4 # 37 "/usr/include/machine/types.h" 3 4 #if 0 #include <cpu/types.h> #endif # 37 "/usr/include/machine/types.h" 3 4 # 1 "/usr/include/cpu/types.h" 1 3 4 #ifndef _CPU_TYPES_H_ #define _CPU_TYPES_H_ #if 0 #include <machine/stdint.h> #endif # 37 "/usr/include/cpu/types.h" 3 4 # 38 "/usr/include/cpu/types.h" 3 4 #if defined(__x86_64__) typedef __int64_t __segsz_t; typedef __int64_t register_t; typedef __uint64_t u_register_t; #elif defined(__i386__) # 44 "/usr/include/cpu/types.h" 3 4 typedef __int32_t __segsz_t; typedef __int32_t register_t; typedef __uint32_t u_register_t; #endif # 48 "/usr/include/cpu/types.h" 3 4 typedef unsigned long vm_offset_t; typedef unsigned long vm_size_t; typedef __uint64_t vm_pindex_t; typedef __uint64_t vm_spindex_t; typedef __int64_t vm_ooffset_t; typedef __uint64_t vm_poff_t; typedef __uint64_t vm_paddr_t; #ifdef _KERNEL typedef __int64_t intfptr_t; typedef __uint64_t uintfptr_t; #endif # 62 "/usr/include/cpu/types.h" 3 4 typedef __uint64_t pml4_entry_t; typedef __uint64_t pdp_entry_t; typedef __uint64_t pd_entry_t; typedef __uint64_t pt_entry_t; typedef __uint32_t cpulock_t; #define _CPUMASK_ELEMENTS 4 typedef struct { __uint64_t ary[4]; } cpumask_t; #define CPULOCK_EXCLBIT 0 #define CPULOCK_EXCL 0x00000001 #define CPULOCK_INCR 0x00000002 #define CPULOCK_CNTMASK 0x7FFFFFFE #define PML4SIZE sizeof(pml4_entry_t) #define PDPSIZE sizeof(pdp_entry_t) #define PDESIZE sizeof(pd_entry_t) #define PTESIZE sizeof(pt_entry_t) #endif # 98 "/usr/include/cpu/types.h" 3 4 # 38 "/usr/include/machine/types.h" 2 3 4 #ifdef _KERNEL typedef __uint32_t intrmask_t; #endif # 45 "/usr/include/machine/types.h" 3 4 #endif # 47 "/usr/include/machine/types.h" 3 4 # 50 "/usr/include/sys/types.h" 2 3 4 #endif # 51 "/usr/include/sys/types.h" 3 4 #ifndef _SYS_STDINT_H_ #if 0 #include <sys/stdint.h> #endif # 52 "/usr/include/sys/types.h" 3 4 # 53 "/usr/include/sys/types.h" 3 4 #endif # 54 "/usr/include/sys/types.h" 3 4 #ifndef _SYS__PTHREADTYPES_H_ #if 0 #include <sys/_pthreadtypes.h> #endif # 55 "/usr/include/sys/types.h" 3 4 # 1 "/usr/include/sys/_pthreadtypes.h" 1 3 4 #ifndef _SYS__PTHREADTYPES_H_ #define _SYS__PTHREADTYPES_H_ struct pthread; struct pthread_attr; struct pthread_cond; struct pthread_cond_attr; struct pthread_mutex; struct pthread_mutex_attr; struct pthread_once; struct pthread_rwlock; struct pthread_rwlockattr; struct pthread_barrier; struct pthread_barrier_attr; struct pthread_spinlock; typedef struct pthread *pthread_t; typedef struct pthread_attr *pthread_attr_t; typedef struct pthread_mutex *pthread_mutex_t; typedef struct pthread_mutex_attr *pthread_mutexattr_t; typedef struct pthread_cond *pthread_cond_t; typedef struct pthread_cond_attr *pthread_condattr_t; typedef int pthread_key_t; typedef struct pthread_once pthread_once_t; typedef struct pthread_rwlock *pthread_rwlock_t; typedef struct pthread_rwlockattr *pthread_rwlockattr_t; typedef struct pthread_barrier *pthread_barrier_t; typedef struct pthread_barrierattr *pthread_barrierattr_t; typedef struct pthread_spinlock *pthread_spinlock_t; typedef void *pthread_addr_t; typedef void *(*pthread_startroutine_t) (void *); struct pthread_once { int state; pthread_mutex_t mutex; }; #endif # 94 "/usr/include/sys/_pthreadtypes.h" 3 4 # 56 "/usr/include/sys/types.h" 2 3 4 #endif # 57 "/usr/include/sys/types.h" 3 4 #if __BSD_VISIBLE typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; typedef unsigned char unchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; #endif # 69 "/usr/include/sys/types.h" 3 4 typedef __uint8_t u_int8_t; typedef __uint16_t u_int16_t; typedef __uint32_t u_int32_t; typedef __uint64_t u_int64_t; typedef __uint64_t u_quad_t; typedef __int64_t quad_t; typedef quad_t * qaddr_t; typedef __int64_t blkcnt_t; typedef __int64_t blksize_t; typedef char * caddr_t; typedef const char * c_caddr_t; typedef volatile char * v_caddr_t; typedef __int32_t daddr_t; typedef __uint32_t u_daddr_t; typedef __uint32_t fixpt_t; #ifndef _FSBLKCNT_T_DECLARED typedef __uint64_t fsblkcnt_t; #define _FSBLKCNT_T_DECLARED #endif # 90 "/usr/include/sys/types.h" 3 4 #ifndef _FSFILCNT_T_DECLARED typedef __uint64_t fsfilcnt_t; #define _FSFILCNT_T_DECLARED #endif # 94 "/usr/include/sys/types.h" 3 4 #ifndef _GID_T_DECLARED typedef __uint32_t gid_t; #define _GID_T_DECLARED #endif # 98 "/usr/include/sys/types.h" 3 4 #ifndef _ID_T_DECLARED typedef __int64_t id_t; #define _ID_T_DECLARED #endif # 102 "/usr/include/sys/types.h" 3 4 #ifndef _IN_ADDR_T_DECLARED typedef __uint32_t in_addr_t; #define _IN_ADDR_T_DECLARED #endif # 106 "/usr/include/sys/types.h" 3 4 #ifndef _IN_PORT_T_DECLARED typedef __uint16_t in_port_t; #define _IN_PORT_T_DECLARED #endif # 110 "/usr/include/sys/types.h" 3 4 typedef __uint64_t ino_t; typedef long key_t; #ifndef _MODE_T_DECLARED typedef __uint16_t mode_t; #define _MODE_T_DECLARED #endif # 116 "/usr/include/sys/types.h" 3 4 typedef __uint32_t nlink_t; #ifndef _OFF_T_DECLARED typedef __off_t off_t; #define _OFF_T_DECLARED #endif # 121 "/usr/include/sys/types.h" 3 4 #ifndef _PID_T_DECLARED typedef __pid_t pid_t; #define _PID_T_DECLARED #endif # 125 "/usr/include/sys/types.h" 3 4 #ifndef _RLIM_T_DECLARED typedef __rlim_t rlim_t; #define _RLIM_T_DECLARED #endif # 129 "/usr/include/sys/types.h" 3 4 typedef __segsz_t segsz_t; #ifndef _SUSECONDS_T_DECLARED typedef __suseconds_t suseconds_t; #define _SUSECONDS_T_DECLARED #endif # 134 "/usr/include/sys/types.h" 3 4 #ifndef _UID_T_DECLARED typedef __uint32_t uid_t; #define _UID_T_DECLARED #endif # 138 "/usr/include/sys/types.h" 3 4 typedef __uint32_t useconds_t; typedef int mqd_t; #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) #ifndef __BOOLEAN_T_DEFINED__ #define __BOOLEAN_T_DEFINED__ typedef __boolean_t boolean_t; #endif # 147 "/usr/include/sys/types.h" 3 4 typedef u_int64_t uoff_t; #ifdef _KERNEL #if !defined(__bool_true_false_are_defined) && !defined(__cplusplus) #define __bool_true_false_are_defined 1 #define false 0 #define true 1 #if __STDC_VERSION__ < 199901L && __GNUC__ < 3 typedef int _Bool; #endif # 158 "/usr/include/sys/types.h" 3 4 typedef _Bool bool; #endif # 160 "/usr/include/sys/types.h" 3 4 #endif # 161 "/usr/include/sys/types.h" 3 4 #endif # 163 "/usr/include/sys/types.h" 3 4 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) struct cdev; typedef u_int32_t udev_t; typedef struct cdev *cdev_t; #endif # 178 "/usr/include/sys/types.h" 3 4 #ifdef _KERNEL #define offsetof(type, field) __offsetof(type, field) typedef udev_t dev_t; #else # 190 "/usr/include/sys/types.h" 3 4 typedef u_int32_t dev_t; #define udev_t dev_t #if __BSD_VISIBLE #define major(x) ((int)(((u_int)(x) >> 8)&0xff)) #define minor(x) ((int)((x)&0xffff00ff)) #define makedev(x,y) ((dev_t)(((x) << 8) | (y))) #endif # 206 "/usr/include/sys/types.h" 3 4 #endif # 208 "/usr/include/sys/types.h" 3 4 #ifndef _CLOCK_T_DECLARED #define _CLOCK_T_DECLARED typedef __clock_t clock_t; #endif # 213 "/usr/include/sys/types.h" 3 4 #ifndef _CLOCKID_T_DECLARED #define _CLOCKID_T_DECLARED typedef __clockid_t clockid_t; #endif # 218 "/usr/include/sys/types.h" 3 4 #if __BSD_VISIBLE #ifndef _LWPID_T_DECLARED #define _LWPID_T_DECLARED typedef __pid_t lwpid_t; #endif # 224 "/usr/include/sys/types.h" 3 4 #endif # 225 "/usr/include/sys/types.h" 3 4 #ifndef _SIZE_T_DECLARED #define _SIZE_T_DECLARED typedef __size_t size_t; #endif # 230 "/usr/include/sys/types.h" 3 4 #ifndef _SSIZE_T_DECLARED #define _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #endif # 235 "/usr/include/sys/types.h" 3 4 #ifndef _TIME_T_DECLARED #define _TIME_T_DECLARED typedef __time_t time_t; #endif # 240 "/usr/include/sys/types.h" 3 4 #ifndef _TIMER_T_DECLARED #define _TIMER_T_DECLARED typedef __timer_t timer_t; #endif # 245 "/usr/include/sys/types.h" 3 4 #if __BSD_VISIBLE #if 0 #include <sys/_fd_set.h> #endif # 248 "/usr/include/sys/types.h" 3 4 # 1 "/usr/include/sys/_fd_set.h" 1 3 4 #ifndef _SYS__FD_SET_H_ #define _SYS__FD_SET_H_ #ifndef FD_SETSIZE #define FD_SETSIZE 1024 #endif # 45 "/usr/include/sys/_fd_set.h" 3 4 #define __NBBY 8 typedef unsigned long __fd_mask; #define __NFDBITS ((unsigned int)sizeof(__fd_mask) * __NBBY) #ifndef __howmany #define __howmany(x, y) (((x) + ((y) - 1)) / (y)) #endif # 54 "/usr/include/sys/_fd_set.h" 3 4 typedef struct fd_set { __fd_mask fds_bits[__howmany(FD_SETSIZE, __NFDBITS)]; } fd_set; #define _fdset_mask(n) ((__fd_mask)1 << ((n) % __NFDBITS)) #define FD_SET(n, p) ((p)->fds_bits[(n)/__NFDBITS] |= _fdset_mask(n)) #define FD_CLR(n, p) ((p)->fds_bits[(n)/__NFDBITS] &= ~_fdset_mask(n)) #define FD_ISSET(n, p) ((p)->fds_bits[(n)/__NFDBITS] & _fdset_mask(n)) #define FD_ZERO(p) __builtin_memset((p), 0, sizeof(*(p))) #if __BSD_VISIBLE #define fd_mask __fd_mask #define NFDBITS __NFDBITS #ifndef howmany #define howmany(a, b) __howmany(a, b) #endif # 76 "/usr/include/sys/_fd_set.h" 3 4 #define FD_COPY(f, t) __builtin_memcpy((t), (f), sizeof(*(f))) #endif # 80 "/usr/include/sys/_fd_set.h" 3 4 #endif # 82 "/usr/include/sys/_fd_set.h" 3 4 # 249 "/usr/include/sys/types.h" 2 3 4 #if 0 #include <sys/_timeval.h> #endif # 249 "/usr/include/sys/types.h" 3 4 # 1 "/usr/include/sys/_timeval.h" 1 3 4 #ifndef _SYS__TIMEVAL_H_ #define _SYS__TIMEVAL_H_ #if 0 #include <machine/stdint.h> #endif # 35 "/usr/include/sys/_timeval.h" 3 4 # 36 "/usr/include/sys/_timeval.h" 3 4 #ifndef _SUSECONDS_T_DECLARED typedef __suseconds_t suseconds_t; #define _SUSECONDS_T_DECLARED #endif # 41 "/usr/include/sys/_timeval.h" 3 4 #ifndef _TIME_T_DECLARED typedef __time_t time_t; #define _TIME_T_DECLARED #endif # 46 "/usr/include/sys/_timeval.h" 3 4 struct timeval { time_t tv_sec; suseconds_t tv_usec; }; #endif # 56 "/usr/include/sys/_timeval.h" 3 4 # 250 "/usr/include/sys/types.h" 2 3 4 #define NBBY 8 #endif # 254 "/usr/include/sys/types.h" 3 4 typedef int __ct_rune_t; #ifndef ___RUNE_T_DECLARED typedef __ct_rune_t __rune_t; #define ___RUNE_T_DECLARED #endif # 275 "/usr/include/sys/types.h" 3 4 #ifndef ___WINT_T_DECLARED typedef __ct_rune_t __wint_t; #define ___WINT_T_DECLARED #endif # 279 "/usr/include/sys/types.h" 3 4 typedef int __nl_item; #if !defined(__clang__) || !defined(__cplusplus) typedef __uint_least16_t __char16_t; typedef __uint_least32_t __char32_t; #endif # 290 "/usr/include/sys/types.h" 3 4 #endif # 292 "/usr/include/sys/types.h" 3 4 # 39 "/usr/include/stdlib.h" 2 3 4 #if __BSD_VISIBLE #ifndef _RUNE_T_DECLARED typedef __rune_t rune_t; #define _RUNE_T_DECLARED #endif # 45 "/usr/include/stdlib.h" 3 4 #endif # 46 "/usr/include/stdlib.h" 3 4 #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif # 51 "/usr/include/stdlib.h" 3 4 #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef __wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif # 57 "/usr/include/stdlib.h" 3 4 #endif # 58 "/usr/include/stdlib.h" 3 4 typedef struct { int quot; int rem; } div_t; typedef struct { long quot; long rem; } ldiv_t; #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 #define RAND_MAX 0x7fffffff __BEGIN_DECLS #ifdef _XLOCALE_H_ #if 0 #include <xlocale/_stdlib.h> #endif # 76 "/usr/include/stdlib.h" 3 4 # 77 "/usr/include/stdlib.h" 3 4 #endif # 78 "/usr/include/stdlib.h" 3 4 extern int __mb_cur_max; extern int ___mb_cur_max(void); #define MB_CUR_MAX ((size_t)___mb_cur_max()) void abort(void) __dead2; #if !defined(_KERNEL_VIRTUAL) int abs(int) __pure2; #endif # 87 "/usr/include/stdlib.h" 3 4 int atexit(void (*)(void)); double atof(const char *); int atoi(const char *); long atol(const char *); void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); void *calloc(size_t, size_t) __alloc_size2(1, 2) __malloclike __heedresult; div_t div(int, int) __pure2; void exit(int) __dead2; void free(void *); char *getenv(const char *); #if !defined(_KERNEL_VIRTUAL) long labs(long) __pure2; #endif # 101 "/usr/include/stdlib.h" 3 4 ldiv_t ldiv(long, long) __pure2; void *malloc(size_t) __malloclike __heedresult __alloc_size(1); int mblen(const char *, size_t); size_t mbstowcs(wchar_t * __restrict , const char * __restrict, size_t); int mbtowc(wchar_t * __restrict, const char * __restrict, size_t); void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); int rand(void); void *realloc(void *, size_t) __heedresult __alloc_size(2); void srand(unsigned); double strtod(const char * __restrict, char ** __restrict); float strtof(const char * __restrict, char ** __restrict); #if !defined(_KERNEL_VIRTUAL) long strtol(const char * __restrict, char ** __restrict, int); #endif # 115 "/usr/include/stdlib.h" 3 4 long double strtold(const char * __restrict, char ** __restrict); #if !defined(_KERNEL_VIRTUAL) unsigned long strtoul(const char * __restrict, char ** __restrict, int); #endif # 121 "/usr/include/stdlib.h" 3 4 int system(const char *); int wctomb(char *, wchar_t); size_t wcstombs(char * __restrict, const wchar_t * __restrict, size_t); #if __ISO_C_VISIBLE >= 1999 || defined(__cplusplus) #ifdef __LONG_LONG_SUPPORTED typedef struct { long long quot; long long rem; } lldiv_t; long long atoll(const char *); long long llabs(long long) __pure2; lldiv_t lldiv(long long, long long) __pure2; long long strtoll(const char * __restrict, char ** __restrict, int); unsigned long long strtoull(const char * __restrict, char ** __restrict, int); #endif # 158 "/usr/include/stdlib.h" 3 4 void _Exit(int) __dead2; #endif # 161 "/usr/include/stdlib.h" 3 4 #if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L void *aligned_alloc(size_t, size_t) __malloclike __heedresult __alloc_align(1) __alloc_size(2); int at_quick_exit(void (*)(void)); void quick_exit(int) __dead2; #endif # 171 "/usr/include/stdlib.h" 3 4 #if __POSIX_VISIBLE >= 199506 int rand_r(unsigned *); #endif # 178 "/usr/include/stdlib.h" 3 4 #if __POSIX_VISIBLE >= 200112 int posix_memalign(void **, size_t, size_t) __nonnull(1); int setenv(const char *, const char *, int); int unsetenv(const char *); #endif # 183 "/usr/include/stdlib.h" 3 4 #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE int getsubopt(char **, char *const *, char **); #ifndef _MKDTEMP_DECLARED char *mkdtemp(char *); #define _MKDTEMP_DECLARED #endif # 190 "/usr/include/stdlib.h" 3 4 #ifndef _MKSTEMP_DECLARED int mkstemp(char *); #define _MKSTEMP_DECLARED #endif # 194 "/usr/include/stdlib.h" 3 4 #endif # 195 "/usr/include/stdlib.h" 3 4 #if __XSI_VISIBLE long a64l(const char *); double drand48(void); double erand48(unsigned short[3]); #if 0 #if __BSD_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 700) char *ecvt(double, int, int * __restrict, int * __restrict); char *fcvt(double, int, int * __restrict, int * __restrict); char *gcvt(double, int, int * __restrict, int * __restrict); #endif # 213 "/usr/include/stdlib.h" 3 4 #endif # 214 "/usr/include/stdlib.h" 3 4 int grantpt(int); char *initstate(unsigned long , char *, long); long jrand48(unsigned short[3]); char *l64a(long); void lcong48(unsigned short[7]); long lrand48(void); #if __BSD_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 700) #if !defined(_MKTEMP_DECLARED) char *mktemp(char *); #define _MKTEMP_DECLARED #endif # 225 "/usr/include/stdlib.h" 3 4 #endif # 226 "/usr/include/stdlib.h" 3 4 long mrand48(void); long nrand48(unsigned short[3]); int posix_openpt(int); char *ptsname(int); int putenv(char *); long random(void); char *realpath(const char * __restrict, char * __restrict); unsigned short *seed48(unsigned short[3]); int setkey(const char *); char *setstate( char *); void srand48(long); void srandom(unsigned long); int unlockpt(int); #endif # 241 "/usr/include/stdlib.h" 3 4 #if __BSD_VISIBLE #if __GNUC__ >= 2 || defined(__INTEL_COMPILER) #undef alloca #define alloca(sz) __builtin_alloca(sz) #endif # 258 "/usr/include/stdlib.h" 3 4 __uint32_t arc4random(void); void arc4random_addrandom(__uint8_t *, size_t); void arc4random_buf(void *, size_t); void arc4random_stir(void); __uint32_t arc4random_uniform(__uint32_t); char *getbsize(int *, long *); char *cgetcap(char *, const char *, int); int cgetclose(void); int cgetent(char **, char **, const char *); int cgetfirst(char **, char **); int cgetmatch(const char *, const char *); int cgetnext(char **, char **); int cgetnum(char *, const char *, long *); int cgetset(const char *); int cgetstr(char *, const char *, char **); int cgetustr(char *, const char *, char **); int daemon(int, int); char *devname(dev_t, mode_t); char *devname_r(dev_t, mode_t, char *, size_t); char *fdevname(int); int fdevname_r(int, char *, size_t); void freezero(void *, size_t); int getloadavg(double [], int); const char * getprogname(void); int heapsort(void *, size_t, size_t, int (*)(const void *, const void *)); int l64a_r(long, char *, int); int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); int mkostemp(char *, int); int mkostemps(char *, int, int); void qsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *)); int radixsort(const unsigned char **, int, const unsigned char *, unsigned int); void *reallocarray(void *, size_t, size_t) __heedresult __alloc_size2(2, 3); void *recallocarray(void *, size_t, size_t, size_t) __heedresult __alloc_size2(3, 4); void *reallocf(void *, size_t) __heedresult __alloc_size(2); int rpmatch(const char *); void setprogname(const char *); int sradixsort(const unsigned char **, int, const unsigned char *, unsigned int); void sranddev(void); void srandomdev(void); long long strsuftoll(const char *, const char *, long long, long long); long long strsuftollx(const char *, const char *, long long, long long, char *, size_t); long long strtonum(const char *, long long, long long, const char **); #if !defined(_KERNEL_VIRTUAL) __int64_t strtoq(const char *, char **, int); __uint64_t strtouq(const char *, char **, int); #endif # 324 "/usr/include/stdlib.h" 3 4 extern char *suboptarg; #endif # 327 "/usr/include/stdlib.h" 3 4 __END_DECLS #endif # 330 "/usr/include/stdlib.h" 3 4 # 16 "./aArray.h" 2 #if 0 #include <stdio.h> #endif # 16 "./aArray.h" # 1 "/usr/include/stdio.h" 1 3 4 #ifndef _STDIO_H_ #define _STDIO_H_ #if 0 #include <sys/cdefs.h> #endif # 39 "/usr/include/stdio.h" 3 4 # 40 "/usr/include/stdio.h" 3 4 #if 0 #include <sys/_null.h> #endif # 40 "/usr/include/stdio.h" 3 4 # 41 "/usr/include/stdio.h" 3 4 #if 0 #include <sys/types.h> #endif # 41 "/usr/include/stdio.h" 3 4 # 42 "/usr/include/stdio.h" 3 4 #if 0 #include <machine/stdarg.h> #endif # 42 "/usr/include/stdio.h" 3 4 # 1 "/usr/include/machine/stdarg.h" 1 3 4 #ifndef _CPU_STDARG_H_ #define _CPU_STDARG_H_ #if defined(__GNUC__) typedef __builtin_va_list __va_list; #else # 42 "/usr/include/machine/stdarg.h" 3 4 typedef char * __va_list; #endif # 44 "/usr/include/machine/stdarg.h" 3 4 #if defined __GNUC__ && !defined(__GNUC_VA_LIST) && !defined(__NO_GNUC_VA_LIST) #define __GNUC_VA_LIST typedef __va_list __gnuc_va_list; #endif # 48 "/usr/include/machine/stdarg.h" 3 4 #ifdef __GNUC__ #define __va_start(ap, last) \ __builtin_va_start(ap, last) #define __va_arg(ap, type) \ __builtin_va_arg((ap), type) #define __va_copy(dest, src) \ __builtin_va_copy((dest), (src)) #define __va_end(ap) \ __builtin_va_end(ap) #else # 65 "/usr/include/machine/stdarg.h" 3 4 #define __va_size(type) \ (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) #define __va_start(ap, last) \ ((ap) = (__va_list)&(last) + __va_size(last)) #define __va_arg(ap, type) \ (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) #define __va_copy(dest, src) \ ((void)((dest) = (src))) #define __va_end(ap) #endif # 79 "/usr/include/machine/stdarg.h" 3 4 #endif # 81 "/usr/include/machine/stdarg.h" 3 4 # 43 "/usr/include/stdio.h" 2 3 4 typedef __off_t fpos_t; #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif # 50 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE >= 200809 #ifndef _OFF_T_DECLARED #define _OFF_T_DECLARED typedef __off_t off_t; #endif # 56 "/usr/include/stdio.h" 3 4 #ifndef _SSIZE_T_DECLARED #define _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #endif # 60 "/usr/include/stdio.h" 3 4 #endif # 61 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE #ifdef __GNUC__ #ifndef _VA_LIST_DECLARED #define _VA_LIST_DECLARED typedef __va_list va_list; #endif # 69 "/usr/include/stdio.h" 3 4 #else # 70 "/usr/include/stdio.h" 3 4 #if 0 #include <stdarg.h> #endif # 70 "/usr/include/stdio.h" 3 4 # 71 "/usr/include/stdio.h" 3 4 #endif # 72 "/usr/include/stdio.h" 3 4 #endif # 73 "/usr/include/stdio.h" 3 4 #define _FSTDIO #ifndef _STDFILE_DECLARED #define _STDFILE_DECLARED typedef struct __FILE FILE; #endif # 100 "/usr/include/stdio.h" 3 4 struct __FILE_public { unsigned char *_p; int _flags; int _fileno; __ssize_t _r; __ssize_t _w; __ssize_t _lbfsize; }; #ifndef _STDSTREAM_DECLARED __BEGIN_DECLS extern FILE *__stdinp; extern FILE *__stdoutp; extern FILE *__stderrp; __END_DECLS #define _STDSTREAM_DECLARED #endif # 118 "/usr/include/stdio.h" 3 4 #define __SLBF 0x0001 #define __SNBF 0x0002 #define __SRD 0x0004 #define __SWR 0x0008 #define __SRW 0x0010 #define __SEOF 0x0020 #define __SERR 0x0040 #define __SMBF 0x0080 #define __SAPP 0x0100 #define __SSTR 0x0200 #define __SOPT 0x0400 #define __SNPT 0x0800 #define __SOFF 0x1000 #define __SMOD 0x2000 #define __SALC 0x4000 #define __SIGN 0x8000 #define _IOFBF 0 #define _IOLBF 1 #define _IONBF 2 #define BUFSIZ 1024 #define EOF (-1) #ifndef FOPEN_MAX #define FOPEN_MAX 20 #endif # 162 "/usr/include/stdio.h" 3 4 #define FILENAME_MAX 1024 #if __XSI_VISIBLE #define P_tmpdir "/tmp/" #endif # 168 "/usr/include/stdio.h" 3 4 #define L_tmpnam 1024 #define TMP_MAX 308915776 #ifndef SEEK_SET #define SEEK_SET 0 #endif # 175 "/usr/include/stdio.h" 3 4 #ifndef SEEK_CUR #define SEEK_CUR 1 #endif # 178 "/usr/include/stdio.h" 3 4 #ifndef SEEK_END #define SEEK_END 2 #endif # 181 "/usr/include/stdio.h" 3 4 #define stdin __stdinp #define stdout __stdoutp #define stderr __stderrp __BEGIN_DECLS void clearerr(FILE *); int fclose(FILE *); int feof(FILE *); int ferror(FILE *); int fflush(FILE *); int fgetc(FILE *); int fgetpos(FILE * __restrict, fpos_t * __restrict); char *fgets(char * __restrict, int, FILE * __restrict); FILE *fopen(const char * __restrict, const char * __restrict); int fprintf(FILE * __restrict, const char * __restrict, ...) __printflike(2, 3); int fputc(int, FILE *); int fputs(const char * __restrict, FILE * __restrict); size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); FILE *freopen(const char * __restrict, const char * __restrict, FILE * __restrict); int fscanf(FILE * __restrict, const char * __restrict, ...) __scanflike(2, 3); int fseek(FILE *, long, int); int fsetpos(FILE *, const fpos_t *); long ftell(FILE *); size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict); int getc(FILE *); int getchar(void); char *gets(char *); void perror(const char *); int printf(const char * __restrict, ...) __printflike(1, 2); int putc(int, FILE *); int putchar(int); int puts(const char *); int remove(const char *); int rename(const char *, const char *); void rewind(FILE *); int scanf(const char * __restrict, ...) __scanflike(1, 2); void setbuf(FILE * __restrict, char * __restrict); int setvbuf(FILE * __restrict, char * __restrict, int, size_t); int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3); int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3); FILE *tmpfile(void); char *tmpnam(char *); int ungetc(int, FILE *); int vfprintf(FILE * __restrict, const char * __restrict, __va_list) __printflike(2, 0); int vprintf(const char * __restrict, __va_list) __printflike(1, 0); int vsprintf(char * __restrict, const char * __restrict, __va_list) __printflike(2, 0); #if __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE >= 500 int snprintf(char * __restrict, size_t, const char * __restrict, ...) __printflike(3, 4); int vsnprintf(char * __restrict, size_t, const char * __restrict, __va_list) __printflike(3, 0); #endif # 245 "/usr/include/stdio.h" 3 4 #if __ISO_C_VISIBLE >= 1999 int vfscanf(FILE * __restrict, const char * __restrict, __va_list) __scanflike(2, 0); int vscanf(const char * __restrict, __va_list) __scanflike(1, 0); int vsscanf(const char * __restrict, const char * __restrict, __va_list) __scanflike(2, 0); #endif # 252 "/usr/include/stdio.h" 3 4 #if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE < 200112) #define L_cuserid 17 #endif # 259 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE #define L_ctermid 1024 char *ctermid(char *); FILE *fdopen(int, const char *); int fileno(FILE *); #endif # 267 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE >= 199209 int pclose(FILE *); FILE *popen(const char *, const char *); #endif # 272 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE >= 199506 int ftrylockfile(FILE *); void flockfile(FILE *); void funlockfile(FILE *); int getc_unlocked(FILE *); int getchar_unlocked(void); int putc_unlocked(int, FILE *); int putchar_unlocked(int); #endif # 287 "/usr/include/stdio.h" 3 4 #if __BSD_VISIBLE void clearerr_unlocked(FILE *); int feof_unlocked(FILE *); int ferror_unlocked(FILE *); int fileno_unlocked(FILE *); #endif # 293 "/usr/include/stdio.h" 3 4 #if __XSI_VISIBLE >= 500 || __POSIX_VISIBLE >= 200112 int fseeko(FILE *, __off_t, int); __off_t ftello(FILE *); #endif # 298 "/usr/include/stdio.h" 3 4 #if __BSD_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 600) int getw(FILE *); int putw(int, FILE *); #endif # 303 "/usr/include/stdio.h" 3 4 #if __XSI_VISIBLE char *tempnam(const char *, const char *); #endif # 307 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE >= 200809 FILE *fmemopen(void *__restrict, size_t, const char *__restrict); ssize_t getdelim(char ** __restrict, size_t * __restrict, int, FILE * __restrict); FILE *open_memstream(char **, size_t *); int renameat(int, const char *, int, const char *); int vdprintf(int, const char * __restrict, __va_list) __printflike(2, 0); int dprintf(int, const char * __restrict, ...) __printflike(2, 3); ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict); #endif # 318 "/usr/include/stdio.h" 3 4 #if __BSD_VISIBLE int asprintf(char **, const char *, ...) __printflike(2, 3); char *ctermid_r(char *); void fcloseall(void); void *fcookie(FILE *); char *fgetln(FILE *, size_t *); const char *fmtcheck(const char *, const char *) __format_arg(2); __ssize_t __fpending(const FILE *); int fpurge(FILE *); void setbuffer(FILE *, char *, int); int setlinebuf(FILE *); int vasprintf(char **, const char *, __va_list) __printflike(2, 0); extern const int sys_nerr; extern const char *const sys_errlist[]; FILE *funopen(const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), fpos_t (*)(void *, fpos_t, int), int (*)(void *)); #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) #endif # 352 "/usr/include/stdio.h" 3 4 int __srget(FILE *); int __swbuf(int, FILE *); static __inline __always_inline int __sgetc(FILE *_fp) { struct __FILE_public *_p = (struct __FILE_public *)_fp; if (--_p->_r < 0) return (__srget(_fp)); else return (*_p->_p++); } static __inline __always_inline int __sputc(int _c, FILE *_fp) { struct __FILE_public *_p = (struct __FILE_public *)_fp; if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && _c != '\n')) return (*_p->_p++ = _c); else return (__swbuf(_c, _fp)); } static __inline __always_inline int __sfeof(FILE *_fp) { struct __FILE_public *_p = (struct __FILE_public *)_fp; return ((_p->_flags & __SEOF) != 0); } static __inline __always_inline int __sferror(FILE *_fp) { struct __FILE_public *_p = (struct __FILE_public *)_fp; return ((_p->_flags & __SERR) != 0); } static __inline __always_inline void __sclearerr(FILE *_fp) { struct __FILE_public *_p = (struct __FILE_public *)_fp; _p->_flags &= ~(__SERR|__SEOF); } static __inline __always_inline int __sfileno(FILE *_fp) { struct __FILE_public *_p = (struct __FILE_public *)_fp; return (_p->_fileno); } #ifndef __LIBC_ISTHREADED_DECLARED #define __LIBC_ISTHREADED_DECLARED extern int __isthreaded; #endif # 421 "/usr/include/stdio.h" 3 4 #ifndef __cplusplus #define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p)) #define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p)) #define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p)) #if __POSIX_VISIBLE #define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p)) #endif # 430 "/usr/include/stdio.h" 3 4 #define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp)) #define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp)) #define getchar() getc(stdin) #define putchar(x) putc(x, stdout) #if __BSD_VISIBLE #define feof_unlocked(p) __sfeof(p) #define ferror_unlocked(p) __sferror(p) #define clearerr_unlocked(p) __sclearerr(p) #define fileno_unlocked(p) __sfileno(p) #endif # 447 "/usr/include/stdio.h" 3 4 #if __POSIX_VISIBLE >= 199506 #define getc_unlocked(fp) __sgetc(fp) #define putc_unlocked(x, fp) __sputc(x, fp) #define getchar_unlocked() getc_unlocked(stdin) #define putchar_unlocked(x) putc_unlocked(x, stdout) #endif # 454 "/usr/include/stdio.h" 3 4 #endif # 455 "/usr/include/stdio.h" 3 4 __END_DECLS #endif # 458 "/usr/include/stdio.h" 3 4 # 17 "./aArray.h" 2 #if 0 #include <string.h> // for memcmp #endif # 17 "./aArray.h" # 1 "/usr/include/string.h" 1 3 4 #ifndef _STRING_H_ #define _STRING_H_ #if 0 #include <sys/cdefs.h> #endif # 36 "/usr/include/string.h" 3 4 # 37 "/usr/include/string.h" 3 4 #if 0 #include <sys/_null.h> #endif # 37 "/usr/include/string.h" 3 4 # 38 "/usr/include/string.h" 3 4 #if 0 #include <sys/types.h> #endif # 38 "/usr/include/string.h" 3 4 # 39 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE #if 0 #include <strings.h> #endif # 45 "/usr/include/string.h" 3 4 # 1 "/usr/include/strings.h" 1 3 4 #ifndef _STRINGS_H_ #define _STRINGS_H_ #if 0 #include <sys/cdefs.h> #endif # 32 "/usr/include/strings.h" 3 4 # 33 "/usr/include/strings.h" 3 4 #if 0 #include <machine/stdint.h> #endif # 33 "/usr/include/strings.h" 3 4 # 34 "/usr/include/strings.h" 3 4 #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif # 39 "/usr/include/strings.h" 3 4 __BEGIN_DECLS #if !defined(_KERNEL_VIRTUAL) #if __BSD_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 700) int bcmp(const void *, const void *, size_t) __pure; void bcopy(const void *, void *, size_t); void bzero(void *, size_t); #endif # 47 "/usr/include/strings.h" 3 4 #if __BSD_VISIBLE void explicit_bzero(void *, size_t); #endif # 50 "/usr/include/strings.h" 3 4 int ffs(int) __pure2; #endif # 52 "/usr/include/strings.h" 3 4 #if __BSD_VISIBLE int ffsll(long long) __pure2; #if !defined(_KERNEL_VIRTUAL) int ffsl(long) __pure2; int fls(int) __pure2; int flsl(long) __pure2; int flsll(long long) __pure2; #endif # 60 "/usr/include/strings.h" 3 4 #endif # 61 "/usr/include/strings.h" 3 4 #if !defined(_KERNEL_VIRTUAL) #if __BSD_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE < 700) char *index(const char *, int) __pure; char *rindex(const char *, int) __pure; #endif # 66 "/usr/include/strings.h" 3 4 int strcasecmp(const char *, const char *) __pure; int strncasecmp(const char *, const char *, size_t) __pure; #endif # 69 "/usr/include/strings.h" 3 4 #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #if 0 #include <xlocale/_strings.h> #endif # 71 "/usr/include/strings.h" 3 4 # 1 "/usr/include/xlocale/_strings.h" 1 3 4 #ifndef _LOCALE_T_DEFINED #define _LOCALE_T_DEFINED typedef struct _xlocale *locale_t; #endif # 33 "/usr/include/xlocale/_strings.h" 3 4 #ifndef _XLOCALE_STRINGS1_H #define _XLOCALE_STRINGS1_H int strcasecmp_l(const char *, const char *, locale_t); int strncasecmp_l(const char *, const char *, size_t, locale_t); #endif # 49 "/usr/include/xlocale/_strings.h" 3 4 # 72 "/usr/include/strings.h" 2 3 4 #endif # 73 "/usr/include/strings.h" 3 4 __END_DECLS #endif # 76 "/usr/include/strings.h" 3 4 # 46 "/usr/include/string.h" 2 3 4 #endif # 47 "/usr/include/string.h" 3 4 #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif # 52 "/usr/include/string.h" 3 4 __BEGIN_DECLS #if __XSI_VISIBLE >= 600 void *memccpy(void * __restrict, const void * __restrict, int, size_t); #endif # 57 "/usr/include/string.h" 3 4 void *memchr(const void *, int, size_t) __pure; #if __BSD_VISIBLE void *memrchr(const void *, int, size_t) __pure; #endif # 61 "/usr/include/string.h" 3 4 #if !defined(_KERNEL_VIRTUAL) int memcmp(const void *, const void *, size_t) __pure; void *memcpy(void * __restrict, const void * __restrict, size_t); #endif # 65 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE void *memmem(const void *, size_t, const void *, size_t) __pure; void *mempcpy(void *, const void *, size_t); #endif # 69 "/usr/include/string.h" 3 4 #if !defined(_KERNEL_VIRTUAL) void *memmove(void *, const void *, size_t); void *memset(void *, int, size_t); #endif # 73 "/usr/include/string.h" 3 4 #if __POSIX_VISIBLE >= 200809 char *stpcpy(char * __restrict, const char * __restrict); char *stpncpy(char * __restrict, const char * __restrict, size_t); #endif # 77 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE char *strcasestr(const char *, const char *) __pure; #endif # 80 "/usr/include/string.h" 3 4 #if !defined(_KERNEL_VIRTUAL) char *strcat(char * __restrict, const char * __restrict); char *strchr(const char *, int) __pure; int strcmp(const char *, const char *) __pure; #endif # 85 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE char *strchrnul(const char*, int) __pure; #endif # 88 "/usr/include/string.h" 3 4 int strcoll(const char *, const char *); #if !defined(_KERNEL_VIRTUAL) char *strcpy(char * __restrict, const char * __restrict); #endif # 92 "/usr/include/string.h" 3 4 size_t strcspn(const char *, const char *) __pure; #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE char *strdup(const char *) __malloclike; #endif # 96 "/usr/include/string.h" 3 4 char *strerror(int); #if __POSIX_VISIBLE >= 200112 int strerror_r(int, char *, size_t); #endif # 100 "/usr/include/string.h" 3 4 #if !defined(_KERNEL_VIRTUAL) #if __BSD_VISIBLE size_t strlcat(char * __restrict, const char * __restrict, size_t); size_t strlcpy(char * __restrict, const char * __restrict, size_t); #endif # 105 "/usr/include/string.h" 3 4 size_t strlen(const char *) __pure; #endif # 107 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE void strmode(mode_t, char *); #endif # 110 "/usr/include/string.h" 3 4 #if !defined(_KERNEL_VIRTUAL) char *strncat(char * __restrict, const char * __restrict, size_t); int strncmp(const char *, const char *, size_t) __pure; char *strncpy(char * __restrict, const char * __restrict, size_t); #endif # 115 "/usr/include/string.h" 3 4 #if __POSIX_VISIBLE >= 200809 char *strndup(const char *, size_t) __malloclike; #if !defined(_KERNEL_VIRTUAL) size_t strnlen(const char *, size_t) __pure; #endif # 120 "/usr/include/string.h" 3 4 #endif # 121 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE char *strnstr(const char *, const char *, size_t) __pure; #endif # 124 "/usr/include/string.h" 3 4 char *strpbrk(const char *, const char *) __pure; #if !defined(_KERNEL_VIRTUAL) char *strrchr(const char *, int) __pure; #endif # 128 "/usr/include/string.h" 3 4 #if __BSD_VISIBLE #if !defined(_KERNEL_VIRTUAL) char *strsep(char **, const char *); #endif # 132 "/usr/include/string.h" 3 4 #endif # 133 "/usr/include/string.h" 3 4 #if __POSIX_VISIBLE >= 200809 char *strsignal(int); #endif # 136 "/usr/include/string.h" 3 4 size_t strspn(const char *, const char *) __pure; #if !defined(_KERNEL_VIRTUAL) char *strstr(const char *, const char *) __pure; #endif # 140 "/usr/include/string.h" 3 4 char *strtok(char * __restrict, const char * __restrict); #if __POSIX_VISIBLE >= 199506 char *strtok_r(char * __restrict, const char * __restrict, char ** __restrict); #endif # 145 "/usr/include/string.h" 3 4 size_t strxfrm(char * __restrict, const char * __restrict, size_t); #if __BSD_VISIBLE int timingsafe_bcmp(const void *, const void *, size_t) __pure; int timingsafe_memcmp(const void *, const void *, size_t) __pure; #endif # 150 "/usr/include/string.h" 3 4 #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #if 0 #include <xlocale/_string.h> #endif # 152 "/usr/include/string.h" 3 4 # 1 "/usr/include/xlocale/_string.h" 1 3 4 #ifndef _LOCALE_T_DEFINED #define _LOCALE_T_DEFINED typedef struct _xlocale *locale_t; #endif # 33 "/usr/include/xlocale/_string.h" 3 4 #ifndef _XLOCALE_STRING1_H #define _XLOCALE_STRING1_H int strcoll_l(const char *, const char *, locale_t); size_t strxfrm_l(char * __restrict, const char * __restrict, size_t, locale_t); #endif # 50 "/usr/include/xlocale/_string.h" 3 4 #ifdef _XLOCALE_H_ #ifndef _XLOCALE_STRING2_H #define _XLOCALE_STRING2_H char *strcasestr_l(const char *, const char *, locale_t); #endif # 60 "/usr/include/xlocale/_string.h" 3 4 #endif # 61 "/usr/include/xlocale/_string.h" 3 4 # 153 "/usr/include/string.h" 2 3 4 #endif # 154 "/usr/include/string.h" 3 4 __END_DECLS #endif # 157 "/usr/include/string.h" 3 4 # 18 "./aArray.h" 2 #if 0 #include <math.h> // for sqrt #endif # 18 "./aArray.h" # 1 "/usr/include/math.h" 1 3 4 #ifndef _MATH_H_ #define _MATH_H_ #if 0 #include <sys/types.h> #endif # 20 "/usr/include/math.h" 3 4 # 21 "/usr/include/math.h" 3 4 #if 0 #include <sys/limits.h> #endif # 21 "/usr/include/math.h" 3 4 # 1 "/usr/include/sys/limits.h" 1 3 4 #ifndef _SYS_LIMITS_H_ #define _SYS_LIMITS_H_ #if 0 #include <machine/limits.h> #endif # 36 "/usr/include/sys/limits.h" 3 4 # 1 "/usr/include/machine/limits.h" 1 3 4 #ifndef _CPU_LIMITS_H_ #define _CPU_LIMITS_H_ #if 0 #include <sys/cdefs.h> #endif # 36 "/usr/include/machine/limits.h" 3 4 # 37 "/usr/include/machine/limits.h" 3 4 #define CHAR_BIT 8 #define MB_LEN_MAX 6 #define SCHAR_MAX 0x7f #define SCHAR_MIN (-0x7f - 1) #define UCHAR_MAX 0xff #ifdef __CHAR_UNSIGNED__ #define CHAR_MAX UCHAR_MAX #define CHAR_MIN 0 #else # 60 "/usr/include/machine/limits.h" 3 4 #define CHAR_MAX SCHAR_MAX #define CHAR_MIN SCHAR_MIN #endif # 63 "/usr/include/machine/limits.h" 3 4 #define USHRT_MAX 0xffff #define SHRT_MAX 0x7fff #define SHRT_MIN (-0x7fff - 1) #define UINT_MAX 0xffffffffU #define INT_MAX 0x7fffffff #define INT_MIN (-0x7fffffff - 1) #if defined(__x86_64__) #define ULONG_MAX 0xffffffffffffffffUL #define LONG_MAX 0x7fffffffffffffffL #define LONG_MIN (-0x7fffffffffffffffL - 1) #ifdef __LONG_LONG_SUPPORTED #define ULLONG_MAX 0xffffffffffffffffULL #define LLONG_MAX 0x7fffffffffffffffLL #define LLONG_MIN (-0x7fffffffffffffffLL - 1) #endif # 82 "/usr/include/machine/limits.h" 3 4 #elif defined(__i386__) # 83 "/usr/include/machine/limits.h" 3 4 #define ULONG_MAX 0xffffffffUL #define LONG_MAX 0x7fffffffUL #define LONG_MIN (-0x7fffffffL - 1) #ifdef __LONG_LONG_SUPPORTED #define ULLONG_MAX 0xffffffffULL #define LLONG_MAX 0x7fffffffLL #define LLONG_MIN (-0x7fffffffLL - 1) #endif # 92 "/usr/include/machine/limits.h" 3 4 #endif # 93 "/usr/include/machine/limits.h" 3 4 #if __POSIX_VISIBLE || __XSI_VISIBLE #define SSIZE_MAX LONG_MAX #endif # 97 "/usr/include/machine/limits.h" 3 4 #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #define SIZE_T_MAX ULONG_MAX #define OFF_MAX LONG_MAX #define OFF_MIN LONG_MIN #endif # 104 "/usr/include/machine/limits.h" 3 4 #if __BSD_VISIBLE #define GID_MAX UINT_MAX #define UID_MAX UINT_MAX #define UQUAD_MAX ULLONG_MAX #define QUAD_MAX LLONG_MAX #define QUAD_MIN LLONG_MIN #endif # 114 "/usr/include/machine/limits.h" 3 4 #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809 #if defined(__x86_64__) #define LONG_BIT 64 #elif defined(__i386__) # 119 "/usr/include/machine/limits.h" 3 4 #define LONG_BIT 32 #endif # 121 "/usr/include/machine/limits.h" 3 4 #define WORD_BIT 32 #endif # 123 "/usr/include/machine/limits.h" 3 4 #endif # 125 "/usr/include/machine/limits.h" 3 4 # 37 "/usr/include/sys/limits.h" 2 3 4 #endif # 39 "/usr/include/sys/limits.h" 3 4 # 22 "/usr/include/math.h" 2 3 4 __BEGIN_DECLS extern char __infinity[]; #if __GNUC_PREREQ__(3, 3) && !defined(__vax__) #define HUGE_VAL __builtin_huge_val() #else # 31 "/usr/include/math.h" 3 4 #define HUGE_VAL (*(double *)(void *)__infinity) #endif # 33 "/usr/include/math.h" 3 4 #if __ISO_C_VISIBLE >= 1999 typedef double double_t; typedef float float_t; #if __GNUC_PREREQ__(3, 3) && !defined(__vax__) #define HUGE_VALF __builtin_huge_valf() #define HUGE_VALL __builtin_huge_vall() #define INFINITY __builtin_inff() #define NAN __builtin_nanf("") #else # 47 "/usr/include/math.h" 3 4 #ifdef __vax__ extern char __infinityf[]; #define HUGE_VALF (*(float *)(void *)__infinityf) #else # 51 "/usr/include/math.h" 3 4 #define HUGE_VALF ((float)HUGE_VAL) #endif # 53 "/usr/include/math.h" 3 4 #define HUGE_VALL ((long double)HUGE_VAL) #define INFINITY HUGE_VALF #ifndef __vax__ extern char __nan[]; #define NAN (*(float *)(void *)__nan) #endif # 59 "/usr/include/math.h" 3 4 #endif # 60 "/usr/include/math.h" 3 4 #define FP_INFINITE 0x01 #define FP_NAN 0x02 #define FP_NORMAL 0x04 #define FP_SUBNORMAL 0x08 #define FP_ZERO 0x10 #define FP_ILOGB0 (-INT_MAX) #define FP_ILOGBNAN INT_MAX #define FP_FAST_FMAF 1 #define MATH_ERRNO 1 #define MATH_ERREXCEPT 2 #define math_errhandling MATH_ERREXCEPT #define fpclassify(x) \ ((sizeof (x) == sizeof (float)) ? \ __fpclassifyf(x) \ : (sizeof (x) == sizeof (double)) ? \ __fpclassifyd(x) \ : __fpclassifyl(x)) #define isfinite(x) \ ((sizeof (x) == sizeof (float)) ? \ __isfinitef(x) \ : (sizeof (x) == sizeof (double)) ? \ __isfinite(x) \ : __isfinitel(x)) #define isnormal(x) \ ((sizeof (x) == sizeof (float)) ? \ __isnormalf(x) \ : (sizeof (x) == sizeof (double)) ? \ __isnormal(x) \ : __isnormall(x)) #define signbit(x) \ ((sizeof (x) == sizeof (float)) ? \ __signbitf(x) \ : (sizeof (x) == sizeof (double)) ? \ __signbit(x) \ : __signbitl(x)) #define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y)) #define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y)) #define isless(x, y) (!isunordered((x), (y)) && (x) < (y)) #define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y)) #define islessgreater(x, y) (!isunordered((x), (y)) && \ ((x) > (y) || (y) > (x))) #define isunordered(x, y) (isnan(x) || isnan(y)) #endif # 115 "/usr/include/math.h" 3 4 #define isinf(x) \ ((sizeof (x) == sizeof (float)) ? \ __isinff(x) \ : (sizeof (x) == sizeof (double)) ? \ __isinf(x) \ : __isinfl(x)) #define isnan(x) \ ((sizeof (x) == sizeof (float)) ? \ __isnanf(x) \ : (sizeof (x) == sizeof (double)) ? \ __isnan(x) \ : __isnanl(x)) #if __BSD_VISIBLE || __XSI_VISIBLE #define M_E ((double)2.7182818284590452354) #define M_LOG2E ((double)1.4426950408889634074) #define M_LOG10E ((double)0.43429448190325182765) #define M_LN2 ((double)0.69314718055994530942) #define M_LN10 ((double)2.30258509299404568402) #define M_PI ((double)3.14159265358979323846) #define M_PI_2 ((double)1.57079632679489661923) #define M_PI_4 ((double)0.78539816339744830962) #define M_1_PI ((double)0.31830988618379067154) #define M_2_PI ((double)0.63661977236758134308) #define M_2_SQRTPI ((double)1.12837916709551257390) #define M_SQRT2 ((double)1.41421356237309504880) #define M_SQRT1_2 ((double)0.70710678118654752440) #ifdef __vax__ #define MAXFLOAT ((float)1.70141173319264430e+38) #else # 150 "/usr/include/math.h" 3 4 #define MAXFLOAT ((float)3.40282346638528860e+38) #endif # 152 "/usr/include/math.h" 3 4 extern int signgam; #endif # 155 "/usr/include/math.h" 3 4 #if __POSIX_VISIBLE >= 201403 #define M_El 2.718281828459045235360287471352662498L #define M_LOG2El 1.442695040888963407359924681001892137L #define M_LOG10El 0.434294481903251827651128918916605082L #define M_LN2l 0.693147180559945309417232121458176568L #define M_LN10l 2.302585092994045684017991454684364208L #define M_PIl 3.141592653589793238462643383279502884L #define M_PI_2l 1.570796326794896619231321691639751442L #define M_PI_4l 0.785398163397448309615660845819875721L #define M_1_PIl 0.318309886183790671537767526745028724L #define M_2_PIl 0.636619772367581343075535053490057448L #define M_2_SQRTPIl 1.128379167095512573896158903121545172L #define M_SQRT2l 1.414213562373095048801688724209698079L #define M_SQRT1_2l 0.707106781186547524400844362104849039L #endif # 171 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE #define HUGE MAXFLOAT #endif # 175 "/usr/include/math.h" 3 4 double acos(double); double asin(double); double atan(double); double atan2(double, double); double cos(double); double sin(double); double tan(double); double cosh(double); double sinh(double); double tanh(double); double exp(double); double frexp(double, int *); double ldexp(double, int); double log(double); double log10(double); double modf(double, double *); double pow(double, double); double sqrt(double); double ceil(double); double fabs(double); double floor(double); double fmod(double, double); #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE double acosh(double); double asinh(double); double atanh(double); double exp2(double); double expm1(double); int ilogb(double); double log1p(double); double log2(double); double logb(double); double scalbn(double, int); double scalbln(double, long int); double cbrt(double); double hypot(double, double); double erf(double); double erfc(double); double lgamma(double); double tgamma(double); double nearbyint(double); double rint(double); long int lrint(double); long long int llrint(double); double round(double); long int lround(double); long long int llround(double); double trunc(double); double remainder(double, double); double remquo(double, double, int *); double copysign(double, double); double nan(const char *); double nextafter(double, double); double nexttoward(double, long double); double fdim(double, double); double fmax(double, double); double fmin(double, double); double fma(double, double, double); #endif # 254 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE || __XSI_VISIBLE double j0(double); double j1(double); double jn(int, double); double y0(double); double y1(double); double yn(int, double); #endif # 263 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE || __XSI_VISIBLE <= 500 double gamma(double); #endif # 267 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE || __XSI_VISIBLE <= 600 double scalb(double, double); #endif # 271 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE double drem(double, double); int finite(double); double gamma_r(double, int *); double lgamma_r(double, int *); double significand(double); #endif # 291 "/usr/include/math.h" 3 4 #if __ISO_C_VISIBLE >= 1999 float acosf(float); float asinf(float); float atanf(float); float atan2f(float, float); float cosf(float); float sinf(float); float tanf(float); float acoshf(float); float asinhf(float); float atanhf(float); float coshf(float); float sinhf(float); float tanhf(float); float expf(float); float exp2f(float); float expm1f(float); float frexpf(float, int *); int ilogbf(float); float ldexpf(float, int); float logf(float); float log10f(float); float log1pf(float); float log2f(float); float logbf(float); float modff(float, float *); float scalbnf(float, int); float scalblnf(float, long int); float cbrtf(float); float fabsf(float); float hypotf(float, float); float powf(float, float); float sqrtf(float); float erff(float); float erfcf(float); float lgammaf(float); float tgammaf(float); float ceilf(float); float floorf(float); float nearbyintf(float); float rintf(float); long int lrintf(float); long long int llrintf(float); float roundf(float); long int lroundf(float); long long int llroundf(float); float truncf(float); float fmodf(float, float); float remainderf(float, float); float remquof(float, float, int *); float copysignf(float, float); float nanf(const char *); float nextafterf(float, float); float nexttowardf(float, long double); float fdimf(float, float); float fmaxf(float, float); float fminf(float, float); float fmaf(float, float, float); #endif # 363 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE || __XSI_VISIBLE float j0f(float); float j1f(float); float jnf(int, float); float scalbf(float, float); float y0f(float); float y1f(float); float ynf(int, float); #endif # 373 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE || __XSI_VISIBLE <= 500 float gammaf(float); #endif # 377 "/usr/include/math.h" 3 4 #if __BSD_VISIBLE float dremf(float, float); int finitef(float); int isinff(float); int isnanf(float); float gammaf_r(float, int *); float lgammaf_r(float, int *); float significandf(float); #endif # 400 "/usr/include/math.h" 3 4 #if __ISO_C_VISIBLE >= 1999 long double acosl(long double); long double asinl(long double); long double atanl(long double); long double atan2l(long double, long double); long double cosl(long double); long double sinl(long double); long double tanl(long double); long double acoshl(long double); long double asinhl(long double); long double atanhl(long double); long double coshl(long double); long double sinhl(long double); long double tanhl(long double); long double expl(long double); long double exp2l(long double); long double expm1l(long double); long double frexpl(long double, int *); int ilogbl(long double); long double ldexpl(long double, int); long double logl(long double); long double log10l(long double); long double log1pl(long double); long double log2l(long double); long double logbl(long double); long double modfl(long double, long double *); long double scalbnl(long double, int); long double scalblnl(long double, long int); long double cbrtl(long double); long double fabsl(long double); long double hypotl(long double, long double); long double powl(long double, long double); long double sqrtl(long double); long double erfl(long double); long double erfcl(long double); long double lgammal(long double); long double tgammal(long double); long double ceill(long double); long double floorl(long double); long double nearbyintl(long double); long double rintl(long double); long int lrintl(long double); long long int llrintl(long double); long double roundl(long double); long int lroundl(long double); long long int llroundl(long double); long double truncl(long double); long double fmodl(long double, long double); long double remainderl(long double, long double); long double remquol(long double, long double, int *); long double copysignl(long double, long double); long double nanl(const char *); long double nextafterl(long double, long double); long double nexttowardl(long double, long double); long double fdiml(long double, long double); long double fmaxl(long double, long double); long double fminl(long double, long double); long double fmal(long double, long double, long double); #endif # 472 "/usr/include/math.h" 3 4 int __fpclassifyd(double); int __fpclassifyf(float); int __fpclassifyl(long double); int __isfinite(double); int __isfinitef(float); int __isfinitel(long double); int __isinf(double); int __isinff(float); int __isinfl(long double); int __isnan(double); int __isnanf(float); int __isnanl(long double); int __isnormal(double); int __isnormalf(float); int __isnormall(long double); int __signbit(double); int __signbitf(float); int __signbitl(long double); #if __BSD_VISIBLE && defined(__vax__) double infnan(int); #endif # 498 "/usr/include/math.h" 3 4 __END_DECLS #endif # 501 "/usr/include/math.h" 3 4 # 19 "./aArray.h" 2 #if defined(_MSC_VER) #if 0 #include <malloc.h> // for msvc realloc #endif # 20 "./aArray.h" # 21 "./aArray.h" #endif # 22 "./aArray.h" #if defined(__cplusplus) #if 0 #include <functional> // for lambda #endif # 23 "./aArray.h" # 24 "./aArray.h" #endif # 25 "./aArray.h" //// $defines are for pre-pre-processed macros // this simplifies end-user compiler messages // if this is aArray.h, they will have already reduced to the final exposed api //// handle warnings // many parameters take an arbitrary mix of pointers/integers // so optionally suppress warnings only for those parameters //// c++ is available but not advertised and not advised // start-end block suppresses some c++ warnings // i.e. (cast) not being static_cast<cast>(), c++98-compat, etc #define AARRAY_nowarn_pedantic_cpp_start #define AARRAY_nowarn_pedantic_cpp_end #define AARRAY_nowarn_align(STATEMENT) STATEMENT #if defined(__clang__) // these are slightly redundant, but handle both clang and gcc #if defined(__cplusplus) #define AARRAY_nowarn_start \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wconversion\"") \ _Pragma("clang diagnostic ignored \"-Wconversion-null\"") \ _Pragma("clang diagnostic ignored \"-Woverflow\"") \ _Pragma("clang diagnostic ignored \"-Wnarrowing\"") #else # 52 "./aArray.h" #define AARRAY_nowarn_start \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wconversion\"") \ _Pragma("clang diagnostic ignored \"-Wint-conversion\"") \ _Pragma("clang diagnostic ignored \"-Wpointer-to-int-cast\"") \ _Pragma("clang diagnostic ignored \"-Wbad-function-cast\"") #endif # 59 "./aArray.h" #define AARRAY_nowarn_end _Pragma("clang diagnostic pop") #if defined(__cplusplus) #undef AARRAY_nowarn_pedantic_cpp_start #define AARRAY_nowarn_pedantic_cpp_start_helper \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wc99-extensions\"") \ _Pragma("clang diagnostic ignored \"-Wc++98-compat-pedantic\"") \ _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ _Pragma("clang diagnostic ignored \"-Wcast-qual\"") #if __clang_major__ < 5 #define AARRAY_nowarn_pedantic_cpp_start \ AARRAY_nowarn_pedantic_cpp_start_helper #else # 72 "./aArray.h" #define AARRAY_nowarn_pedantic_cpp_start \ AARRAY_nowarn_pedantic_cpp_start_helper \ _Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"") #endif # 76 "./aArray.h" #undef AARRAY_nowarn_pedantic_cpp_end #define AARRAY_nowarn_pedantic_cpp_end _Pragma("clang diagnostic pop") #endif # 79 "./aArray.h" #undef AARRAY_nowarn_align #define AARRAY_nowarn_align(STATEMENT) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wcast-align\"") \ STATEMENT _Pragma("clang diagnostic pop") #elif defined(__GNUC__) # 85 "./aArray.h" // these are slightly redundant, but handle both clang and gcc #if defined(__cplusplus) #define AARRAY_nowarn_start \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wconversion\"") \ _Pragma("GCC diagnostic ignored \"-Wconversion-null\"") \ _Pragma("GCC diagnostic ignored \"-Woverflow\"") \ _Pragma("GCC diagnostic ignored \"-Wnarrowing\"") #else # 94 "./aArray.h" #define AARRAY_nowarn_start \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wconversion\"") \ _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ _Pragma("GCC diagnostic ignored \"-Wpointer-to-int-cast\"") \ _Pragma("GCC diagnostic ignored \"-Wbad-function-cast\"") #endif # 101 "./aArray.h" #define AARRAY_nowarn_end _Pragma("GCC diagnostic pop") #if defined(__cplusplus) #undef AARRAY_nowarn_pedantic_cpp_start #undef AARRAY_nowarn_pedantic_cpp_end #define AARRAY_nowarn_pedantic_cpp_start \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wpedantic\"") #define AARRAY_nowarn_pedantic_cpp_end _Pragma("GCC diagnostic pop") #endif # 110 "./aArray.h" #elif defined(_MSC_VER) # 111 "./aArray.h" #define AARRAY_nowarn_start \ __pragma(warning(push)) \ __pragma(warning(disable:4047)) #define AARRAY_nowarn_end __pragma(warning(pop)) #else # 116 "./aArray.h" // don't hide int-pointer conversion warnings for this compiler #define AARRAY_nowarn_start #define AARRAY_nowarn_end #endif # 120 "./aArray.h" #if defined(__cplusplus) AARRAY_nowarn_pedantic_cpp_start #define AARRAY_move std::move #else # 125 "./aArray.h" #define AARRAY_move #endif # 127 "./aArray.h" //// compile as .c .h, or as a single header with 'static inline' functions #if defined(AARRAY_c) #define AARRAY_define(name, ...) name __VA_ARGS__ #elif defined(AARRAY_h) # 135 "./aArray.h" #define AARRAY_define(name, ...) extern name; #else # 137 "./aArray.h" #define AARRAY_define(name, ...) static inline name __VA_ARGS__ #endif # 139 "./aArray.h" //// general compiler compatibility #if !defined(__has_feature) #define __has_feature(x) 0 #endif # 144 "./aArray.h" #if !defined(__has_extension) // pre-3.0 clang #define __has_extension __has_feature #endif # 148 "./aArray.h" #if defined(__builtin_prefetch) #define AARRAY_prefetch(A, B, C) __builtin_prefetch(A, B, C) #else # 152 "./aArray.h" #define AARRAY_prefetch(A, B, C) #endif # 154 "./aArray.h" //// switch on/off safety checks #if defined(AARRAY_UNSAFE) #define AARRAY_safety(UNSAFE, ...) UNSAFE #else # 159 "./aArray.h" #define AARRAY_safety(UNSAFE, ...) __VA_ARGS__ #endif # 161 "./aArray.h" //// switch on/off type warnings for generics #if defined(AARRAY_WARN) || (defined(__GNUC__) && !defined(__clang__)) // gcc can't handle pragmas within expressions, and so misses out #define AARRAY_nowarn_internal_start #define AARRAY_nowarn_internal_end #else # 168 "./aArray.h" #define AARRAY_nowarn_internal_start AARRAY_nowarn_start #define AARRAY_nowarn_internal_end AARRAY_nowarn_end #endif # 171 "./aArray.h" //// set the size of aSort's cache #if !defined(AARRAY_sortCache) #define AARRAY_sortCache 512 #endif # 176 "./aArray.h" //// error handling AARRAY_define(__attribute((noreturn)) void AARRAY_aError(char errLocation[], char errMsg[]), { fflush(stdout); fprintf(stderr, "%s: %s\n", errLocation, errMsg); abort(); }) // set the default handler #if defined(AARRAY_c) void (*aError)(char[], char[]) = &AARRAY_aError; #elif defined(AARRAY_h) # 188 "./aArray.h" extern void (*aError)(char[], char[]); #else # 190 "./aArray.h" static void (*aError)(char[], char[]) = &AARRAY_aError; #endif # 192 "./aArray.h" // generate "file.c:line_number" for error messages #define AARRAY_STRINGIFY(x) #x #define AARRAY_TOSTRING(x) AARRAY_STRINGIFY(x) #define AARRAY_LINE (char*)__FILE__ ":" AARRAY_TOSTRING(__LINE__) // generate error messages #define AARRAY_aError_MsgLen 52 + 3*20 + 1 #define AARRAY_aError_CALL(MSG) { aError(errLoc, MSG); abort(); } #define AARRAY_Error_OutOfMemory(SIZE) \ { char AARRAY_aError_Msg[AARRAY_aError_MsgLen]; \ if(0>snprintf(AARRAY_aError_Msg, AARRAY_aError_MsgLen, \ "out of memory (allocating=%zu)", \ SIZE)) \ AARRAY_aError_CALL((char*)"out of memory " \ "(can I interest you in a banana instead? 🍌 )") \ else AARRAY_aError_CALL(AARRAY_aError_Msg) } #define AARRAY_Error_OutOfBounds(LENGTH, POS) \ { char AARRAY_aError_Msg[AARRAY_aError_MsgLen]; \ if(0>snprintf(AARRAY_aError_Msg, AARRAY_aError_MsgLen, \ "out of bounds (length=%zu but pos=%zu)", \ LENGTH, POS)) \ AARRAY_aError_CALL((char*)"out of bounds (no info)") \ else AARRAY_aError_CALL(AARRAY_aError_Msg) } #define AARRAY_Error_RemovalIsOutOfBounds(LENGTH, POS, RLEN) \ { char AARRAY_aError_Msg[AARRAY_aError_MsgLen]; \ if(0>snprintf(AARRAY_aError_Msg, AARRAY_aError_MsgLen, \ "removal is out of bounds (length=%zu but pos=%zu removal=%zu)", \ LENGTH, POS, RLEN)) \ AARRAY_aError_CALL((char*)"removal is out of bounds (no info)") \ else AARRAY_aError_CALL(AARRAY_aError_Msg) } #define AARRAY_Error_ArrayIsStatic(LENGTH) \ { char AARRAY_aError_Msg[AARRAY_aError_MsgLen]; \ if(0>snprintf(AARRAY_aError_Msg, AARRAY_aError_MsgLen, \ "array is STATIC (length=%zu)", LENGTH)) \ AARRAY_aError_CALL((char*)"array is STATIC (no info)") \ else AARRAY_aError_CALL(AARRAY_aError_Msg) } #define AARRAY_Error_ArrayIsNull(ARRAY_NO) \ { char AARRAY_aError_Msg[AARRAY_aError_MsgLen]; \ if(0>snprintf(AARRAY_aError_Msg, AARRAY_aError_MsgLen, \ "array is NULL (array no=%zu)", ARRAY_NO)) \ AARRAY_aError_CALL((char*)"array is NULL (no info)") \ else AARRAY_aError_CALL(AARRAY_aError_Msg) } #define AARRAY_Error_ArrayIsWide \ (aError(AARRAY_LINE, (char*)"array type too wide (max 8 bytes)"), 0) #define AARRAY_Error_WrongArgCount(ARG_NUM, MULTIPLE, ADDITION) \ { char AARRAY_aError_Msg[AARRAY_aError_MsgLen]; \ if(0>snprintf(AARRAY_aError_Msg, AARRAY_aError_MsgLen, \ "wrong arg count (args=%zu but should be %i + multiple of %i)", \ ARG_NUM, ADDITION, MULTIPLE)) \ AARRAY_aError_CALL((char*)"wrong arg count (no info)") \ else AARRAY_aError_CALL(AARRAY_aError_Msg) } #define AARRAY_Error_InfiniteLoop \ AARRAY_aError_CALL((char*)"infinite loop (jump=0)") #define AARRAY_Error_FormatStringArgs \ AARRAY_aError_CALL((char*)"format requires more arguments") #define AARRAY_Error_FormatStringMalformed \ AARRAY_aError_CALL((char*)"format is malformed") #define AARRAY_Error_NullParameter \ AARRAY_aError_CALL((char*)"parameter is NULL") //// foundations for array allocation AARRAY_define(size_t AARRAY_upper_power_of_two(size_t v), { // from: graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 // very slightly faster than: 1<<(64-AARRAY_BUILTIN_LL(clz,v-1)) ////if __LP64__ >> 32 v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; if(sizeof(size_t)==8) v |= v >> 32; v++; return v; }) // cross platform count-leading-zeros #if defined(__GNUC__) #define AARRAY_builtin_ll(name,with) \ (sizeof(with)<=sizeof(int)?__builtin_##name(with) : \ (sizeof(with)<=sizeof(long)?__builtin_##name##l(with) : \ __builtin_##name##ll(with))) AARRAY_define(int AARRAY_clz(size_t value), { return AARRAY_builtin_ll(clz,value); }) #elif defined(_MSC_VER) # 272 "./aArray.h" #if 0 #include <intrin.h> #endif # 272 "./aArray.h" # 273 "./aArray.h" #if defined(_WIN64) #pragma intrinsic(_BitScanReverse,_BitScanReverse64) AARRAY_define(int AARRAY_clz(size_t value), { unsigned long result; return (int)(sizeof(size_t) <= 4? (_BitScanReverse(&result, (unsigned long)value)? 31-result : 32) : _BitScanReverse64(&result, value)? 63-result : 64); }) #else # 281 "./aArray.h" #pragma intrinsic(_BitScanReverse) AARRAY_define(int AARRAY_clz(size_t value), { unsigned long result; return (int)(_BitScanReverse(&result, value)? 31-result : 32); }) #endif # 286 "./aArray.h" #else # 287 "./aArray.h" // originally from: www.hackersdelight.org/hdcodetxt/nlz.c.txt AARRAY_define(int AARRAY_clz(size_t x), { int n = 0; if(sizeof(size_t)==8 && x <= 0x00000000FFFFFFFF) { n += 32; x <<= 32; } if(x <= 0x0000FFFFFFFFFFFF) { n += 16; x <<= 16; } if(x <= 0x00FFFFFFFFFFFFFF) { n += 8; x <<= 8; } if(x <= 0x0FFFFFFFFFFFFFFF) { n += 4; x <<= 4; } if(x <= 0x3FFFFFFFFFFFFFFF) { n += 2; x <<= 2; } if(x <= 0x7FFFFFFFFFFFFFFF) { n += 1; x <<= 1; } return n; }) #endif # 299 "./aArray.h" //// array allocators, for 3 types of array // fix pointers to realloced memory, to point back into memory #define AARRAY_FIX_POINTERS(TYPE) \ if(!*vec) *length = 0; \ else if(vecsIncr) { \ \ size_t m = vecsIncr==5? 2: vecsIncr-1; \ while(m < vecsCount) { \ if(vecs[m] >= (uintptr_t)(*vec) && \ vecs[m] < (uintptr_t)(*vec)+(*length)*sizeof(TYPE)) \ AARRAY_nowarn_align(vecs[m] += \ (uintptr_t)length-(uintptr_t)((size_t*)*vec-1);) \ m += vecsIncr; } } // calculate capacity from length #define AARRAY_ALLOC_NOCAPACITY(TYPE) \ size_t curSize = (*length) * sizeof(TYPE) + sizeof(size_t); \ size_t newSize = ((*length) + (ilen-rlen)) * sizeof(TYPE) + sizeof(size_t); \ if((!*vec || AARRAY_clz(newSize-1) < AARRAY_clz(curSize-1))) { \ length = (size_t*)realloc(!*vec? NULL : length, \ AARRAY_upper_power_of_two(newSize)); \ AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(newSize)); \ AARRAY_FIX_POINTERS(TYPE) } \ *vec = (TYPE*)(length+1); // allocate minimum, and any future length change throws an error #define AARRAY_ALLOC_STATIC(TYPE) \ size_t curSize = (*length) * sizeof(TYPE) + sizeof(size_t); \ size_t newSize = ((*length) + (ilen-rlen)) * sizeof(TYPE) + sizeof(size_t); \ if(*vec) { AARRAY_safety((void)curSize;, \ if(newSize!=curSize) AARRAY_nowarn_align( \ AARRAY_Error_ArrayIsStatic(*((size_t*)*vec-1)))) } \ else { length = (size_t*)realloc(NULL, newSize); \ AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(newSize)); \ AARRAY_FIX_POINTERS(TYPE) } \ *vec = (TYPE*)(length+1); // store capacity // alternative growth strategies // size += (size >> 3) + (size < 9 ? 3 : 6); // size += size >> 1; // *1.5 // size = AARRAY_upper_power_of_two(size) #define AARRAY_ALLOC_STD(TYPE) \ AARRAY_nowarn_align(size_t curSize = *vec? *((size_t*)*vec-2) : 0;) \ size_t newSize = ((*length) + (ilen-rlen)) * sizeof(TYPE) + sizeof(size_t) * 2; \ if((!*vec || newSize > curSize)) { \ newSize += newSize >> 1; \ length = (size_t*)realloc(!*vec? NULL : length-1, newSize); \ AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(newSize)); \ *length = newSize; \ length += 1; \ AARRAY_FIX_POINTERS(TYPE) } \ *vec = (TYPE*)(length+1); //// handle array allocation #define AARRAY_Expand(TYPE, GROWTH) \ \ size_t lengthHolder = 0, *length = &lengthHolder; \ if(*vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) \ AARRAY_safety((void)errLoc;, \ if(pos > *length) AARRAY_Error_OutOfBounds(*length, pos) \ if(rlen > (*length) - pos) \ AARRAY_Error_RemovalIsOutOfBounds(*length, pos, rlen)) \ if(rlen > ilen && (*length)-(pos+rlen)) \ \ memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), \ sizeof(TYPE) * ((*length) - (pos+rlen))); \ \ AARRAY_ALLOC_##GROWTH(TYPE) \ if(rlen < ilen && (*length)-(pos+rlen)) { \ \ memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), \ sizeof(TYPE) * ((*length) - (pos+rlen))); } //// generate type specific and growth-strategy specific functions //// GENERATE_GENERICS creates functions for each data type, // FTYPE also make it specific to a block|lambda|function-pointer // These functions are then put into an array, // letting us select the right one at compile time AARRAY_define(int8_t*AARRAY_Replace_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t ilen, int8_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int8_t, NOCAPACITY); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int8_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_Replace_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t ilen, int16_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int16_t, NOCAPACITY); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int16_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_Replace_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t ilen, int32_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int32_t, NOCAPACITY); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int32_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_Replace_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t ilen, int64_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int64_t, NOCAPACITY); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int64_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) static void(*const AARRAY_Replace_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Replace_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_Replace_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_Replace_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Replace_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_Replace_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t ilen, int8_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int8_t, STATIC); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int8_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_Replace_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t ilen, int16_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int16_t, STATIC); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int16_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_Replace_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t ilen, int32_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int32_t, STATIC); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int32_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_Replace_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t ilen, int64_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int64_t, STATIC); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int64_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) static void(*const AARRAY_Replace_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Replace_STATIC_int8_t, (void(*)(void))&AARRAY_Replace_STATIC_int16_t, 0, (void(*)(void))&AARRAY_Replace_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Replace_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_Replace_STD_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t ilen, int8_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int8_t, STD); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int8_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_Replace_STD_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t ilen, int16_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int16_t, STD); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int16_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_Replace_STD_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t ilen, int32_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int32_t, STD); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int32_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_Replace_STD_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t ilen, int64_t items[]), { //// replaces section of a array with N items if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } // vecs is {array1 ... arrayN}, but doesn't contain pointers; // so vsIncr skipped with setting it to 0 size_t vecsCount = 1; size_t vecsIncr = 0; AARRAY_nowarn_align(uintptr_t*vecs = (uintptr_t*)items;) int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int64_t, STD); if(*vec) { if(ilen) memcpy(&((*vec)[pos]), vecs, sizeof(int64_t) * ilen); AARRAY_nowarn_align(*((size_t*)(*vec)-1) += ilen-rlen;) } return *vec; }) static void(*const AARRAY_Replace_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Replace_STD_int8_t, (void(*)(void))&AARRAY_Replace_STD_int16_t, 0, (void(*)(void))&AARRAY_Replace_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Replace_STD_int64_t }; AARRAY_define(int8_t*AARRAY_Append_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t ilen, int8_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_NOCAPACITY_int8_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int16_t*AARRAY_Append_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t ilen, int16_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_NOCAPACITY_int16_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int32_t*AARRAY_Append_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t ilen, int32_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_NOCAPACITY_int32_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int64_t*AARRAY_Append_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t ilen, int64_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_NOCAPACITY_int64_t( errLoc, vec, pos, 0, ilen, items); }) static void(*const AARRAY_Append_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Append_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_Append_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_Append_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Append_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_Append_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t ilen, int8_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STATIC_int8_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int16_t*AARRAY_Append_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t ilen, int16_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STATIC_int16_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int32_t*AARRAY_Append_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t ilen, int32_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STATIC_int32_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int64_t*AARRAY_Append_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t ilen, int64_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STATIC_int64_t( errLoc, vec, pos, 0, ilen, items); }) static void(*const AARRAY_Append_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Append_STATIC_int8_t, (void(*)(void))&AARRAY_Append_STATIC_int16_t, 0, (void(*)(void))&AARRAY_Append_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Append_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_Append_STD_int8_t(char errLoc[], int8_t*vec[], size_t ilen, int8_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STD_int8_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int16_t*AARRAY_Append_STD_int16_t(char errLoc[], int16_t*vec[], size_t ilen, int16_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STD_int16_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int32_t*AARRAY_Append_STD_int32_t(char errLoc[], int32_t*vec[], size_t ilen, int32_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STD_int32_t( errLoc, vec, pos, 0, ilen, items); }) AARRAY_define(int64_t*AARRAY_Append_STD_int64_t(char errLoc[], int64_t*vec[], size_t ilen, int64_t items[]), { AARRAY_nowarn_align(size_t pos = vec && *vec? // get array length *((size_t*)*vec-1) : 0;) return AARRAY_Replace_STD_int64_t( errLoc, vec, pos, 0, ilen, items); }) static void(*const AARRAY_Append_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Append_STD_int8_t, (void(*)(void))&AARRAY_Append_STD_int16_t, 0, (void(*)(void))&AARRAY_Append_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Append_STD_int64_t }; AARRAY_define(int8_t*AARRAY_Concat_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t vecsCount, int8_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int8_t, NOCAPACITY); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_Concat_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t vecsCount, int16_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int16_t, NOCAPACITY); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_Concat_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t vecsCount, int32_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int32_t, NOCAPACITY); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_Concat_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t vecsCount, int64_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int64_t, NOCAPACITY); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) static void(*const AARRAY_Concat_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Concat_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_Concat_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_Concat_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Concat_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_Concat_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t vecsCount, int8_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int8_t, STATIC); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_Concat_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t vecsCount, int16_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int16_t, STATIC); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_Concat_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t vecsCount, int32_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int32_t, STATIC); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_Concat_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t vecsCount, int64_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int64_t, STATIC); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) static void(*const AARRAY_Concat_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Concat_STATIC_int8_t, (void(*)(void))&AARRAY_Concat_STATIC_int16_t, 0, (void(*)(void))&AARRAY_Concat_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Concat_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_Concat_STD_int8_t(char errLoc[], int8_t*vec[], size_t vecsCount, int8_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int8_t, STD); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_Concat_STD_int16_t(char errLoc[], int16_t*vec[], size_t vecsCount, int16_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int16_t, STD); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_Concat_STD_int32_t(char errLoc[], int32_t*vec[], size_t vecsCount, int32_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int32_t, STD); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_Concat_STD_int64_t(char errLoc[], int64_t*vec[], size_t vecsCount, int64_t*vecs_[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } uintptr_t*vecs = (uintptr_t*)vecs_; size_t rlen = 0; size_t ilen = 0; size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n]) ilen += *((size_t*)vecs[n]-1); // vecs is {vec0, ... ,vecN}, so vsIncr is 1 size_t vecsIncr = 1; int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_nowarn_align(size_t pos = *vec? *((size_t*)*vec-1) : 0;) AARRAY_Expand(int64_t, STD); if(*vec) { AARRAY_nowarn_align(size_t vLen = *((size_t*)*vec-1);) n = (size_t)-1; while(++n < vecsCount) { if(!vecs[n]) continue; size_t ns = (size_t)-1, vsnLen; vsnLen = *((size_t*)vecs[n]-1); while(++ns < vsnLen) (*vec)[vLen+ns] = vecs_[n][ns]; vLen += vsnLen; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen;) } return *vec; }) static void(*const AARRAY_Concat_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Concat_STD_int8_t, (void(*)(void))&AARRAY_Concat_STD_int16_t, 0, (void(*)(void))&AARRAY_Concat_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Concat_STD_int64_t }; AARRAY_define(int8_t*AARRAY_GenericArray_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int8_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int8_t, NOCAPACITY); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int8_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_GenericArray_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int16_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int16_t, NOCAPACITY); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int16_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_GenericArray_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int32_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int32_t, NOCAPACITY); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int32_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_GenericArray_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int64_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int64_t, NOCAPACITY); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int64_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) static void(*const AARRAY_GenericArray_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_GenericArray_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_GenericArray_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_GenericArray_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_GenericArray_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_GenericArray_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int8_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int8_t, STATIC); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int8_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_GenericArray_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int16_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int16_t, STATIC); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int16_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_GenericArray_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int32_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int32_t, STATIC); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int32_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_GenericArray_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int64_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int64_t, STATIC); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int64_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) static void(*const AARRAY_GenericArray_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_GenericArray_STATIC_int8_t, (void(*)(void))&AARRAY_GenericArray_STATIC_int16_t, 0, (void(*)(void))&AARRAY_GenericArray_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_GenericArray_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_GenericArray_STD_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int8_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int8_t, STD); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int8_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int16_t*AARRAY_GenericArray_STD_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int16_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int16_t, STD); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int16_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int32_t*AARRAY_GenericArray_STD_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int32_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int32_t, STD); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int32_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) AARRAY_define(int64_t*AARRAY_GenericArray_STD_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { size_t n = 0; size_t alen, ilen = 0; size_t vecsIncr = 2; while(n < vecsCount) { alen = vecs[n]; AARRAY_safety(, if(alen && vecs[n+1]==(uintptr_t)NULL) AARRAY_Error_ArrayIsNull((n+2)/2)); if(alen==SIZE_MAX) { while(((int64_t*)vecs[n+1])[++alen]) { } vecs[n] = alen; } ilen += alen; n+=vecsIncr; } // vecs is {len0, array0, ... lenN, arrayN}, so vsIncr is 2 int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_Expand(int64_t, STD); if(*vec) { n = 0; while(n < vecsCount) { alen = vecs[n]; if(alen) { memcpy(&((*vec)[pos]), (void*)vecs[n+1], sizeof(int64_t)*alen); pos += alen; } n+=vecsIncr; } AARRAY_nowarn_align(*((size_t*)*vec-1) += ilen-rlen;) } return *vec; }) static void(*const AARRAY_GenericArray_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_GenericArray_STD_int8_t, (void(*)(void))&AARRAY_GenericArray_STD_int16_t, 0, (void(*)(void))&AARRAY_GenericArray_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_GenericArray_STD_int64_t }; AARRAY_define(int8_t*AARRAY_ReplaceArray_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_NOCAPACITY_int8_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int16_t*AARRAY_ReplaceArray_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_NOCAPACITY_int16_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int32_t*AARRAY_ReplaceArray_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_NOCAPACITY_int32_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int64_t*AARRAY_ReplaceArray_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_NOCAPACITY_int64_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) static void(*const AARRAY_ReplaceArray_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ReplaceArray_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_ReplaceArray_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_ReplaceArray_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ReplaceArray_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_ReplaceArray_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STATIC_int8_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int16_t*AARRAY_ReplaceArray_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STATIC_int16_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int32_t*AARRAY_ReplaceArray_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STATIC_int32_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int64_t*AARRAY_ReplaceArray_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STATIC_int64_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) static void(*const AARRAY_ReplaceArray_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ReplaceArray_STATIC_int8_t, (void(*)(void))&AARRAY_ReplaceArray_STATIC_int16_t, 0, (void(*)(void))&AARRAY_ReplaceArray_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ReplaceArray_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_ReplaceArray_STD_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STD_int8_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int16_t*AARRAY_ReplaceArray_STD_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STD_int16_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int32_t*AARRAY_ReplaceArray_STD_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STD_int32_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) AARRAY_define(int64_t*AARRAY_ReplaceArray_STD_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+3) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 2, 3)); return AARRAY_GenericArray_STD_int64_t( errLoc, vec, pos, rlen, vecsCount, vecs); }) static void(*const AARRAY_ReplaceArray_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ReplaceArray_STD_int8_t, (void(*)(void))&AARRAY_ReplaceArray_STD_int16_t, 0, (void(*)(void))&AARRAY_ReplaceArray_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ReplaceArray_STD_int64_t }; AARRAY_define(int8_t*AARRAY_AppendArray_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_NOCAPACITY_int8_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int16_t*AARRAY_AppendArray_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_NOCAPACITY_int16_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int32_t*AARRAY_AppendArray_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_NOCAPACITY_int32_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int64_t*AARRAY_AppendArray_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_NOCAPACITY_int64_t( errLoc, vec, pos, 0, vecsCount, vecs); }) static void(*const AARRAY_AppendArray_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_AppendArray_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_AppendArray_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_AppendArray_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_AppendArray_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_AppendArray_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STATIC_int8_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int16_t*AARRAY_AppendArray_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STATIC_int16_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int32_t*AARRAY_AppendArray_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STATIC_int32_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int64_t*AARRAY_AppendArray_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STATIC_int64_t( errLoc, vec, pos, 0, vecsCount, vecs); }) static void(*const AARRAY_AppendArray_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_AppendArray_STATIC_int8_t, (void(*)(void))&AARRAY_AppendArray_STATIC_int16_t, 0, (void(*)(void))&AARRAY_AppendArray_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_AppendArray_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_AppendArray_STD_int8_t(char errLoc[], int8_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STD_int8_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int16_t*AARRAY_AppendArray_STD_int16_t(char errLoc[], int16_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STD_int16_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int32_t*AARRAY_AppendArray_STD_int32_t(char errLoc[], int32_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STD_int32_t( errLoc, vec, pos, 0, vecsCount, vecs); }) AARRAY_define(int64_t*AARRAY_AppendArray_STD_int64_t(char errLoc[], int64_t*vec[], size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } AARRAY_safety(, if((vecsCount+1) % 2 != 1) AARRAY_Error_WrongArgCount(vecsCount+1, 2, 1)); AARRAY_nowarn_align(size_t pos = vec && *vec? *((size_t*)*vec-1) : 0;) return AARRAY_GenericArray_STD_int64_t( errLoc, vec, pos, 0, vecsCount, vecs); }) static void(*const AARRAY_AppendArray_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_AppendArray_STD_int8_t, (void(*)(void))&AARRAY_AppendArray_STD_int16_t, 0, (void(*)(void))&AARRAY_AppendArray_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_AppendArray_STD_int64_t }; AARRAY_define(int8_t*AARRAY_Multi_NOCAPACITY_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int8_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_NOCAPACITY(int8_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int8_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int8_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int16_t*AARRAY_Multi_NOCAPACITY_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int16_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_NOCAPACITY(int16_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int16_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int16_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int32_t*AARRAY_Multi_NOCAPACITY_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int32_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_NOCAPACITY(int32_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int32_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int32_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int64_t*AARRAY_Multi_NOCAPACITY_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int64_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_NOCAPACITY(int64_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int64_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int64_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) static void(*const AARRAY_Multi_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Multi_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_Multi_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_Multi_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Multi_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_Multi_STATIC_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int8_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STATIC(int8_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int8_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int8_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int16_t*AARRAY_Multi_STATIC_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int16_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STATIC(int16_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int16_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int16_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int32_t*AARRAY_Multi_STATIC_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int32_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STATIC(int32_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int32_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int32_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int64_t*AARRAY_Multi_STATIC_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int64_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STATIC(int64_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int64_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int64_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) static void(*const AARRAY_Multi_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Multi_STATIC_int8_t, (void(*)(void))&AARRAY_Multi_STATIC_int16_t, 0, (void(*)(void))&AARRAY_Multi_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Multi_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_Multi_STD_int8_t(char errLoc[], int8_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int8_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STD(int8_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int8_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int8_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int16_t*AARRAY_Multi_STD_int16_t(char errLoc[], int16_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int16_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STD(int16_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int16_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int16_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int32_t*AARRAY_Multi_STD_int32_t(char errLoc[], int32_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int32_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STD(int32_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int32_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int32_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) AARRAY_define(int64_t*AARRAY_Multi_STD_int64_t(char errLoc[], int64_t*vec[], size_t pos, size_t rlen, size_t vecsCount, uintptr_t vecs[]), { if(vec) { AARRAY_prefetch((size_t*)*vec-1, 1, 1); } size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) size_t n = 0, alen, ilen = 0, atimes, newlen = *length, maxlen = newlen; size_t saved_pos = pos, saved_rlen = rlen; size_t vecsIncr = 5; AARRAY_safety(, if((vecsCount+3) % 5 != 1) AARRAY_Error_WrongArgCount(vecsCount+3, 5, 1)); while(n < vecsCount) { atimes = vecs[n]; alen = vecs[n+1]; AARRAY_safety(, if(atimes && alen && !vecs[n+2]) AARRAY_Error_ArrayIsNull(n/5+1)); if(alen==SIZE_MAX) { while(((int64_t*)vecs[n+2])[++alen]) { } vecs[n+1] = alen; } // check input, and work out max length required for array if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } if(pos > newlen) AARRAY_Error_OutOfBounds(*length, pos) if(rlen > newlen - pos) AARRAY_Error_RemovalIsOutOfBounds(newlen, pos, rlen) ilen = atimes? atimes * alen : alen; newlen += ilen - rlen; if(newlen > maxlen) maxlen = newlen; n+=vecsIncr; } ilen = maxlen - *length; rlen = 0; // vecs is {times0, len0, array0, ... timesN, lenN, arrayN}, so vsIncr is 3 int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; AARRAY_ALLOC_STD(int64_t) if(*vec) { n = 0; pos = saved_pos; rlen = saved_rlen; do { atimes = vecs[n]; alen = vecs[n+1]; if(n) { pos = vecs[n-2]; rlen = vecs[n-1]; } ilen = atimes? atimes * alen : alen; if(ilen-rlen) { memmove(&((*vec)[pos+ilen]), &((*vec)[pos+rlen]), sizeof(int64_t) * ((*length) - (pos+rlen))); *length += ilen-rlen; } if(!atimes) {} else while(atimes--) { memcpy(&((*vec)[pos]), (void*)vecs[n+2], sizeof(int64_t) * alen); pos += alen; } n+=vecsIncr; } while(n < vecsCount); } return *vec; }) static void(*const AARRAY_Multi_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Multi_STD_int8_t, (void(*)(void))&AARRAY_Multi_STD_int16_t, 0, (void(*)(void))&AARRAY_Multi_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Multi_STD_int64_t }; AARRAY_define(int8_t*AARRAY_Alloc_NOCAPACITY_int8_t( char errLoc[], int8_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int8_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int8_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_NOCAPACITY(int8_t); *length = len; return *vec = (int8_t*)(length+1); } }) AARRAY_define(int16_t*AARRAY_Alloc_NOCAPACITY_int16_t( char errLoc[], int16_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int16_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int16_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_NOCAPACITY(int16_t); *length = len; return *vec = (int16_t*)(length+1); } }) AARRAY_define(int32_t*AARRAY_Alloc_NOCAPACITY_int32_t( char errLoc[], int32_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int32_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int32_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_NOCAPACITY(int32_t); *length = len; return *vec = (int32_t*)(length+1); } }) AARRAY_define(int64_t*AARRAY_Alloc_NOCAPACITY_int64_t( char errLoc[], int64_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int64_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int64_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_NOCAPACITY(int64_t); *length = len; return *vec = (int64_t*)(length+1); } }) static void(*const AARRAY_Alloc_NOCAPACITY_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Alloc_NOCAPACITY_int8_t, (void(*)(void))&AARRAY_Alloc_NOCAPACITY_int16_t, 0, (void(*)(void))&AARRAY_Alloc_NOCAPACITY_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Alloc_NOCAPACITY_int64_t }; AARRAY_define(int8_t*AARRAY_Alloc_STATIC_int8_t( char errLoc[], int8_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 1) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int8_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int8_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STATIC(int8_t); *length = len; return *vec = (int8_t*)(length+1); } }) AARRAY_define(int16_t*AARRAY_Alloc_STATIC_int16_t( char errLoc[], int16_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 1) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int16_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int16_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STATIC(int16_t); *length = len; return *vec = (int16_t*)(length+1); } }) AARRAY_define(int32_t*AARRAY_Alloc_STATIC_int32_t( char errLoc[], int32_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 1) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int32_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int32_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STATIC(int32_t); *length = len; return *vec = (int32_t*)(length+1); } }) AARRAY_define(int64_t*AARRAY_Alloc_STATIC_int64_t( char errLoc[], int64_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 1) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 0) { size_t newsize = len * sizeof(int64_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int64_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STATIC(int64_t); *length = len; return *vec = (int64_t*)(length+1); } }) static void(*const AARRAY_Alloc_STATIC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Alloc_STATIC_int8_t, (void(*)(void))&AARRAY_Alloc_STATIC_int16_t, 0, (void(*)(void))&AARRAY_Alloc_STATIC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Alloc_STATIC_int64_t }; AARRAY_define(int8_t*AARRAY_Alloc_STD_int8_t( char errLoc[], int8_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int8_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 1) { size_t newsize = len * sizeof(int8_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int8_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STD(int8_t); *length = len; return *vec = (int8_t*)(length+1); } }) AARRAY_define(int16_t*AARRAY_Alloc_STD_int16_t( char errLoc[], int16_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int16_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 1) { size_t newsize = len * sizeof(int16_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int16_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STD(int16_t); *length = len; return *vec = (int16_t*)(length+1); } }) AARRAY_define(int32_t*AARRAY_Alloc_STD_int32_t( char errLoc[], int32_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int32_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 1) { size_t newsize = len * sizeof(int32_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int32_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STD(int32_t); *length = len; return *vec = (int32_t*)(length+1); } }) AARRAY_define(int64_t*AARRAY_Alloc_STD_int64_t( char errLoc[], int64_t*vec[], size_t len), { size_t lengthHolder = 0, *length = &lengthHolder; if(vec && *vec) AARRAY_nowarn_align(length = (size_t*)*vec-1;) int64_t*vecHolder = NULL; if(!vec) vec = &vecHolder; if( 0) { if(*length != len) { AARRAY_Error_ArrayIsStatic(*((size_t*)*(size_t**)vec-1)); } return *vec; } else if( 1) { size_t newsize = len * sizeof(int64_t) + sizeof(size_t) * 2; length = (size_t*)realloc(!*vec? NULL : length-1, newsize); AARRAY_safety(, if(!length) AARRAY_Error_OutOfMemory(len)); *length = newsize; *(length+1) = len; return *vec = (int64_t*)(length+2); } else { *length = 0; // so NOCAPACITY assumes need for realloc size_t ilen = len, rlen = *length; size_t vecsCount = 0, vecsIncr = 0, *vecs = NULL; AARRAY_ALLOC_STD(int64_t); *length = len; return *vec = (int64_t*)(length+1); } }) static void(*const AARRAY_Alloc_STD_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Alloc_STD_int8_t, (void(*)(void))&AARRAY_Alloc_STD_int16_t, 0, (void(*)(void))&AARRAY_Alloc_STD_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Alloc_STD_int64_t }; //// get the number of var-arg arguments, and make them generic // as above, but for 64 bit only, such as aFmt // make c++ happy // as above, but hide compiler warnings for mixed int/pointer arrays // uintptr_t conversion of first arg resolves gcc issue // get around requirement for __VA_ARGS__ to not be empty #define AARRAY_ArgsTail(A, ...) __VA_ARGS__ #if defined(AARRAY_NOTYPEOF) \ || (defined(_MSC_VER) && !__has_feature(cxx_decltype)) // create api functions without type-casts #define AARRAY_typeof(TYPE, EXPR) EXPR #elif __has_feature(cxx_decltype) # 2341 "./aArray.h" // +0 resolves c++ compliance #define AARRAY_typeof(TYPE, EXPR) (__decltype(TYPE+0))(EXPR) #else # 2344 "./aArray.h" #define AARRAY_typeof(TYPE, EXPR) \ AARRAY_nowarn_internal_start (__typeof(TYPE))(EXPR) AARRAY_nowarn_internal_end #endif # 2347 "./aArray.h" //// generate the main apis for c, c++, and compilers without __typeof support #define aAppend_NOCAPACITY(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, void*)) \ AARRAY_Append_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, AARRAY_nowarn_internal_start \ (sizeof(**vec)==1? sizeof((uint8_t[] ){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? sizeof((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? sizeof((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=8? sizeof((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__}) : \ AARRAY_Error_ArrayIsWide) / sizeof(**vec), \ (sizeof(**vec)==1? (void*)AARRAY_move((uint8_t []){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? (void*)AARRAY_move((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? (void*)AARRAY_move((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ (void*)AARRAY_move((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__})) \ AARRAY_nowarn_internal_end)) #define aReplace_NOCAPACITY(vec, pos, rlen, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, void*)) \ AARRAY_Replace_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, \ AARRAY_nowarn_internal_start \ (sizeof(**vec)==1? sizeof((uint8_t[] ){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? sizeof((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? sizeof((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=8? sizeof((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__}) : \ AARRAY_Error_ArrayIsWide) / sizeof(**vec), \ (sizeof(**vec)==1? (void*)AARRAY_move((uint8_t []){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? (void*)AARRAY_move((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? (void*)AARRAY_move((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ (void*)AARRAY_move((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__})) \ AARRAY_nowarn_internal_end)) #define aDelete_NOCAPACITY(vec, pos, rlen) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, void*)) \ AARRAY_Replace_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, 0, NULL)) #define aConcat_NOCAPACITY(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, uintptr_t*)) \ AARRAY_Concat_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, \ sizeof((void*[]){(void*)__VA_ARGS__}) / sizeof(void*), \ (uintptr_t*)AARRAY_move((void*[]){(void*)__VA_ARGS__}))) #define aAppendArray_NOCAPACITY(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, uintptr_t*)) \ AARRAY_AppendArray_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aReplaceArray_NOCAPACITY(vec, pos, rlen, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, uintptr_t*)) \ AARRAY_ReplaceArray_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aMulti_NOCAPACITY(vec, pos, rlen, arrTimes, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, uintptr_t*)) \ AARRAY_Multi_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, \ AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)arrTimes, __VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)arrTimes, __VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aAlloc_NOCAPACITY(vec, len) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t)) \ AARRAY_Alloc_NOCAPACITY_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, len)) #define aAppend_STATIC(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, void*)) \ AARRAY_Append_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, AARRAY_nowarn_internal_start \ (sizeof(**vec)==1? sizeof((uint8_t[] ){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? sizeof((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? sizeof((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=8? sizeof((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__}) : \ AARRAY_Error_ArrayIsWide) / sizeof(**vec), \ (sizeof(**vec)==1? (void*)AARRAY_move((uint8_t []){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? (void*)AARRAY_move((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? (void*)AARRAY_move((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ (void*)AARRAY_move((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__})) \ AARRAY_nowarn_internal_end)) #define aReplace_STATIC(vec, pos, rlen, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, void*)) \ AARRAY_Replace_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, \ AARRAY_nowarn_internal_start \ (sizeof(**vec)==1? sizeof((uint8_t[] ){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? sizeof((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? sizeof((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=8? sizeof((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__}) : \ AARRAY_Error_ArrayIsWide) / sizeof(**vec), \ (sizeof(**vec)==1? (void*)AARRAY_move((uint8_t []){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? (void*)AARRAY_move((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? (void*)AARRAY_move((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ (void*)AARRAY_move((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__})) \ AARRAY_nowarn_internal_end)) #define aDelete_STATIC(vec, pos, rlen) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, void*)) \ AARRAY_Replace_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, 0, NULL)) #define aConcat_STATIC(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, uintptr_t*)) \ AARRAY_Concat_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, \ sizeof((void*[]){(void*)__VA_ARGS__}) / sizeof(void*), \ (uintptr_t*)AARRAY_move((void*[]){(void*)__VA_ARGS__}))) #define aAppendArray_STATIC(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, uintptr_t*)) \ AARRAY_AppendArray_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aReplaceArray_STATIC(vec, pos, rlen, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, uintptr_t*)) \ AARRAY_ReplaceArray_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aMulti_STATIC(vec, pos, rlen, arrTimes, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, uintptr_t*)) \ AARRAY_Multi_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, \ AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)arrTimes, __VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)arrTimes, __VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aAlloc_STATIC(vec, len) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t)) \ AARRAY_Alloc_STATIC_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, len)) #define aAppend(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, void*)) \ AARRAY_Append_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, AARRAY_nowarn_internal_start \ (sizeof(**vec)==1? sizeof((uint8_t[] ){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? sizeof((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? sizeof((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=8? sizeof((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__}) : \ AARRAY_Error_ArrayIsWide) / sizeof(**vec), \ (sizeof(**vec)==1? (void*)AARRAY_move((uint8_t []){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? (void*)AARRAY_move((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? (void*)AARRAY_move((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ (void*)AARRAY_move((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__})) \ AARRAY_nowarn_internal_end)) #define aReplace(vec, pos, rlen, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, void*)) \ AARRAY_Replace_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, \ AARRAY_nowarn_internal_start \ (sizeof(**vec)==1? sizeof((uint8_t[] ){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? sizeof((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? sizeof((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=8? sizeof((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__}) : \ AARRAY_Error_ArrayIsWide) / sizeof(**vec), \ (sizeof(**vec)==1? (void*)AARRAY_move((uint8_t []){(uint8_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)==2? (void*)AARRAY_move((uint16_t[]){(uint16_t)(uintptr_t)__VA_ARGS__}) : \ sizeof(**vec)<=4? (void*)AARRAY_move((uint32_t[]){(uint32_t)(uintptr_t)__VA_ARGS__}) : \ (void*)AARRAY_move((uint64_t[]){(uint64_t)(uintptr_t)__VA_ARGS__})) \ AARRAY_nowarn_internal_end)) #define aDelete(vec, pos, rlen) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, void*)) \ AARRAY_Replace_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, 0, NULL)) #define aConcat(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, uintptr_t*)) \ AARRAY_Concat_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, \ sizeof((void*[]){(void*)__VA_ARGS__}) / sizeof(void*), \ (uintptr_t*)AARRAY_move((void*[]){(void*)__VA_ARGS__}))) #define aAppendArray(vec, ...) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t, uintptr_t*)) \ AARRAY_AppendArray_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aReplaceArray(vec, pos, rlen, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, uintptr_t*)) \ AARRAY_ReplaceArray_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aMulti(vec, pos, rlen, arrTimes, ...) \ (AARRAY_typeof(*vec, (void*(*)( \ char[], void**, size_t, size_t, size_t, uintptr_t*)) \ AARRAY_Multi_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, pos, rlen, \ AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)arrTimes, __VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)arrTimes, __VA_ARGS__}) \ AARRAY_nowarn_internal_end)) #define aAlloc(vec, len) \ (AARRAY_typeof(*vec, (void*(*)(char[], void**, size_t)) \ AARRAY_Alloc_STD_FUNCTIONS[sizeof(**vec)-1]) \ (AARRAY_LINE, (void**)vec, len)) // make pointer casts safer: ensuring data can become (voidstars)data AARRAY_define(void AARRAY_Free(void*vec[]), { if(*vec) { free((size_t*)*vec-2); *vec = NULL; } }) #define aFree(vec) \ AARRAY_Free(0?(void**)(uintptr_t)sizeof( \ **vec \ ):(void**)vec) AARRAY_define(void AARRAY_Free_NOCAPACITY(void*vec[]), { if(*vec) { free((size_t*)*vec-1); *vec = NULL; } }) AARRAY_define(void AARRAY_Free_STATIC(void*vec[]), { AARRAY_Free_NOCAPACITY(vec); }) // to make stack traces clearer #define aFree_NOCAPACITY(vec) \ AARRAY_Free_NOCAPACITY(0?(void**)(uintptr_t)sizeof( \ **vec \ ):(void**)vec) #define aFree_STATIC(vec) \ AARRAY_Free_STATIC(0?(void**)(uintptr_t)sizeof( \ **vec \ ):(void**)vec) //// supporting api AARRAY_define(size_t AARRAY_aLength(void*vec), { return !vec? 0 : *((size_t*)vec-1); }) #define aLength(vec) AARRAY_aLength(0?(void*)(uintptr_t)sizeof( \ *vec \ ):(void*)vec) AARRAY_define(int8_t AARRAY_Length2__int8_t( char errLoc[], int8_t vec[], size_t pos), { if(!vec) AARRAY_safety(return 0; (void)errLoc;, { if(pos==0) return 0; else AARRAY_Error_OutOfBounds(aLength(vec), pos); }) AARRAY_nowarn_align(size_t*length = (size_t*)vec-1;) AARRAY_safety(, if(pos > *length) AARRAY_Error_OutOfBounds(aLength(vec), pos)); *length = pos; // if(pos==0) { pos-1 will index into *length (which is 0); // so vec[pos-1] is safe and returns 0 } return vec[pos-1]; }) AARRAY_define(int16_t AARRAY_Length2__int16_t( char errLoc[], int16_t vec[], size_t pos), { if(!vec) AARRAY_safety(return 0; (void)errLoc;, { if(pos==0) return 0; else AARRAY_Error_OutOfBounds(aLength(vec), pos); }) AARRAY_nowarn_align(size_t*length = (size_t*)vec-1;) AARRAY_safety(, if(pos > *length) AARRAY_Error_OutOfBounds(aLength(vec), pos)); *length = pos; // if(pos==0) { pos-1 will index into *length (which is 0); // so vec[pos-1] is safe and returns 0 } return vec[pos-1]; }) AARRAY_define(int32_t AARRAY_Length2__int32_t( char errLoc[], int32_t vec[], size_t pos), { if(!vec) AARRAY_safety(return 0; (void)errLoc;, { if(pos==0) return 0; else AARRAY_Error_OutOfBounds(aLength(vec), pos); }) AARRAY_nowarn_align(size_t*length = (size_t*)vec-1;) AARRAY_safety(, if(pos > *length) AARRAY_Error_OutOfBounds(aLength(vec), pos)); *length = pos; // if(pos==0) { pos-1 will index into *length (which is 0); // so vec[pos-1] is safe and returns 0 } return vec[pos-1]; }) AARRAY_define(int64_t AARRAY_Length2__int64_t( char errLoc[], int64_t vec[], size_t pos), { if(!vec) AARRAY_safety(return 0; (void)errLoc;, { if(pos==0) return 0; else AARRAY_Error_OutOfBounds(aLength(vec), pos); }) AARRAY_nowarn_align(size_t*length = (size_t*)vec-1;) AARRAY_safety(, if(pos > *length) AARRAY_Error_OutOfBounds(aLength(vec), pos)); *length = pos; // if(pos==0) { pos-1 will index into *length (which is 0); // so vec[pos-1] is safe and returns 0 } return vec[pos-1]; }) static void(*const AARRAY_Length2__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Length2__int8_t, (void(*)(void))&AARRAY_Length2__int16_t, 0, (void(*)(void))&AARRAY_Length2__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Length2__int64_t }; #define aLength2(vec, len) \ (AARRAY_typeof(*vec, (uint64_t(*)(char[], void*, size_t)) \ AARRAY_Length2__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, len)) AARRAY_define(int8_t AARRAY_ZLength2__int8_t( char errLoc[], int8_t vec[], size_t pos), { return AARRAY_Length2__int8_t(errLoc, vec, aLength(vec) - pos); }) AARRAY_define(int16_t AARRAY_ZLength2__int16_t( char errLoc[], int16_t vec[], size_t pos), { return AARRAY_Length2__int16_t(errLoc, vec, aLength(vec) - pos); }) AARRAY_define(int32_t AARRAY_ZLength2__int32_t( char errLoc[], int32_t vec[], size_t pos), { return AARRAY_Length2__int32_t(errLoc, vec, aLength(vec) - pos); }) AARRAY_define(int64_t AARRAY_ZLength2__int64_t( char errLoc[], int64_t vec[], size_t pos), { return AARRAY_Length2__int64_t(errLoc, vec, aLength(vec) - pos); }) static void(*const AARRAY_ZLength2__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ZLength2__int8_t, (void(*)(void))&AARRAY_ZLength2__int16_t, 0, (void(*)(void))&AARRAY_ZLength2__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ZLength2__int64_t }; #define aZLength2(vec, len) \ (AARRAY_typeof(*vec, (uint64_t(*)(char[], void*, size_t)) \ AARRAY_ZLength2__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, len)) AARRAY_define(int8_t*AARRAY_AtPtr__int8_t( char errLoc[], int8_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return &(vec[pos]); }) AARRAY_define(int16_t*AARRAY_AtPtr__int16_t( char errLoc[], int16_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return &(vec[pos]); }) AARRAY_define(int32_t*AARRAY_AtPtr__int32_t( char errLoc[], int32_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return &(vec[pos]); }) AARRAY_define(int64_t*AARRAY_AtPtr__int64_t( char errLoc[], int64_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return &(vec[pos]); }) static void(*const AARRAY_AtPtr__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_AtPtr__int8_t, (void(*)(void))&AARRAY_AtPtr__int16_t, 0, (void(*)(void))&AARRAY_AtPtr__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_AtPtr__int64_t }; #define aAtPtr(vec, pos) \ (AARRAY_typeof(vec, (uint64_t*(*)(char[], void*, size_t)) \ AARRAY_AtPtr__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, pos)) AARRAY_define(int8_t*AARRAY_ZAtPtr__int8_t( char errLoc[], int8_t vec[], size_t pos), { return AARRAY_AtPtr__int8_t(errLoc, vec, aLength(vec) - (pos+1)); }) AARRAY_define(int16_t*AARRAY_ZAtPtr__int16_t( char errLoc[], int16_t vec[], size_t pos), { return AARRAY_AtPtr__int16_t(errLoc, vec, aLength(vec) - (pos+1)); }) AARRAY_define(int32_t*AARRAY_ZAtPtr__int32_t( char errLoc[], int32_t vec[], size_t pos), { return AARRAY_AtPtr__int32_t(errLoc, vec, aLength(vec) - (pos+1)); }) AARRAY_define(int64_t*AARRAY_ZAtPtr__int64_t( char errLoc[], int64_t vec[], size_t pos), { return AARRAY_AtPtr__int64_t(errLoc, vec, aLength(vec) - (pos+1)); }) static void(*const AARRAY_ZAtPtr__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ZAtPtr__int8_t, (void(*)(void))&AARRAY_ZAtPtr__int16_t, 0, (void(*)(void))&AARRAY_ZAtPtr__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ZAtPtr__int64_t }; #define aZAtPtr(vec, pos) \ (AARRAY_typeof(vec, (uint64_t*(*)(char[], void*, size_t)) \ AARRAY_ZAtPtr__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, pos)) AARRAY_define(int8_t AARRAY_At__int8_t( char errLoc[], int8_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return vec[pos]; }) AARRAY_define(int16_t AARRAY_At__int16_t( char errLoc[], int16_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return vec[pos]; }) AARRAY_define(int32_t AARRAY_At__int32_t( char errLoc[], int32_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return vec[pos]; }) AARRAY_define(int64_t AARRAY_At__int64_t( char errLoc[], int64_t vec[], size_t pos), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); return vec[pos]; }) static void(*const AARRAY_At__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_At__int8_t, (void(*)(void))&AARRAY_At__int16_t, 0, (void(*)(void))&AARRAY_At__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_At__int64_t }; #define aAt(vec, pos) \ (AARRAY_typeof(*vec, (uint64_t(*)(char[], void*, size_t)) \ AARRAY_At__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, pos)) AARRAY_define(int8_t AARRAY_ZAt__int8_t( char errLoc[], int8_t vec[], size_t pos), { return AARRAY_At__int8_t(errLoc, vec, aLength(vec) - (pos+1)); }) AARRAY_define(int16_t AARRAY_ZAt__int16_t( char errLoc[], int16_t vec[], size_t pos), { return AARRAY_At__int16_t(errLoc, vec, aLength(vec) - (pos+1)); }) AARRAY_define(int32_t AARRAY_ZAt__int32_t( char errLoc[], int32_t vec[], size_t pos), { return AARRAY_At__int32_t(errLoc, vec, aLength(vec) - (pos+1)); }) AARRAY_define(int64_t AARRAY_ZAt__int64_t( char errLoc[], int64_t vec[], size_t pos), { return AARRAY_At__int64_t(errLoc, vec, aLength(vec) - (pos+1)); }) static void(*const AARRAY_ZAt__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ZAt__int8_t, (void(*)(void))&AARRAY_ZAt__int16_t, 0, (void(*)(void))&AARRAY_ZAt__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ZAt__int64_t }; #define aZAt(vec, pos) \ (AARRAY_typeof(*vec, (uint64_t(*)(char[], void*, size_t)) \ AARRAY_ZAt__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, pos)) AARRAY_define(int8_t AARRAY_At2__int8_t( char errLoc[], int8_t vec[], size_t pos, int8_t item), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); vec[pos] = item; return item; }) AARRAY_define(int16_t AARRAY_At2__int16_t( char errLoc[], int16_t vec[], size_t pos, int16_t item), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); vec[pos] = item; return item; }) AARRAY_define(int32_t AARRAY_At2__int32_t( char errLoc[], int32_t vec[], size_t pos, int32_t item), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); vec[pos] = item; return item; }) AARRAY_define(int64_t AARRAY_At2__int64_t( char errLoc[], int64_t vec[], size_t pos, int64_t item), { AARRAY_safety((void)errLoc;, if(pos >= aLength(vec)) AARRAY_Error_OutOfBounds(aLength(vec), pos)); vec[pos] = item; return item; }) static void(*const AARRAY_At2__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_At2__int8_t, (void(*)(void))&AARRAY_At2__int16_t, 0, (void(*)(void))&AARRAY_At2__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_At2__int64_t }; #define aAt2(vec, pos, item) \ (AARRAY_typeof(*vec, (uint64_t(*)(char[], void*, size_t, uint64_t)) \ AARRAY_At2__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, pos, \ AARRAY_nowarn_internal_start (uint64_t)item AARRAY_nowarn_internal_end)) AARRAY_define(int8_t AARRAY_ZAt2__int8_t( char errLoc[], int8_t vec[], size_t pos, int8_t item), { return AARRAY_At2__int8_t(errLoc, vec, aLength(vec) - (pos+1), item); }) AARRAY_define(int16_t AARRAY_ZAt2__int16_t( char errLoc[], int16_t vec[], size_t pos, int16_t item), { return AARRAY_At2__int16_t(errLoc, vec, aLength(vec) - (pos+1), item); }) AARRAY_define(int32_t AARRAY_ZAt2__int32_t( char errLoc[], int32_t vec[], size_t pos, int32_t item), { return AARRAY_At2__int32_t(errLoc, vec, aLength(vec) - (pos+1), item); }) AARRAY_define(int64_t AARRAY_ZAt2__int64_t( char errLoc[], int64_t vec[], size_t pos, int64_t item), { return AARRAY_At2__int64_t(errLoc, vec, aLength(vec) - (pos+1), item); }) static void(*const AARRAY_ZAt2__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ZAt2__int8_t, (void(*)(void))&AARRAY_ZAt2__int16_t, 0, (void(*)(void))&AARRAY_ZAt2__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ZAt2__int64_t }; #define aZAt2(vec, pos, item) \ (AARRAY_typeof(*vec, (uint64_t(*)(char[], void*, size_t, uint64_t)) \ AARRAY_ZAt2__FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, (void*)vec, pos, \ AARRAY_nowarn_internal_start item AARRAY_nowarn_internal_end)) AARRAY_define(int AARRAY_Cmp__int8_t( int8_t vec[], size_t n, int8_t*vecs[]), { while(n--) { if(vec == vecs[n]) continue; if(aLength(vec) != aLength(vecs[n])) return 0; if(aLength(vec)==0) continue; // surely memcmp would work, but this upsets MSan // memcmp(((size_t*)(uintptr_t)vec-1), ((size_t*)(uintptr_t)vecs[n]-1), // aLength(vec)*sizeof(int8_t)+sizeof(size_t)); size_t m = -1; while(++m < aLength(vec)) if(vec[m]!=vecs[n][m]) return 0; } return 1; }) AARRAY_define(int AARRAY_Cmp__int16_t( int16_t vec[], size_t n, int16_t*vecs[]), { while(n--) { if(vec == vecs[n]) continue; if(aLength(vec) != aLength(vecs[n])) return 0; if(aLength(vec)==0) continue; // surely memcmp would work, but this upsets MSan // memcmp(((size_t*)(uintptr_t)vec-1), ((size_t*)(uintptr_t)vecs[n]-1), // aLength(vec)*sizeof(int16_t)+sizeof(size_t)); size_t m = -1; while(++m < aLength(vec)) if(vec[m]!=vecs[n][m]) return 0; } return 1; }) AARRAY_define(int AARRAY_Cmp__int32_t( int32_t vec[], size_t n, int32_t*vecs[]), { while(n--) { if(vec == vecs[n]) continue; if(aLength(vec) != aLength(vecs[n])) return 0; if(aLength(vec)==0) continue; // surely memcmp would work, but this upsets MSan // memcmp(((size_t*)(uintptr_t)vec-1), ((size_t*)(uintptr_t)vecs[n]-1), // aLength(vec)*sizeof(int32_t)+sizeof(size_t)); size_t m = -1; while(++m < aLength(vec)) if(vec[m]!=vecs[n][m]) return 0; } return 1; }) AARRAY_define(int AARRAY_Cmp__int64_t( int64_t vec[], size_t n, int64_t*vecs[]), { while(n--) { if(vec == vecs[n]) continue; if(aLength(vec) != aLength(vecs[n])) return 0; if(aLength(vec)==0) continue; // surely memcmp would work, but this upsets MSan // memcmp(((size_t*)(uintptr_t)vec-1), ((size_t*)(uintptr_t)vecs[n]-1), // aLength(vec)*sizeof(int64_t)+sizeof(size_t)); size_t m = -1; while(++m < aLength(vec)) if(vec[m]!=vecs[n][m]) return 0; } return 1; }) static void(*const AARRAY_Cmp__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Cmp__int8_t, (void(*)(void))&AARRAY_Cmp__int16_t, 0, (void(*)(void))&AARRAY_Cmp__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Cmp__int64_t }; #define aCmp(vec, ...) \ (((int(*)(void*, size_t, void*)) \ AARRAY_Cmp__FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, \ sizeof((void*[]){(void*)__VA_ARGS__}) / sizeof(void*), \ (uintptr_t*)AARRAY_move((void*[]){(void*)__VA_ARGS__}))) AARRAY_define(size_t AARRAY_IndexOf__int8_t(int8_t vec[], int8_t item), { size_t length = aLength(vec), i = (size_t)-1; while(++i < length) if(vec[i]==item) return i; return (size_t)-1; }) AARRAY_define(size_t AARRAY_IndexOf__int16_t(int16_t vec[], int16_t item), { size_t length = aLength(vec), i = (size_t)-1; while(++i < length) if(vec[i]==item) return i; return (size_t)-1; }) AARRAY_define(size_t AARRAY_IndexOf__int32_t(int32_t vec[], int32_t item), { size_t length = aLength(vec), i = (size_t)-1; while(++i < length) if(vec[i]==item) return i; return (size_t)-1; }) AARRAY_define(size_t AARRAY_IndexOf__int64_t(int64_t vec[], int64_t item), { size_t length = aLength(vec), i = (size_t)-1; while(++i < length) if(vec[i]==item) return i; return (size_t)-1; }) static void(*const AARRAY_IndexOf__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_IndexOf__int8_t, (void(*)(void))&AARRAY_IndexOf__int16_t, 0, (void(*)(void))&AARRAY_IndexOf__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_IndexOf__int64_t }; #define aIndexOf(vec, item) \ ((size_t(*)(void*, uint64_t)) \ AARRAY_IndexOf__FUNCTIONS[sizeof(*vec)-1])(vec, \ AARRAY_nowarn_internal_start item AARRAY_nowarn_internal_end) AARRAY_define(size_t AARRAY_ZIndexOf__int8_t(int8_t vec[], int8_t item), { size_t i = aLength(vec); while(i--) if(vec[i]==item) return i; return (size_t)-1; }) AARRAY_define(size_t AARRAY_ZIndexOf__int16_t(int16_t vec[], int16_t item), { size_t i = aLength(vec); while(i--) if(vec[i]==item) return i; return (size_t)-1; }) AARRAY_define(size_t AARRAY_ZIndexOf__int32_t(int32_t vec[], int32_t item), { size_t i = aLength(vec); while(i--) if(vec[i]==item) return i; return (size_t)-1; }) AARRAY_define(size_t AARRAY_ZIndexOf__int64_t(int64_t vec[], int64_t item), { size_t i = aLength(vec); while(i--) if(vec[i]==item) return i; return (size_t)-1; }) static void(*const AARRAY_ZIndexOf__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_ZIndexOf__int8_t, (void(*)(void))&AARRAY_ZIndexOf__int16_t, 0, (void(*)(void))&AARRAY_ZIndexOf__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_ZIndexOf__int64_t }; #define aZIndexOf(vec, item) \ ((size_t(*)(void*, uint64_t)) \ AARRAY_ZIndexOf__FUNCTIONS[sizeof(*vec)-1])(vec, \ AARRAY_nowarn_internal_start item AARRAY_nowarn_internal_end) AARRAY_define(void AARRAY_Map_FUNC_int8_t( char errLoc[], int8_t vec[], void(*f)(int8_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) , data ); }) AARRAY_define(void AARRAY_Map_FUNC_int16_t( char errLoc[], int16_t vec[], void(*f)(int16_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) , data ); }) AARRAY_define(void AARRAY_Map_FUNC_int32_t( char errLoc[], int32_t vec[], void(*f)(int32_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) , data ); }) AARRAY_define(void AARRAY_Map_FUNC_int64_t( char errLoc[], int64_t vec[], void(*f)(int64_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) , data ); }) static void(*const AARRAY_Map_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Map_FUNC_int8_t, (void(*)(void))&AARRAY_Map_FUNC_int16_t, 0, (void(*)(void))&AARRAY_Map_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Map_FUNC_int64_t }; #define aMap_FUNC(vec, f, data) \ ((void(*)(char[], void*, void(*)(void), void*)) \ AARRAY_Map_FUNC_FUNCTIONS[sizeof(*vec)-1])(AARRAY_LINE, vec, (void(*)(void))f, data) AARRAY_define(int AARRAY_Loop_FUNC_int8_t( char errLoc[], int8_t vec[], size_t pos, int(*f)(size_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos , data ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_FUNC_int16_t( char errLoc[], int16_t vec[], size_t pos, int(*f)(size_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos , data ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_FUNC_int32_t( char errLoc[], int32_t vec[], size_t pos, int(*f)(size_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos , data ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_FUNC_int64_t( char errLoc[], int64_t vec[], size_t pos, int(*f)(size_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos , data ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) static void(*const AARRAY_Loop_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Loop_FUNC_int8_t, (void(*)(void))&AARRAY_Loop_FUNC_int16_t, 0, (void(*)(void))&AARRAY_Loop_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Loop_FUNC_int64_t }; #define aLoop_FUNC(vec, pos, f, data) \ ((int(*)(char[], void*, size_t, int(*)(size_t, void*), void*)) \ AARRAY_Loop_FUNC_FUNCTIONS[sizeof(*vec)-1])(AARRAY_LINE, vec, pos, f, data) AARRAY_define(int8_t* AARRAY_Filter_FUNC_int8_t( char errLoc[], int8_t vec[], int(*f)(int8_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) , data )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int16_t* AARRAY_Filter_FUNC_int16_t( char errLoc[], int16_t vec[], int(*f)(int16_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) , data )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int32_t* AARRAY_Filter_FUNC_int32_t( char errLoc[], int32_t vec[], int(*f)(int32_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) , data )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int64_t* AARRAY_Filter_FUNC_int64_t( char errLoc[], int64_t vec[], int(*f)(int64_t*, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) , data )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) static void(*const AARRAY_Filter_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Filter_FUNC_int8_t, (void(*)(void))&AARRAY_Filter_FUNC_int16_t, 0, (void(*)(void))&AARRAY_Filter_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Filter_FUNC_int64_t }; #define aFilter_FUNC(vec, f, data) \ (AARRAY_typeof(vec, (uint64_t*(*)(char[], void*, void(*)(void), void*)) \ AARRAY_Filter_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, vec,(void(*)(void))f, data)) #if __has_extension(blocks) AARRAY_define(void AARRAY_Map_BLOCK_int8_t( char errLoc[], int8_t vec[], void(^f)(int8_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) AARRAY_define(void AARRAY_Map_BLOCK_int16_t( char errLoc[], int16_t vec[], void(^f)(int16_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) AARRAY_define(void AARRAY_Map_BLOCK_int32_t( char errLoc[], int32_t vec[], void(^f)(int32_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) AARRAY_define(void AARRAY_Map_BLOCK_int64_t( char errLoc[], int64_t vec[], void(^f)(int64_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) static void(*const AARRAY_Map_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Map_BLOCK_int8_t, (void(*)(void))&AARRAY_Map_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_Map_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Map_BLOCK_int64_t }; #define aMap_BLOCK(vec, f) \ ((void(*)(char[], void*, void(^)(void*))) \ AARRAY_Map_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, vec, (void(^)(void*))f) AARRAY_define(int AARRAY_Loop_BLOCK_int8_t( char errLoc[], int8_t vec[], size_t pos, int (^f)(size_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_BLOCK_int16_t( char errLoc[], int16_t vec[], size_t pos, int (^f)(size_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_BLOCK_int32_t( char errLoc[], int32_t vec[], size_t pos, int (^f)(size_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_BLOCK_int64_t( char errLoc[], int64_t vec[], size_t pos, int (^f)(size_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) static void(*const AARRAY_Loop_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Loop_BLOCK_int8_t, (void(*)(void))&AARRAY_Loop_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_Loop_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Loop_BLOCK_int64_t }; #define aLoop_BLOCK(vec, pos, f) \ ((int(*)(char[], void*, size_t, int(^)(size_t))) \ AARRAY_Loop_BLOCK_FUNCTIONS[sizeof(*vec)-1])(AARRAY_LINE, vec, pos, f) AARRAY_define(int8_t* AARRAY_Filter_BLOCK_int8_t( char errLoc[], int8_t vec[], int(^f)(int8_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int16_t* AARRAY_Filter_BLOCK_int16_t( char errLoc[], int16_t vec[], int(^f)(int16_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int32_t* AARRAY_Filter_BLOCK_int32_t( char errLoc[], int32_t vec[], int(^f)(int32_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int64_t* AARRAY_Filter_BLOCK_int64_t( char errLoc[], int64_t vec[], int(^f)(int64_t*)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) static void(*const AARRAY_Filter_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Filter_BLOCK_int8_t, (void(*)(void))&AARRAY_Filter_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_Filter_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Filter_BLOCK_int64_t }; #define aFilter_BLOCK(vec, f) \ (AARRAY_typeof(vec, (uint64_t*(*)(char[], void*, int(^)(uint64_t*))) \ AARRAY_Filter_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ (AARRAY_LINE, vec,(int(^)(uint64_t*))f)) #endif # 3252 "./aArray.h" #if defined(__cplusplus) AARRAY_define(void AARRAY_Map_LAMBDA_int8_t( char errLoc[], int8_t vec[], std::function<void(int8_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) AARRAY_define(void AARRAY_Map_LAMBDA_int16_t( char errLoc[], int16_t vec[], std::function<void(int16_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) AARRAY_define(void AARRAY_Map_LAMBDA_int32_t( char errLoc[], int32_t vec[], std::function<void(int32_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) AARRAY_define(void AARRAY_Map_LAMBDA_int64_t( char errLoc[], int64_t vec[], std::function<void(int64_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; // only FUNC versions use extra data parameter while(++n < aLength(vec)) f(&(vec[n]) ); }) static void(*const AARRAY_Map_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Map_LAMBDA_int8_t, (void(*)(void))&AARRAY_Map_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_Map_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Map_LAMBDA_int64_t }; #define aMap_LAMBDA(vec, f) \ ((void(*)(char[], void*, std::function<void(void*)>)) \ AARRAY_Map_LAMBDA_FUNCTIONS[sizeof(*vec)-1])(AARRAY_LINE, vec, f) AARRAY_define(int AARRAY_Loop_LAMBDA_int8_t( char errLoc[], int8_t vec[], size_t pos, std::function<int(size_t)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_LAMBDA_int16_t( char errLoc[], int16_t vec[], size_t pos, std::function<int(size_t)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_LAMBDA_int32_t( char errLoc[], int32_t vec[], size_t pos, std::function<int(size_t)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) AARRAY_define(int AARRAY_Loop_LAMBDA_int64_t( char errLoc[], int64_t vec[], size_t pos, std::function<int(size_t)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); int offset = 0; while(pos < aLength(vec)) { if((offset > 0 && pos < (size_t)offset) || (offset < 0 && pos > (size_t)offset)) return offset; offset = f(pos ); if(!offset) return 0; // play safe with int promotion if(offset > 0) pos += (size_t) offset; else pos -= (size_t)-offset; } return offset; }) static void(*const AARRAY_Loop_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Loop_LAMBDA_int8_t, (void(*)(void))&AARRAY_Loop_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_Loop_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Loop_LAMBDA_int64_t }; #define aLoop_LAMBDA(vec, pos, f) \ ((int(*)(char[], void*, size_t, std::function<int(size_t)>)) \ AARRAY_Loop_LAMBDA_FUNCTIONS[sizeof(*vec)-1])(AARRAY_LINE, vec, pos, f) AARRAY_define(int8_t* AARRAY_Filter_LAMBDA_int8_t( char errLoc[], int8_t vec[], std::function<int(int8_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int16_t* AARRAY_Filter_LAMBDA_int16_t( char errLoc[], int16_t vec[], std::function<int(int16_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int32_t* AARRAY_Filter_LAMBDA_int32_t( char errLoc[], int32_t vec[], std::function<int(int32_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) AARRAY_define(int64_t* AARRAY_Filter_LAMBDA_int64_t( char errLoc[], int64_t vec[], std::function<int(int64_t*)> f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1, nn = (size_t)-1; while(++n < aLength(vec)) { if(f(&(vec[n]) )) vec[++nn] = vec[n]; } (void)aLength2(vec, nn+1); return vec; }) static void(*const AARRAY_Filter_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Filter_LAMBDA_int8_t, (void(*)(void))&AARRAY_Filter_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_Filter_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Filter_LAMBDA_int64_t }; #define aFilter_LAMBDA(vec, f) \ (AARRAY_typeof(vec, (uint64_t*(*)(char[], void*, std::function<int(void*)>))\ AARRAY_Filter_LAMBDA_FUNCTIONS[sizeof(*vec)-1])(AARRAY_LINE, vec, f)) #endif # 3404 "./aArray.h" // aFold is generic over array_type, function_type, AND base_type // Rather than make previous cppp macros more generic, we treat aFold as unique // Though it's possible to create macros that genericize any c function // Which would be useful... AARRAY_define(int8_t AARRAY_Fold_FUNC_int8_t_int8_t( char errLoc[], int8_t*vec, int8_t base, int8_t(*f)(int8_t,int8_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int16_t AARRAY_Fold_FUNC_int16_t_int8_t( char errLoc[], int8_t*vec, int16_t base, int16_t(*f)(int16_t,int8_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int32_t AARRAY_Fold_FUNC_int32_t_int8_t( char errLoc[], int8_t*vec, int32_t base, int32_t(*f)(int32_t,int8_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int64_t AARRAY_Fold_FUNC_int64_t_int8_t( char errLoc[], int8_t*vec, int64_t base, int64_t(*f)(int64_t,int8_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int8_t AARRAY_Fold_FUNC_int8_t_int16_t( char errLoc[], int16_t*vec, int8_t base, int8_t(*f)(int8_t,int16_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int16_t AARRAY_Fold_FUNC_int16_t_int16_t( char errLoc[], int16_t*vec, int16_t base, int16_t(*f)(int16_t,int16_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int32_t AARRAY_Fold_FUNC_int32_t_int16_t( char errLoc[], int16_t*vec, int32_t base, int32_t(*f)(int32_t,int16_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int64_t AARRAY_Fold_FUNC_int64_t_int16_t( char errLoc[], int16_t*vec, int64_t base, int64_t(*f)(int64_t,int16_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int8_t AARRAY_Fold_FUNC_int8_t_int32_t( char errLoc[], int32_t*vec, int8_t base, int8_t(*f)(int8_t,int32_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int16_t AARRAY_Fold_FUNC_int16_t_int32_t( char errLoc[], int32_t*vec, int16_t base, int16_t(*f)(int16_t,int32_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int32_t AARRAY_Fold_FUNC_int32_t_int32_t( char errLoc[], int32_t*vec, int32_t base, int32_t(*f)(int32_t,int32_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int64_t AARRAY_Fold_FUNC_int64_t_int32_t( char errLoc[], int32_t*vec, int64_t base, int64_t(*f)(int64_t,int32_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int8_t AARRAY_Fold_FUNC_int8_t_int64_t( char errLoc[], int64_t*vec, int8_t base, int8_t(*f)(int8_t,int64_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int16_t AARRAY_Fold_FUNC_int16_t_int64_t( char errLoc[], int64_t*vec, int16_t base, int16_t(*f)(int16_t,int64_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int32_t AARRAY_Fold_FUNC_int32_t_int64_t( char errLoc[], int64_t*vec, int32_t base, int32_t(*f)(int32_t,int64_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) AARRAY_define(int64_t AARRAY_Fold_FUNC_int64_t_int64_t( char errLoc[], int64_t*vec, int64_t base, int64_t(*f)(int64_t,int64_t, void*), void*data), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] , data ); return base; }) static void(*const AARRAY_Fold_FUNC_FUNCTIONS[8][8])(void) = { { (void(*)(void))&AARRAY_Fold_FUNC_int8_t_int8_t, (void(*)(void))&AARRAY_Fold_FUNC_int8_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_FUNC_int8_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_FUNC_int8_t_int64_t }, { (void(*)(void))&AARRAY_Fold_FUNC_int16_t_int8_t, (void(*)(void))&AARRAY_Fold_FUNC_int16_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_FUNC_int16_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_FUNC_int16_t_int64_t }, {0}, { (void(*)(void))&AARRAY_Fold_FUNC_int32_t_int8_t, (void(*)(void))&AARRAY_Fold_FUNC_int32_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_FUNC_int32_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_FUNC_int32_t_int64_t }, {0}, {0}, {0}, { (void(*)(void))&AARRAY_Fold_FUNC_int64_t_int8_t, (void(*)(void))&AARRAY_Fold_FUNC_int64_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_FUNC_int64_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_FUNC_int64_t_int64_t } }; #define aFold_FUNC(vec, base, f, data) \ (AARRAY_typeof(base, (uint64_t(*)(char[], void*, uint64_t, void(*)(void), void*)) \ AARRAY_Fold_FUNC_FUNCTIONS[sizeof(base)-1][sizeof(*vec)-1]) \ (AARRAY_LINE, vec, (uint64_t)base, (void(*)(void))f, data)) #if __has_extension(blocks) AARRAY_define(int8_t AARRAY_Fold_BLOCK_int8_t_int8_t( char errLoc[], int8_t*vec, int8_t base, int8_t(^f)(int8_t,int8_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_BLOCK_int16_t_int8_t( char errLoc[], int8_t*vec, int16_t base, int16_t(^f)(int16_t,int8_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_BLOCK_int32_t_int8_t( char errLoc[], int8_t*vec, int32_t base, int32_t(^f)(int32_t,int8_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_BLOCK_int64_t_int8_t( char errLoc[], int8_t*vec, int64_t base, int64_t(^f)(int64_t,int8_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int8_t AARRAY_Fold_BLOCK_int8_t_int16_t( char errLoc[], int16_t*vec, int8_t base, int8_t(^f)(int8_t,int16_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_BLOCK_int16_t_int16_t( char errLoc[], int16_t*vec, int16_t base, int16_t(^f)(int16_t,int16_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_BLOCK_int32_t_int16_t( char errLoc[], int16_t*vec, int32_t base, int32_t(^f)(int32_t,int16_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_BLOCK_int64_t_int16_t( char errLoc[], int16_t*vec, int64_t base, int64_t(^f)(int64_t,int16_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int8_t AARRAY_Fold_BLOCK_int8_t_int32_t( char errLoc[], int32_t*vec, int8_t base, int8_t(^f)(int8_t,int32_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_BLOCK_int16_t_int32_t( char errLoc[], int32_t*vec, int16_t base, int16_t(^f)(int16_t,int32_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_BLOCK_int32_t_int32_t( char errLoc[], int32_t*vec, int32_t base, int32_t(^f)(int32_t,int32_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_BLOCK_int64_t_int32_t( char errLoc[], int32_t*vec, int64_t base, int64_t(^f)(int64_t,int32_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int8_t AARRAY_Fold_BLOCK_int8_t_int64_t( char errLoc[], int64_t*vec, int8_t base, int8_t(^f)(int8_t,int64_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_BLOCK_int16_t_int64_t( char errLoc[], int64_t*vec, int16_t base, int16_t(^f)(int16_t,int64_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_BLOCK_int32_t_int64_t( char errLoc[], int64_t*vec, int32_t base, int32_t(^f)(int32_t,int64_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_BLOCK_int64_t_int64_t( char errLoc[], int64_t*vec, int64_t base, int64_t(^f)(int64_t,int64_t)), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) static void(*const AARRAY_Fold_BLOCK_FUNCTIONS[8][8])(void) = { { (void(*)(void))&AARRAY_Fold_BLOCK_int8_t_int8_t, (void(*)(void))&AARRAY_Fold_BLOCK_int8_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int8_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int8_t_int64_t }, { (void(*)(void))&AARRAY_Fold_BLOCK_int16_t_int8_t, (void(*)(void))&AARRAY_Fold_BLOCK_int16_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int16_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int16_t_int64_t }, {0}, { (void(*)(void))&AARRAY_Fold_BLOCK_int32_t_int8_t, (void(*)(void))&AARRAY_Fold_BLOCK_int32_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int32_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int32_t_int64_t }, {0}, {0}, {0}, { (void(*)(void))&AARRAY_Fold_BLOCK_int64_t_int8_t, (void(*)(void))&AARRAY_Fold_BLOCK_int64_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int64_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_BLOCK_int64_t_int64_t } }; #define aFold_BLOCK(vec, base, f) \ (AARRAY_typeof(base, (uint64_t(*)(char[], void*, uint64_t, \ uint64_t(^)(uint64_t,uint64_t))) \ AARRAY_Fold_BLOCK_FUNCTIONS[sizeof(base)-1][sizeof(*vec)-1]) \ (AARRAY_LINE, vec, (uint64_t)base, (uint64_t(^)(uint64_t,uint64_t))f)) #endif # 3730 "./aArray.h" #if defined(__cplusplus) AARRAY_define(int8_t AARRAY_Fold_LAMBDA_int8_t_int8_t( char errLoc[], int8_t*vec, int8_t base, std::function<int8_t(int8_t,int8_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_LAMBDA_int16_t_int8_t( char errLoc[], int8_t*vec, int16_t base, std::function<int16_t(int16_t,int8_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_LAMBDA_int32_t_int8_t( char errLoc[], int8_t*vec, int32_t base, std::function<int32_t(int32_t,int8_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_LAMBDA_int64_t_int8_t( char errLoc[], int8_t*vec, int64_t base, std::function<int64_t(int64_t,int8_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int8_t AARRAY_Fold_LAMBDA_int8_t_int16_t( char errLoc[], int16_t*vec, int8_t base, std::function<int8_t(int8_t,int16_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_LAMBDA_int16_t_int16_t( char errLoc[], int16_t*vec, int16_t base, std::function<int16_t(int16_t,int16_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_LAMBDA_int32_t_int16_t( char errLoc[], int16_t*vec, int32_t base, std::function<int32_t(int32_t,int16_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_LAMBDA_int64_t_int16_t( char errLoc[], int16_t*vec, int64_t base, std::function<int64_t(int64_t,int16_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int8_t AARRAY_Fold_LAMBDA_int8_t_int32_t( char errLoc[], int32_t*vec, int8_t base, std::function<int8_t(int8_t,int32_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_LAMBDA_int16_t_int32_t( char errLoc[], int32_t*vec, int16_t base, std::function<int16_t(int16_t,int32_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_LAMBDA_int32_t_int32_t( char errLoc[], int32_t*vec, int32_t base, std::function<int32_t(int32_t,int32_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_LAMBDA_int64_t_int32_t( char errLoc[], int32_t*vec, int64_t base, std::function<int64_t(int64_t,int32_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int8_t AARRAY_Fold_LAMBDA_int8_t_int64_t( char errLoc[], int64_t*vec, int8_t base, std::function<int8_t(int8_t,int64_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int16_t AARRAY_Fold_LAMBDA_int16_t_int64_t( char errLoc[], int64_t*vec, int16_t base, std::function<int16_t(int16_t,int64_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int32_t AARRAY_Fold_LAMBDA_int32_t_int64_t( char errLoc[], int64_t*vec, int32_t base, std::function<int32_t(int32_t,int64_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) AARRAY_define(int64_t AARRAY_Fold_LAMBDA_int64_t_int64_t( char errLoc[], int64_t*vec, int64_t base, std::function<int64_t(int64_t,int64_t)>f), { AARRAY_safety((void)errLoc, if(!f) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < aLength(vec)) base = f(base,vec[n] ); return base; }) static void(*const AARRAY_Fold_LAMBDA_FUNCTIONS[8][8])(void) = { { (void(*)(void))&AARRAY_Fold_LAMBDA_int8_t_int8_t, (void(*)(void))&AARRAY_Fold_LAMBDA_int8_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int8_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int8_t_int64_t }, { (void(*)(void))&AARRAY_Fold_LAMBDA_int16_t_int8_t, (void(*)(void))&AARRAY_Fold_LAMBDA_int16_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int16_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int16_t_int64_t }, {0}, { (void(*)(void))&AARRAY_Fold_LAMBDA_int32_t_int8_t, (void(*)(void))&AARRAY_Fold_LAMBDA_int32_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int32_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int32_t_int64_t }, {0}, {0}, {0}, { (void(*)(void))&AARRAY_Fold_LAMBDA_int64_t_int8_t, (void(*)(void))&AARRAY_Fold_LAMBDA_int64_t_int16_t, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int64_t_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Fold_LAMBDA_int64_t_int64_t } }; #define aFold_LAMBDA(vec, base, f) \ (AARRAY_typeof(base, (uint64_t(*)(char[], void*, uint64_t, \ std::function<uint64_t(uint64_t,uint64_t)>)) \ AARRAY_Fold_LAMBDA_FUNCTIONS[sizeof(base)-1][sizeof(*vec)-1]) \ (AARRAY_LINE, vec, (uint64_t)base, f)) #endif # 3882 "./aArray.h" //// search and sort // aSort needs a whole bunch of helper macros and functions // thanks goes to: https://github.com/BonzaiThePenguin/WikiSort typedef struct { size_t size, power_of_two; size_t numerator, decimal; size_t denominator, decimal_step, numerator_step; } AARRAY_sortIt; AARRAY_define(void AARRAY_sortReverse__int8_t( int8_t vec[], size_t start, size_t end), { int8_t temp; for(size_t n = (end-start)/2; n > 0; n--) { temp = vec[start+n-1]; vec[start+n-1] = vec[end-n]; vec[end-n] = temp; } }) AARRAY_define(void AARRAY_sortReverse__int16_t( int16_t vec[], size_t start, size_t end), { int16_t temp; for(size_t n = (end-start)/2; n > 0; n--) { temp = vec[start+n-1]; vec[start+n-1] = vec[end-n]; vec[end-n] = temp; } }) AARRAY_define(void AARRAY_sortReverse__int32_t( int32_t vec[], size_t start, size_t end), { int32_t temp; for(size_t n = (end-start)/2; n > 0; n--) { temp = vec[start+n-1]; vec[start+n-1] = vec[end-n]; vec[end-n] = temp; } }) AARRAY_define(void AARRAY_sortReverse__int64_t( int64_t vec[], size_t start, size_t end), { int64_t temp; for(size_t n = (end-start)/2; n > 0; n--) { temp = vec[start+n-1]; vec[start+n-1] = vec[end-n]; vec[end-n] = temp; } }) static void(*const AARRAY_sortReverse__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortReverse__int8_t, (void(*)(void))&AARRAY_sortReverse__int16_t, 0, (void(*)(void))&AARRAY_sortReverse__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortReverse__int64_t }; #define AARRAY_aSortReverse(vec, start, end) \ (((int(*)(void*, size_t, size_t)) \ AARRAY_sortReverse__FUNCTIONS[sizeof(*vec)-1])((void*)vec, start, end)) AARRAY_define(void AARRAY_sortRotate__int8_t( int8_t array[], const size_t amount, size_t start, size_t end, int8_t cache[], const size_t cacheSize), { if(end-start == 0) return; size_t sA = start, eA = start+amount, sB = start+amount, eB = end; if(eA-sA <= eB-sB) { if(eA-sA <= cacheSize) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); memmove(&array[sA], &array[sB], (eB-sB)*sizeof(array[0])); memcpy(&array[sA+(eB-sB)], &cache[0], (eA-sA)*sizeof(array[0])); return; } } else { if(eB-sB <= cacheSize) { memcpy(&cache[0], &array[sB], (eB-sB)*sizeof(array[0])); memmove(&array[eB-(eA-sA)], &array[sA], (eA-sA)*sizeof(array[0])); memcpy(&array[sA], &cache[0], (eB-sB)*sizeof(array[0])); return; } } AARRAY_aSortReverse(array, sA, eA); AARRAY_aSortReverse(array, sB, eB); AARRAY_aSortReverse(array, start, end); }) AARRAY_define(void AARRAY_sortRotate__int16_t( int16_t array[], const size_t amount, size_t start, size_t end, int16_t cache[], const size_t cacheSize), { if(end-start == 0) return; size_t sA = start, eA = start+amount, sB = start+amount, eB = end; if(eA-sA <= eB-sB) { if(eA-sA <= cacheSize) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); memmove(&array[sA], &array[sB], (eB-sB)*sizeof(array[0])); memcpy(&array[sA+(eB-sB)], &cache[0], (eA-sA)*sizeof(array[0])); return; } } else { if(eB-sB <= cacheSize) { memcpy(&cache[0], &array[sB], (eB-sB)*sizeof(array[0])); memmove(&array[eB-(eA-sA)], &array[sA], (eA-sA)*sizeof(array[0])); memcpy(&array[sA], &cache[0], (eB-sB)*sizeof(array[0])); return; } } AARRAY_aSortReverse(array, sA, eA); AARRAY_aSortReverse(array, sB, eB); AARRAY_aSortReverse(array, start, end); }) AARRAY_define(void AARRAY_sortRotate__int32_t( int32_t array[], const size_t amount, size_t start, size_t end, int32_t cache[], const size_t cacheSize), { if(end-start == 0) return; size_t sA = start, eA = start+amount, sB = start+amount, eB = end; if(eA-sA <= eB-sB) { if(eA-sA <= cacheSize) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); memmove(&array[sA], &array[sB], (eB-sB)*sizeof(array[0])); memcpy(&array[sA+(eB-sB)], &cache[0], (eA-sA)*sizeof(array[0])); return; } } else { if(eB-sB <= cacheSize) { memcpy(&cache[0], &array[sB], (eB-sB)*sizeof(array[0])); memmove(&array[eB-(eA-sA)], &array[sA], (eA-sA)*sizeof(array[0])); memcpy(&array[sA], &cache[0], (eB-sB)*sizeof(array[0])); return; } } AARRAY_aSortReverse(array, sA, eA); AARRAY_aSortReverse(array, sB, eB); AARRAY_aSortReverse(array, start, end); }) AARRAY_define(void AARRAY_sortRotate__int64_t( int64_t array[], const size_t amount, size_t start, size_t end, int64_t cache[], const size_t cacheSize), { if(end-start == 0) return; size_t sA = start, eA = start+amount, sB = start+amount, eB = end; if(eA-sA <= eB-sB) { if(eA-sA <= cacheSize) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); memmove(&array[sA], &array[sB], (eB-sB)*sizeof(array[0])); memcpy(&array[sA+(eB-sB)], &cache[0], (eA-sA)*sizeof(array[0])); return; } } else { if(eB-sB <= cacheSize) { memcpy(&cache[0], &array[sB], (eB-sB)*sizeof(array[0])); memmove(&array[eB-(eA-sA)], &array[sA], (eA-sA)*sizeof(array[0])); memcpy(&array[sA], &cache[0], (eB-sB)*sizeof(array[0])); return; } } AARRAY_aSortReverse(array, sA, eA); AARRAY_aSortReverse(array, sB, eB); AARRAY_aSortReverse(array, start, end); }) static void(*const AARRAY_sortRotate__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortRotate__int8_t, (void(*)(void))&AARRAY_sortRotate__int16_t, 0, (void(*)(void))&AARRAY_sortRotate__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortRotate__int64_t }; #define AARRAY_aSortRotate(vec, value, start, end, vecb, cacheSize) \ (((void(*)(void*, size_t, size_t, size_t, void*, size_t)) \ AARRAY_sortRotate__FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, vecb, cacheSize)) AARRAY_define(size_t AARRAY_sortBinaryFirst_FUNC_int8_t( const int8_t array[], const int8_t value, size_t start, size_t end, int(*f)(int8_t,int8_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_FUNC_int16_t( const int16_t array[], const int16_t value, size_t start, size_t end, int(*f)(int16_t,int16_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_FUNC_int32_t( const int32_t array[], const int32_t value, size_t start, size_t end, int(*f)(int32_t,int32_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_FUNC_int64_t( const int64_t array[], const int64_t value, size_t start, size_t end, int(*f)(int64_t,int64_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) static void(*const AARRAY_sortBinaryFirst_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortBinaryFirst_FUNC_int8_t, (void(*)(void))&AARRAY_sortBinaryFirst_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sortBinaryFirst_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortBinaryFirst_FUNC_int64_t }; AARRAY_define(size_t AARRAY_sortBinaryLast_FUNC_int8_t( const int8_t array[], const int8_t value, size_t start, size_t end, int(*f)(int8_t,int8_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_FUNC_int16_t( const int16_t array[], const int16_t value, size_t start, size_t end, int(*f)(int16_t,int16_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_FUNC_int32_t( const int32_t array[], const int32_t value, size_t start, size_t end, int(*f)(int32_t,int32_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_FUNC_int64_t( const int64_t array[], const int64_t value, size_t start, size_t end, int(*f)(int64_t,int64_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) static void(*const AARRAY_sortBinaryLast_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortBinaryLast_FUNC_int8_t, (void(*)(void))&AARRAY_sortBinaryLast_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sortBinaryLast_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortBinaryLast_FUNC_int64_t }; #define AARRAY_aSortBinaryFirst_FUNC(vec, value, start, end, f) \ (((size_t(*)(void*, int64_t, size_t, size_t, void(*)(void))) \ AARRAY_sortBinaryFirst_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, (void(*)(void))f)) #define AARRAY_aSortBinaryLast_FUNC(vec, value, start, end, f) \ (((size_t(*)(void*, int64_t, size_t, size_t, void(*)(void))) \ AARRAY_sortBinaryLast_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, (void(*)(void))f)) #if __has_extension(blocks) AARRAY_define(size_t AARRAY_sortBinaryFirst_BLOCK_int8_t( const int8_t array[], const int8_t value, size_t start, size_t end, int(^f)(int8_t,int8_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_BLOCK_int16_t( const int16_t array[], const int16_t value, size_t start, size_t end, int(^f)(int16_t,int16_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_BLOCK_int32_t( const int32_t array[], const int32_t value, size_t start, size_t end, int(^f)(int32_t,int32_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_BLOCK_int64_t( const int64_t array[], const int64_t value, size_t start, size_t end, int(^f)(int64_t,int64_t)), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) static void(*const AARRAY_sortBinaryFirst_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortBinaryFirst_BLOCK_int8_t, (void(*)(void))&AARRAY_sortBinaryFirst_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sortBinaryFirst_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortBinaryFirst_BLOCK_int64_t }; AARRAY_define(size_t AARRAY_sortBinaryLast_BLOCK_int8_t( const int8_t array[], const int8_t value, size_t start, size_t end, int(^f)(int8_t,int8_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_BLOCK_int16_t( const int16_t array[], const int16_t value, size_t start, size_t end, int(^f)(int16_t,int16_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_BLOCK_int32_t( const int32_t array[], const int32_t value, size_t start, size_t end, int(^f)(int32_t,int32_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_BLOCK_int64_t( const int64_t array[], const int64_t value, size_t start, size_t end, int(^f)(int64_t,int64_t)), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) static void(*const AARRAY_sortBinaryLast_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortBinaryLast_BLOCK_int8_t, (void(*)(void))&AARRAY_sortBinaryLast_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sortBinaryLast_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortBinaryLast_BLOCK_int64_t }; #define AARRAY_aSortBinaryFirst_BLOCK(vec, value, start, end, f) \ (((size_t(*)(void*, int64_t, size_t, size_t, void*)) \ AARRAY_sortBinaryFirst_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, (void*)f)) #define AARRAY_aSortBinaryLast_BLOCK(vec, value, start, end, f) \ (((size_t(*)(void*, int64_t, size_t, size_t, void*)) \ AARRAY_sortBinaryLast_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, (void*)f)) #endif # 4250 "./aArray.h" #if defined(__cplusplus) AARRAY_define(size_t AARRAY_sortBinaryFirst_LAMBDA_int8_t( const int8_t array[], const int8_t value, size_t start, size_t end, std::function<int(int8_t, int8_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_LAMBDA_int16_t( const int16_t array[], const int16_t value, size_t start, size_t end, std::function<int(int16_t, int16_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_LAMBDA_int32_t( const int32_t array[], const int32_t value, size_t start, size_t end, std::function<int(int32_t, int32_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryFirst_LAMBDA_int64_t( const int64_t array[], const int64_t value, size_t start, size_t end, std::function<int(int64_t, int64_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return start; while(start < end) { size_t mid = start+(end-start)/2; if(f(array[mid], value)) start = mid+1; else end = mid; } if(start == rend-1 && f(array[start], value)) start++; return start; }) static void(*const AARRAY_sortBinaryFirst_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortBinaryFirst_LAMBDA_int8_t, (void(*)(void))&AARRAY_sortBinaryFirst_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sortBinaryFirst_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortBinaryFirst_LAMBDA_int64_t }; AARRAY_define(size_t AARRAY_sortBinaryLast_LAMBDA_int8_t( const int8_t array[], const int8_t value, size_t start, size_t end, std::function<int(int8_t, int8_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_LAMBDA_int16_t( const int16_t array[], const int16_t value, size_t start, size_t end, std::function<int(int16_t, int16_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_LAMBDA_int32_t( const int32_t array[], const int32_t value, size_t start, size_t end, std::function<int(int32_t, int32_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) AARRAY_define(size_t AARRAY_sortBinaryLast_LAMBDA_int64_t( const int64_t array[], const int64_t value, size_t start, size_t end, std::function<int(int64_t, int64_t)>f), { size_t rend = end; end -= 1; if(start >= rend) return end; while(start < end) { size_t mid = start+(end-start)/2; if(!f(value, array[mid])) start = mid+1; else end = mid; } if(start == rend-1 && !f(value, array[start])) start++; return start; }) static void(*const AARRAY_sortBinaryLast_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortBinaryLast_LAMBDA_int8_t, (void(*)(void))&AARRAY_sortBinaryLast_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sortBinaryLast_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortBinaryLast_LAMBDA_int64_t }; #define AARRAY_aSortBinaryFirst_LAMBDA(vec, value, start, end, f) \ (((size_t(*)(void*, int64_t, size_t, size_t, std::function<int(int,int)>)) \ AARRAY_sortBinaryFirst_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, (std::function<int(int,int)>)f)) #define AARRAY_aSortBinaryLast_LAMBDA(vec, value, start, end, f) \ (((size_t(*)(void*, int64_t, size_t, size_t, std::function<int(int,int)>)) \ AARRAY_sortBinaryLast_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, value, start, end, (std::function<int(int,int)>)f)) #endif # 4366 "./aArray.h" AARRAY_define(void AARRAY_sortNextRange__int8_t( AARRAY_sortIt*it, size_t*start, size_t*end), { *start = it->decimal; it->decimal += it->decimal_step; it->numerator += it->numerator_step; if(it->numerator >= it->denominator) { it->numerator -= it->denominator; it->decimal++; } *end = it->decimal; }) AARRAY_define(void AARRAY_sortNextRange__int16_t( AARRAY_sortIt*it, size_t*start, size_t*end), { *start = it->decimal; it->decimal += it->decimal_step; it->numerator += it->numerator_step; if(it->numerator >= it->denominator) { it->numerator -= it->denominator; it->decimal++; } *end = it->decimal; }) AARRAY_define(void AARRAY_sortNextRange__int32_t( AARRAY_sortIt*it, size_t*start, size_t*end), { *start = it->decimal; it->decimal += it->decimal_step; it->numerator += it->numerator_step; if(it->numerator >= it->denominator) { it->numerator -= it->denominator; it->decimal++; } *end = it->decimal; }) AARRAY_define(void AARRAY_sortNextRange__int64_t( AARRAY_sortIt*it, size_t*start, size_t*end), { *start = it->decimal; it->decimal += it->decimal_step; it->numerator += it->numerator_step; if(it->numerator >= it->denominator) { it->numerator -= it->denominator; it->decimal++; } *end = it->decimal; }) static void(*const AARRAY_sortNextRange__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortNextRange__int8_t, (void(*)(void))&AARRAY_sortNextRange__int16_t, 0, (void(*)(void))&AARRAY_sortNextRange__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortNextRange__int64_t }; AARRAY_define(int AARRAY_sortNextLevel__int8_t(AARRAY_sortIt*it), { it->decimal_step += it->decimal_step; it->numerator_step += it->numerator_step; if(it->numerator_step >= it->denominator) { it->numerator_step -= it->denominator; it->decimal_step++; } return it->decimal_step < it->size; }) AARRAY_define(int AARRAY_sortNextLevel__int16_t(AARRAY_sortIt*it), { it->decimal_step += it->decimal_step; it->numerator_step += it->numerator_step; if(it->numerator_step >= it->denominator) { it->numerator_step -= it->denominator; it->decimal_step++; } return it->decimal_step < it->size; }) AARRAY_define(int AARRAY_sortNextLevel__int32_t(AARRAY_sortIt*it), { it->decimal_step += it->decimal_step; it->numerator_step += it->numerator_step; if(it->numerator_step >= it->denominator) { it->numerator_step -= it->denominator; it->decimal_step++; } return it->decimal_step < it->size; }) AARRAY_define(int AARRAY_sortNextLevel__int64_t(AARRAY_sortIt*it), { it->decimal_step += it->decimal_step; it->numerator_step += it->numerator_step; if(it->numerator_step >= it->denominator) { it->numerator_step -= it->denominator; it->decimal_step++; } return it->decimal_step < it->size; }) static void(*const AARRAY_sortNextLevel__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortNextLevel__int8_t, (void(*)(void))&AARRAY_sortNextLevel__int16_t, 0, (void(*)(void))&AARRAY_sortNextLevel__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortNextLevel__int64_t }; #define AARRAY_aSortNextRange(vec, iter, start, end) \ (((void(*)(AARRAY_sortIt*, size_t*, size_t*)) \ AARRAY_sortNextRange__FUNCTIONS[sizeof(*vec)-1])(iter, start, end)) #define AARRAY_aSortNextLevel(vec, iter) \ (((int (*)(AARRAY_sortIt*)) \ AARRAY_sortNextLevel__FUNCTIONS[sizeof(*vec)-1])(iter)) AARRAY_define(void AARRAY_sortMergeInto_FUNC_int8_t( int8_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int8_t,int8_t), int8_t into[]), { int8_t*A_index = &from[sA], *B_index = &from[sB]; int8_t*A_last = &from[eA], *B_last = &from[eB]; int8_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_FUNC_int16_t( int16_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int16_t,int16_t), int16_t into[]), { int16_t*A_index = &from[sA], *B_index = &from[sB]; int16_t*A_last = &from[eA], *B_last = &from[eB]; int16_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_FUNC_int32_t( int32_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int32_t,int32_t), int32_t into[]), { int32_t*A_index = &from[sA], *B_index = &from[sB]; int32_t*A_last = &from[eA], *B_last = &from[eB]; int32_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_FUNC_int64_t( int64_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int64_t,int64_t), int64_t into[]), { int64_t*A_index = &from[sA], *B_index = &from[sB]; int64_t*A_last = &from[eA], *B_last = &from[eB]; int64_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) static void(*const AARRAY_sortMergeInto_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInto_FUNC_int8_t, (void(*)(void))&AARRAY_sortMergeInto_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInto_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInto_FUNC_int64_t }; AARRAY_define(void AARRAY_sortMergeExternal_FUNC_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int8_t,int8_t), int8_t cache[]), { int8_t*A_index = &cache[0]; int8_t*B_index = &array[sB]; int8_t*insert_index = &array[sA]; int8_t*A_last = &cache[eA-sA]; int8_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_FUNC_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int16_t,int16_t), int16_t cache[]), { int16_t*A_index = &cache[0]; int16_t*B_index = &array[sB]; int16_t*insert_index = &array[sA]; int16_t*A_last = &cache[eA-sA]; int16_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_FUNC_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int32_t,int32_t), int32_t cache[]), { int32_t*A_index = &cache[0]; int32_t*B_index = &array[sB]; int32_t*insert_index = &array[sA]; int32_t*A_last = &cache[eA-sA]; int32_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_FUNC_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int64_t,int64_t), int64_t cache[]), { int64_t*A_index = &cache[0]; int64_t*B_index = &array[sB]; int64_t*insert_index = &array[sA]; int64_t*A_last = &cache[eA-sA]; int64_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) static void(*const AARRAY_sortMergeExternal_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeExternal_FUNC_int8_t, (void(*)(void))&AARRAY_sortMergeExternal_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sortMergeExternal_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeExternal_FUNC_int64_t }; AARRAY_define(void AARRAY_sortMergeInternal_FUNC_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int8_t,int8_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int8_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int8_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int8_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_FUNC_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int16_t,int16_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int16_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int16_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int16_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_FUNC_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int32_t,int32_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int32_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int32_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int32_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_FUNC_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int64_t,int64_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int64_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int64_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int64_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) static void(*const AARRAY_sortMergeInternal_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInternal_FUNC_int8_t, (void(*)(void))&AARRAY_sortMergeInternal_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInternal_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInternal_FUNC_int64_t }; AARRAY_define(void AARRAY_sortMergeInPlace_FUNC_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int8_t,int8_t), int8_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_FUNC(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_FUNC(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_FUNC_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int16_t,int16_t), int16_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_FUNC(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_FUNC(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_FUNC_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int32_t,int32_t), int32_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_FUNC(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_FUNC(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_FUNC_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(*f)(int64_t,int64_t), int64_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_FUNC(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_FUNC(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) static void(*const AARRAY_sortMergeInPlace_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInPlace_FUNC_int8_t, (void(*)(void))&AARRAY_sortMergeInPlace_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInPlace_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInPlace_FUNC_int64_t }; #define AARRAY_aSortMergeInto_FUNC(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void(*)(void), void*)) \ AARRAY_sortMergeInto_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void(*)(void))f, vecb)) #define AARRAY_aSortMergeExternal_FUNC(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void(*)(void), void*)) \ AARRAY_sortMergeExternal_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void(*)(void))f, vecb)) #define AARRAY_aSortMergeInternal_FUNC(vec, s1, s2, s3, s4, f, s5) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void(*)(void), size_t)) \ AARRAY_sortMergeInternal_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void(*)(void))f, s5)) #define AARRAY_aSortMergeInPlace_FUNC(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void(*)(void), void*)) \ AARRAY_sortMergeInPlace_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void(*)(void))f, vecb)) #if __has_extension(blocks) AARRAY_define(void AARRAY_sortMergeInto_BLOCK_int8_t( int8_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int8_t,int8_t), int8_t into[]), { int8_t*A_index = &from[sA], *B_index = &from[sB]; int8_t*A_last = &from[eA], *B_last = &from[eB]; int8_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_BLOCK_int16_t( int16_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int16_t,int16_t), int16_t into[]), { int16_t*A_index = &from[sA], *B_index = &from[sB]; int16_t*A_last = &from[eA], *B_last = &from[eB]; int16_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_BLOCK_int32_t( int32_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int32_t,int32_t), int32_t into[]), { int32_t*A_index = &from[sA], *B_index = &from[sB]; int32_t*A_last = &from[eA], *B_last = &from[eB]; int32_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_BLOCK_int64_t( int64_t from[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int64_t,int64_t), int64_t into[]), { int64_t*A_index = &from[sA], *B_index = &from[sB]; int64_t*A_last = &from[eA], *B_last = &from[eB]; int64_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) static void(*const AARRAY_sortMergeInto_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInto_BLOCK_int8_t, (void(*)(void))&AARRAY_sortMergeInto_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInto_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInto_BLOCK_int64_t }; AARRAY_define(void AARRAY_sortMergeExternal_BLOCK_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int8_t,int8_t), int8_t cache[]), { int8_t*A_index = &cache[0]; int8_t*B_index = &array[sB]; int8_t*insert_index = &array[sA]; int8_t*A_last = &cache[eA-sA]; int8_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_BLOCK_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int16_t,int16_t), int16_t cache[]), { int16_t*A_index = &cache[0]; int16_t*B_index = &array[sB]; int16_t*insert_index = &array[sA]; int16_t*A_last = &cache[eA-sA]; int16_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_BLOCK_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int32_t,int32_t), int32_t cache[]), { int32_t*A_index = &cache[0]; int32_t*B_index = &array[sB]; int32_t*insert_index = &array[sA]; int32_t*A_last = &cache[eA-sA]; int32_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_BLOCK_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int64_t,int64_t), int64_t cache[]), { int64_t*A_index = &cache[0]; int64_t*B_index = &array[sB]; int64_t*insert_index = &array[sA]; int64_t*A_last = &cache[eA-sA]; int64_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) static void(*const AARRAY_sortMergeExternal_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeExternal_BLOCK_int8_t, (void(*)(void))&AARRAY_sortMergeExternal_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sortMergeExternal_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeExternal_BLOCK_int64_t }; AARRAY_define(void AARRAY_sortMergeInternal_BLOCK_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int8_t,int8_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int8_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int8_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int8_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_BLOCK_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int16_t,int16_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int16_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int16_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int16_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_BLOCK_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int32_t,int32_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int32_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int32_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int32_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_BLOCK_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int64_t,int64_t), size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int64_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int64_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int64_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) static void(*const AARRAY_sortMergeInternal_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInternal_BLOCK_int8_t, (void(*)(void))&AARRAY_sortMergeInternal_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInternal_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInternal_BLOCK_int64_t }; AARRAY_define(void AARRAY_sortMergeInPlace_BLOCK_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int8_t,int8_t), int8_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_BLOCK(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_BLOCK(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_BLOCK_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int16_t,int16_t), int16_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_BLOCK(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_BLOCK(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_BLOCK_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int32_t,int32_t), int32_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_BLOCK(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_BLOCK(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_BLOCK_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, int(^f)(int64_t,int64_t), int64_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_BLOCK(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_BLOCK(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) static void(*const AARRAY_sortMergeInPlace_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInPlace_BLOCK_int8_t, (void(*)(void))&AARRAY_sortMergeInPlace_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInPlace_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInPlace_BLOCK_int64_t }; #define AARRAY_aSortMergeInto_BLOCK(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void*, void*)) \ AARRAY_sortMergeInto_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void*)f, vecb)) #define AARRAY_aSortMergeExternal_BLOCK(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void*, void*)) \ AARRAY_sortMergeExternal_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void*)f, vecb)) #define AARRAY_aSortMergeInternal_BLOCK(vec, s1, s2, s3, s4, f, s5) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void*, size_t)) \ AARRAY_sortMergeInternal_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void*)f, s5)) #define AARRAY_aSortMergeInPlace_BLOCK(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, void*, void*)) \ AARRAY_sortMergeInPlace_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (void*)f, vecb)) #endif # 5154 "./aArray.h" #if defined(__cplusplus) AARRAY_define(void AARRAY_sortMergeInto_LAMBDA_int8_t( int8_t from[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int8_t, int8_t)>f, int8_t into[]), { int8_t*A_index = &from[sA], *B_index = &from[sB]; int8_t*A_last = &from[eA], *B_last = &from[eB]; int8_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_LAMBDA_int16_t( int16_t from[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int16_t, int16_t)>f, int16_t into[]), { int16_t*A_index = &from[sA], *B_index = &from[sB]; int16_t*A_last = &from[eA], *B_last = &from[eB]; int16_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_LAMBDA_int32_t( int32_t from[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int32_t, int32_t)>f, int32_t into[]), { int32_t*A_index = &from[sA], *B_index = &from[sB]; int32_t*A_last = &from[eA], *B_last = &from[eB]; int32_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) AARRAY_define(void AARRAY_sortMergeInto_LAMBDA_int64_t( int64_t from[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int64_t, int64_t)>f, int64_t into[]), { int64_t*A_index = &from[sA], *B_index = &from[sB]; int64_t*A_last = &from[eA], *B_last = &from[eB]; int64_t*insert_index = &into[0]; while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) { memcpy(insert_index, B_index, (size_t)(B_last-B_index)*sizeof(from[0])); break; } } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) { memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(from[0])); break; } } } }) static void(*const AARRAY_sortMergeInto_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInto_LAMBDA_int8_t, (void(*)(void))&AARRAY_sortMergeInto_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInto_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInto_LAMBDA_int64_t }; AARRAY_define(void AARRAY_sortMergeExternal_LAMBDA_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int8_t, int8_t)>f, int8_t cache[]), { int8_t*A_index = &cache[0]; int8_t*B_index = &array[sB]; int8_t*insert_index = &array[sA]; int8_t*A_last = &cache[eA-sA]; int8_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_LAMBDA_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int16_t, int16_t)>f, int16_t cache[]), { int16_t*A_index = &cache[0]; int16_t*B_index = &array[sB]; int16_t*insert_index = &array[sA]; int16_t*A_last = &cache[eA-sA]; int16_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_LAMBDA_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int32_t, int32_t)>f, int32_t cache[]), { int32_t*A_index = &cache[0]; int32_t*B_index = &array[sB]; int32_t*insert_index = &array[sA]; int32_t*A_last = &cache[eA-sA]; int32_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) AARRAY_define(void AARRAY_sortMergeExternal_LAMBDA_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int64_t, int64_t)>f, int64_t cache[]), { int64_t*A_index = &cache[0]; int64_t*B_index = &array[sB]; int64_t*insert_index = &array[sA]; int64_t*A_last = &cache[eA-sA]; int64_t*B_last = &array[eB]; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(*B_index, *A_index)) { *insert_index = *A_index; A_index++; insert_index++; if(A_index == A_last) break; } else { *insert_index = *B_index; B_index++; insert_index++; if(B_index == B_last) break; } } } memcpy(insert_index, A_index, (size_t)(A_last-A_index)*sizeof(array[0])); }) static void(*const AARRAY_sortMergeExternal_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeExternal_LAMBDA_int8_t, (void(*)(void))&AARRAY_sortMergeExternal_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sortMergeExternal_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeExternal_LAMBDA_int64_t }; AARRAY_define(void AARRAY_sortMergeInternal_LAMBDA_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int8_t, int8_t)>f, size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int8_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int8_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int8_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_LAMBDA_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int16_t, int16_t)>f, size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int16_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int16_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int16_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_LAMBDA_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int32_t, int32_t)>f, size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int32_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int32_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int32_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) AARRAY_define(void AARRAY_sortMergeInternal_LAMBDA_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int64_t, int64_t)>f, size_t sBuff), { size_t A_count = 0, B_count = 0, insert = 0; if(eB-sB > 0 && eA-sA > 0) { while(1) { if(!f(array[sB+B_count], array[sBuff+A_count])) { { int64_t temp = array[sA+insert]; array[sA+insert] = array[sBuff+A_count]; array[sBuff+A_count] = temp; }; A_count++; insert++; if(A_count >= eA-sA) break; } else { { int64_t temp = array[sA+insert]; array[sA+insert] = array[sB+B_count]; array[sB+B_count] = temp; }; B_count++; insert++; if(B_count >= eB-sB) break; } } } for(size_t n = 0; n < (eA-sA)-A_count; n++) { int64_t temp = array[sBuff+A_count+n]; array[sBuff+A_count+n] = array[sA+insert+n]; array[sA+insert+n] = temp; }; }) static void(*const AARRAY_sortMergeInternal_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInternal_LAMBDA_int8_t, (void(*)(void))&AARRAY_sortMergeInternal_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInternal_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInternal_LAMBDA_int64_t }; AARRAY_define(void AARRAY_sortMergeInPlace_LAMBDA_int8_t( int8_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int8_t, int8_t)>f, int8_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_LAMBDA(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_LAMBDA_int16_t( int16_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int16_t, int16_t)>f, int16_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_LAMBDA(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_LAMBDA_int32_t( int32_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int32_t, int32_t)>f, int32_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_LAMBDA(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) AARRAY_define(void AARRAY_sortMergeInPlace_LAMBDA_int64_t( int64_t array[], size_t sA, size_t eA, size_t sB, size_t eB, std::function<int(int64_t, int64_t)>f, int64_t cache[]), { if(eA-sA == 0 || eB-sB == 0) return; while(1) { size_t mid = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sA], sB, eB, f); size_t amount = mid-eA; AARRAY_aSortRotate(array, eA-sA, sA, mid, cache, AARRAY_sortCache); if(eB == mid) break; sB = mid; sA = sA+amount; eA = sB; sA = AARRAY_aSortBinaryLast_LAMBDA(array, array[sA], sA, eA, f); if(eA-sA == 0) break; } }) static void(*const AARRAY_sortMergeInPlace_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortMergeInPlace_LAMBDA_int8_t, (void(*)(void))&AARRAY_sortMergeInPlace_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sortMergeInPlace_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortMergeInPlace_LAMBDA_int64_t }; #define AARRAY_aSortMergeInto_LAMBDA(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, \ std::function<int(int,int)>, void*)) \ AARRAY_sortMergeInto_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (std::function<int(int,int)>)f, vecb)) #define AARRAY_aSortMergeExternal_LAMBDA(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, \ std::function<int(int,int)>, void*)) \ AARRAY_sortMergeExternal_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (std::function<int(int,int)>)f, vecb)) #define AARRAY_aSortMergeInternal_LAMBDA(vec, s1, s2, s3, s4, f, s5) \ (((void(*)(void*, size_t, size_t, size_t, size_t, \ std::function<int(int,int)>, size_t)) \ AARRAY_sortMergeInternal_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (std::function<int(int,int)>)f, s5)) #define AARRAY_aSortMergeInPlace_LAMBDA(vec, s1, s2, s3, s4, f, vecb) \ (((void(*)(void*, size_t, size_t, size_t, size_t, \ std::function<int(int,int)>, void*)) \ AARRAY_sortMergeInPlace_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, s1, s2, s3, s4, (std::function<int(int,int)>)f, vecb)) #endif # 5512 "./aArray.h" // all that work, just to support this beast // I'm glad I didn't write it myself AARRAY_define(int AARRAY_sortCompare__int8_t(int8_t a, int8_t b), { return a<b; }) AARRAY_define(int AARRAY_sortCompare__int16_t(int16_t a, int16_t b), { return a<b; }) AARRAY_define(int AARRAY_sortCompare__int32_t(int32_t a, int32_t b), { return a<b; }) AARRAY_define(int AARRAY_sortCompare__int64_t(int64_t a, int64_t b), { return a<b; }) static void(*const AARRAY_sortCompare__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sortCompare__int8_t, (void(*)(void))&AARRAY_sortCompare__int16_t, 0, (void(*)(void))&AARRAY_sortCompare__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sortCompare__int64_t }; AARRAY_define(int8_t*AARRAY_sort_FUNC_int8_t( int8_t array[], int(*f)(int8_t,int8_t)), { size_t size = aLength(array); int8_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int8_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int8_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_FUNC( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_FUNC( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_FUNC( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_FUNC( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int8_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int8_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_FUNC( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int8_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int8_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int8_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int16_t*AARRAY_sort_FUNC_int16_t( int16_t array[], int(*f)(int16_t,int16_t)), { size_t size = aLength(array); int16_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int16_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int16_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_FUNC( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_FUNC( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_FUNC( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_FUNC( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int16_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int16_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_FUNC( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int16_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int16_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int16_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int32_t*AARRAY_sort_FUNC_int32_t( int32_t array[], int(*f)(int32_t,int32_t)), { size_t size = aLength(array); int32_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int32_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int32_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_FUNC( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_FUNC( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_FUNC( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_FUNC( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int32_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int32_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_FUNC( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int32_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int32_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int32_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int64_t*AARRAY_sort_FUNC_int64_t( int64_t array[], int(*f)(int64_t,int64_t)), { size_t size = aLength(array); int64_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int64_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int64_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_FUNC( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_FUNC( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_FUNC( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_FUNC( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int64_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int64_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_FUNC( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int64_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int64_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_FUNC( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_FUNC( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int64_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_FUNC(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_FUNC(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) static void(*const AARRAY_sort_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sort_FUNC_int8_t, (void(*)(void))&AARRAY_sort_FUNC_int16_t, 0, (void(*)(void))&AARRAY_sort_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sort_FUNC_int64_t }; #define aSort(vec) \ (AARRAY_typeof(vec, (uint64_t*(*)(void*,void(*)(void))) \ AARRAY_sort_FUNC_FUNCTIONS[sizeof(*vec)-1])((void*)vec, (void(*)(void)) \ AARRAY_sortCompare__FUNCTIONS[sizeof(*vec)-1])) #define aSortF_FUNC(vec, f) \ (AARRAY_typeof(vec, (uint64_t*(*)(void*,void(*)(void))) \ AARRAY_sort_FUNC_FUNCTIONS[sizeof(*vec)-1])((void*)vec, (void(*)(void))f)) #if __has_extension(blocks) AARRAY_define(int8_t*AARRAY_sort_BLOCK_int8_t( int8_t array[], int(^f)(int8_t,int8_t)), { size_t size = aLength(array); int8_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int8_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int8_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_BLOCK( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_BLOCK( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int8_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int8_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_BLOCK( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int8_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int8_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int8_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int16_t*AARRAY_sort_BLOCK_int16_t( int16_t array[], int(^f)(int16_t,int16_t)), { size_t size = aLength(array); int16_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int16_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int16_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_BLOCK( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_BLOCK( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int16_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int16_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_BLOCK( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int16_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int16_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int16_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int32_t*AARRAY_sort_BLOCK_int32_t( int32_t array[], int(^f)(int32_t,int32_t)), { size_t size = aLength(array); int32_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int32_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int32_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_BLOCK( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_BLOCK( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int32_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int32_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_BLOCK( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int32_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int32_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int32_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int64_t*AARRAY_sort_BLOCK_int64_t( int64_t array[], int(^f)(int64_t,int64_t)), { size_t size = aLength(array); int64_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int64_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int64_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_BLOCK( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_BLOCK( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_BLOCK( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int64_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int64_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_BLOCK( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int64_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int64_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_BLOCK( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_BLOCK( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int64_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_BLOCK(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_BLOCK(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) static void(*const AARRAY_sort_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sort_BLOCK_int8_t, (void(*)(void))&AARRAY_sort_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_sort_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sort_BLOCK_int64_t }; #define aSortF_BLOCK(vec, f) \ (AARRAY_typeof(vec, (uint64_t*(*)(void*, void*)) \ AARRAY_sort_BLOCK_FUNCTIONS[sizeof(*vec)-1])((void*)vec, (void*)f)) #endif # 13255 "./aArray.h" #if defined(__cplusplus) AARRAY_define(int8_t*AARRAY_sort_LAMBDA_int8_t( int8_t array[], std::function<int(int8_t, int8_t)>f), { size_t size = aLength(array); int8_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int8_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int8_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int8_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int8_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int8_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int8_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int8_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int8_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int8_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_LAMBDA( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_LAMBDA( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int8_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int8_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_LAMBDA( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int8_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int8_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int8_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int8_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int16_t*AARRAY_sort_LAMBDA_int16_t( int16_t array[], std::function<int(int16_t, int16_t)>f), { size_t size = aLength(array); int16_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int16_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int16_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int16_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int16_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int16_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int16_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int16_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int16_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int16_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_LAMBDA( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_LAMBDA( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int16_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int16_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_LAMBDA( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int16_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int16_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int16_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int16_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int32_t*AARRAY_sort_LAMBDA_int32_t( int32_t array[], std::function<int(int32_t, int32_t)>f), { size_t size = aLength(array); int32_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int32_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int32_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int32_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int32_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int32_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int32_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int32_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int32_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int32_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_LAMBDA( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_LAMBDA( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int32_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int32_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_LAMBDA( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int32_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int32_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int32_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int32_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) AARRAY_define(int64_t*AARRAY_sort_LAMBDA_int64_t( int64_t array[], std::function<int(int64_t, int64_t)>f), { size_t size = aLength(array); int64_t cache[AARRAY_sortCache]; AARRAY_sortIt it; if(size < 4) { if(size == 3) { if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; if(f(array[2], array[1])) { { int64_t temp = array[1]; array[1] = array[2]; array[2] = temp; }; if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } } else if(size == 2) { if(f(array[1], array[0])) { int64_t temp = array[0]; array[0] = array[1]; array[1] = temp; }; } return array; } // new it it.size = size; // floor_power_of_2(size) size_t s = size; s = s | (s >> 1); s = s | (s >> 2); s = s | (s >> 4); s = s | (s >> 8); s = s | (s >> 16); if(sizeof(size_t)==8) s = s | (s >> 32); s = s-(s >> 1); it.power_of_two = s; it.denominator = it.power_of_two/4; it.numerator_step = it.size % it.denominator; it.decimal_step = it.size/it.denominator; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { uint8_t order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; size_t sRange, eRange; AARRAY_aSortNextRange(array, &it, &sRange, &eRange); if(eRange-sRange==8) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+7], array[sRange+6]) || (order[6] > order[7] && !f(array[sRange+6], array[sRange+7]))) { { int64_t temp = array[sRange+6]; array[sRange+6] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[6]; order[6] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+7], array[sRange+5]) || (order[5] > order[7] && !f(array[sRange+5], array[sRange+7]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[5]; order[5] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+7], array[sRange+3]) || (order[3] > order[7] && !f(array[sRange+3], array[sRange+7]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+7]; array[sRange+7] = temp; }; { uint8_t temp = order[3]; order[3] = order[7]; order[7] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+3]) || (order[3] > order[6] && !f(array[sRange+3], array[sRange+6]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[3]; order[3] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; } else if(eRange-sRange==7) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+6], array[sRange+5]) || (order[5] > order[6] && !f(array[sRange+5], array[sRange+6]))) { { int64_t temp = array[sRange+5]; array[sRange+5] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[5]; order[5] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+4]) || (order[4] > order[6] && !f(array[sRange+4], array[sRange+6]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[4]; order[4] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+6], array[sRange+2]) || (order[2] > order[6] && !f(array[sRange+2], array[sRange+6]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+6]; array[sRange+6] = temp; }; { uint8_t temp = order[2]; order[2] = order[6]; order[6] = temp; }; }; \ if(f(array[sRange+4], array[sRange+0]) || (order[0] > order[4] && !f(array[sRange+0], array[sRange+4]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[0]; order[0] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+1]) || (order[1] > order[5] && !f(array[sRange+1], array[sRange+5]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[1]; order[1] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==6) { \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+4]) || (order[4] > order[5] && !f(array[sRange+4], array[sRange+5]))) { { int64_t temp = array[sRange+4]; array[sRange+4] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[4]; order[4] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+5], array[sRange+3]) || (order[3] > order[5] && !f(array[sRange+3], array[sRange+5]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[3]; order[3] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+5], array[sRange+2]) || (order[2] > order[5] && !f(array[sRange+2], array[sRange+5]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+5]; array[sRange+5] = temp; }; { uint8_t temp = order[2]; order[2] = order[5]; order[5] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; } else if(eRange-sRange==5) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+4], array[sRange+3]) || (order[3] > order[4] && !f(array[sRange+3], array[sRange+4]))) { { int64_t temp = array[sRange+3]; array[sRange+3] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[3]; order[3] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+4], array[sRange+2]) || (order[2] > order[4] && !f(array[sRange+2], array[sRange+4]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[2]; order[2] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+4], array[sRange+1]) || (order[1] > order[4] && !f(array[sRange+1], array[sRange+4]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+4]; array[sRange+4] = temp; }; { uint8_t temp = order[1]; order[1] = order[4]; order[4] = temp; }; }; \ if(f(array[sRange+3], array[sRange+0]) || (order[0] > order[3] && !f(array[sRange+0], array[sRange+3]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[0]; order[0] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } else if(eRange-sRange==4) { \ if(f(array[sRange+1], array[sRange+0]) || (order[0] > order[1] && !f(array[sRange+0], array[sRange+1]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+1]; array[sRange+1] = temp; }; { uint8_t temp = order[0]; order[0] = order[1]; order[1] = temp; }; }; \ if(f(array[sRange+3], array[sRange+2]) || (order[2] > order[3] && !f(array[sRange+2], array[sRange+3]))) { { int64_t temp = array[sRange+2]; array[sRange+2] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[2]; order[2] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+0]) || (order[0] > order[2] && !f(array[sRange+0], array[sRange+2]))) { { int64_t temp = array[sRange+0]; array[sRange+0] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[0]; order[0] = order[2]; order[2] = temp; }; }; \ if(f(array[sRange+3], array[sRange+1]) || (order[1] > order[3] && !f(array[sRange+1], array[sRange+3]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+3]; array[sRange+3] = temp; }; { uint8_t temp = order[1]; order[1] = order[3]; order[3] = temp; }; }; \ if(f(array[sRange+2], array[sRange+1]) || (order[1] > order[2] && !f(array[sRange+1], array[sRange+2]))) { { int64_t temp = array[sRange+1]; array[sRange+1] = array[sRange+2]; array[sRange+2] = temp; }; { uint8_t temp = order[1]; order[1] = order[2]; order[2] = temp; }; }; } } if(size < 8) return array; while(1) { if(it.decimal_step < AARRAY_sortCache) { if((it.decimal_step+1)*4 <= AARRAY_sortCache && it.decimal_step*4 <= size) { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA1, sB1, sA2, sB2, sA3, sB3, eA1, eB1, eA2, eB2, eA3, eB3; AARRAY_aSortNextRange(array, &it, &sA1, &eA1); AARRAY_aSortNextRange(array, &it, &sB1, &eB1); AARRAY_aSortNextRange(array, &it, &sA2, &eA2); AARRAY_aSortNextRange(array, &it, &sB2, &eB2); if(f(array[eB1-1], array[sA1])) { memcpy(&cache[eB1-sB1], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[0], &array[sB1], (eB1-sB1)*sizeof(array[0])); } else if(f(array[sB1], array[eA1-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA1, eA1, sB1, eB1, f, &cache[0]); } else { if(!f(array[sB2], array[eA2-1]) && !f(array[sA2], array[eB1-1])) continue; memcpy(&cache[0], &array[sA1], (eA1-sA1)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)], &array[sB1], (eB1-sB1)*sizeof(array[0])); } eA1 = eB1; if(f(array[eB2-1], array[sA2])) { memcpy(&cache[(eA1-sA1)+(eB2-sB2)], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[eA1-sA1], &array[sB2], (eB2-sB2)*sizeof(array[0])); } else if(f(array[sB2], array[eA2-1])) { AARRAY_aSortMergeInto_LAMBDA( array, sA2, eA2, sB2, eB2, f, &cache[eA1-sA1]); } else { memcpy(&cache[eA1-sA1], &array[sA2], (eA2-sA2)*sizeof(array[0])); memcpy(&cache[(eA1-sA1)+(eA2-sA2)], &array[sB2], (eB2-sB2)*sizeof(array[0])); } eA2 = eB2; sA3 = 0; eA3 = eA1-sA1; sB3 = eA1-sA1; eB3 = (eA1-sA1)+(eA2-sA2); if(f(cache[eB3-1], cache[sA3])) { memcpy(&array[sA1+(eA2-sA2)], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } else if(f(cache[sB3], cache[eA3-1])) { AARRAY_aSortMergeInto_LAMBDA( cache, sA3, eA3, sB3, eB3, f, &array[sA1]); } else { memcpy(&array[sA1], &cache[sA3], (eA3-sA3)*sizeof(array[0])); memcpy(&array[sA1+(eA1-sA1)], &cache[sB3], (eB3-sB3)*sizeof(array[0])); } } AARRAY_aSortNextLevel(array, &it); } else { it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { size_t sA, eA, sB, eB; AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[sB], array[eA-1])) { memcpy(&cache[0], &array[sA], (eA-sA)*sizeof(array[0])); AARRAY_aSortMergeExternal_LAMBDA( array, sA, eA, sB, eB, f, cache); } } } } else { double block_size_d = sqrt(it.decimal_step); size_t block_size = (size_t)block_size_d; size_t buffer_size = it.decimal_step/block_size+1; int find_separately; size_t sBuff1, eBuff1, sBuff2, eBuff2, sA, eA, sB, eB; size_t index, last, count, find, start, pull_index = 0; struct { size_t from, to, count, sRange, eRange; } pull[2]; pull[0].from = pull[0].to = pull[0].count = 0; pull[1].from = pull[1].to = pull[1].count = 0; pull[0].sRange = pull[0].eRange = 0; pull[1].sRange = pull[1].eRange = 0; sBuff1 = 0; eBuff1 = 0; sBuff2 = 0; eBuff2 = 0; find_separately = 0; find = buffer_size+buffer_size; if(block_size <= AARRAY_sortCache) find = buffer_size; else if(find > it.decimal_step) { find = buffer_size; find_separately = 1; } it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); for(last = sA, count = 1; count < find; last = index, count++) { if(eA-(last+1) == 0) index = (last+1); else { int indexSet = 0; size_t skip = (eA-(last+1))/(find-count); if(!skip) skip = 1; for(index = (last+1)+skip; !f(array[last], array[index-1]); index += skip) if(index >= eA-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index, eA, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[last], index-skip, index, f); } ; if(index == eA) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+buffer_size; sBuff2 = sA+buffer_size; eBuff2 = sA+count; break; } else if(find == buffer_size+buffer_size) { sBuff1 = sA; eBuff1 = sA+count; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = sA; eBuff1 = sA+count; break; } else if(find_separately) { sBuff1 = sA; eBuff1 = sA+count; find_separately = 0; } else { sBuff2 = sA; eBuff2 = sA+count; break; } } else if(pull_index == 0 && count > eBuff1-sBuff1) { sBuff1 = sA; eBuff1 = sA+count; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = sA;; } for(last = eB-1, count = 1; count < find; last = index-1, count++) { if(last-sB == 0) index = sB; else { int indexSet = 0; size_t skip = (last-sB)/(find-count); if(!skip) skip = 1; for(index = last-skip; index > sB && !f(array[index-1], array[last]); index -= skip) if(index < sB+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], sB, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[last], index, index+skip, f); } ; if(index == sB) break; } index = last; if(count >= buffer_size) { \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; pull_index = 1; if(count == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB-buffer_size; sBuff2 = eB-buffer_size; eBuff2 = eB; break; } else if(find == buffer_size+buffer_size) { sBuff1 = eB-count; eBuff1 = eB; find = buffer_size; } else if(block_size <= AARRAY_sortCache) { sBuff1 = eB-count; eBuff1 = eB; break; } else if(find_separately) { sBuff1 = eB-count; eBuff1 = eB; find_separately = 0; } else { if(pull[0].sRange == sA) pull[0].eRange -= pull[1].count; sBuff2 = eB-count; eBuff2 = eB; break; } } else if(pull_index == 0 && count > (eBuff1-sBuff1)) { sBuff1 = eB-count; eBuff1 = eB; \ pull[pull_index].sRange = sA; \ pull[pull_index].eRange = eB; \ pull[pull_index].count = count; \ pull[pull_index].from = index; \ pull[pull_index].to = eB;; } } for(pull_index = 0; pull_index < 2; pull_index++) { size_t sRange, eRange; size_t length = pull[pull_index].count; if(pull[pull_index].to < pull[pull_index].from) { index = pull[pull_index].from; for(count = 1; count < length; count++) { size_t index_ = index; if((pull[pull_index].from-(count-1))-pull[pull_index].to == 0) index = pull[pull_index].to; else { int indexSet = 0; size_t skip = ((pull[pull_index].from-(count-1))-pull[pull_index].to)/(length-count); if(!skip) skip = 1; for(index = (pull[pull_index].from-(count-1))-skip; index > pull[pull_index].to && !f(array[index-1], array[index_-1]); index -= skip) if(index < pull[pull_index].to+skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], pull[pull_index].to, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[index_-1], index, index+skip, f); } ; sRange = index+1; eRange = pull[pull_index].from+1; AARRAY_aSortRotate(array, (eRange-sRange)-count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index+count; } } else if(pull[pull_index].to > pull[pull_index].from) { index = pull[pull_index].from+1; for(count = 1; count < length; count++) { if(pull[pull_index].to-index == 0) index = index; else { int indexSet = 0; size_t skip = (pull[pull_index].to-index)/(length-count); if(!skip) skip = 1; for(index = index+skip; !f(array[index], array[index-1]); index += skip) if(index >= pull[pull_index].to-skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index, pull[pull_index].to, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[index], index-skip, index, f); } ; sRange = pull[pull_index].from; eRange = index-1; AARRAY_aSortRotate( array, count, sRange, eRange, cache, AARRAY_sortCache); pull[pull_index].from = index-1-count; } } } buffer_size = eBuff1-sBuff1; block_size = it.decimal_step/buffer_size+1; it.numerator = it.decimal = 0; while(!(it.decimal >= it.size)) { AARRAY_aSortNextRange(array, &it, &sA, &eA); AARRAY_aSortNextRange(array, &it, &sB, &eB); start = sA; if(start == pull[0].sRange) { if(pull[0].from > pull[0].to) { sA += pull[0].count; if(eA-sA == 0) continue; } else if(pull[0].from < pull[0].to) { eB -= pull[0].count; if(eB-sB == 0) continue; } } if(start == pull[1].sRange) { if(pull[1].from > pull[1].to) { sA += pull[1].count; if(eA-sA == 0) continue; } else if(pull[1].from < pull[1].to) { eB -= pull[1].count; if(eB-sB == 0) continue; ; } } if(f(array[eB-1], array[sA])) AARRAY_aSortRotate(array, eA-sA, sA, eB, cache, AARRAY_sortCache); else if(f(array[eA], array[eA-1])) { size_t sBlockA, eBlockA, sFirstA, eFirstA, sLastA, eLastA, sLastB, eLastB, sBlockB, eBlockB; size_t indexA, findA; sBlockA = sA; eBlockA = eA; sFirstA = sA; eFirstA = sA+(eBlockA-sBlockA) % block_size; for(indexA = sBuff1, index = eFirstA; index < eBlockA; indexA++, index += block_size) { int64_t temp = array[indexA]; array[indexA] = array[index]; array[index] = temp; }; sLastA = sFirstA; eLastA = eFirstA; sLastB = 0; eLastB = 0; sBlockB = sB; eBlockB = sB+(block_size < eB-sB? block_size : eB-sB); sBlockA += eFirstA-sFirstA; indexA = sBuff1; if(eLastA-sLastA <= AARRAY_sortCache) memcpy(&cache[0], &array[sLastA], (eLastA-sLastA)*sizeof(array[0])); else if(eBuff2-sBuff2 > 0) for(size_t n = 0; n < eLastA-sLastA; n++) { int64_t temp = array[sLastA+n]; array[sLastA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; if(eBlockA-sBlockA > 0) { while(1) { if((eLastB-sLastB > 0 && !f(array[eLastB-1], array[indexA])) || eBlockB-sBlockB == 0) { size_t B_split = AARRAY_aSortBinaryFirst_LAMBDA( array, array[indexA], sLastB, eLastB, f); size_t B_remaining = eLastB-B_split; size_t minA = sBlockA; for(findA = minA+block_size; findA < eBlockA; findA += block_size) if(f(array[findA], array[minA])) minA = findA; for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[minA+n]; array[minA+n] = temp; }; { int64_t temp = array[sBlockA]; array[sBlockA] = array[indexA]; array[indexA] = temp; }; indexA++; if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, B_split, f, cache); if(eBuff2-sBuff2 > 0 || block_size <= AARRAY_sortCache) { if(block_size <= AARRAY_sortCache) memcpy(&cache[0], &array[sBlockA], block_size*sizeof(array[0])); else for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBuff2+n]; array[sBuff2+n] = temp; }; for(size_t n = 0; n < B_remaining; n++) { int64_t temp = array[B_split+n]; array[B_split+n] = array[sBlockA+block_size-B_remaining+n]; array[sBlockA+block_size-B_remaining+n] = temp; }; } else AARRAY_aSortRotate(array, sBlockA-B_split, B_split, sBlockA+block_size, cache, AARRAY_sortCache); sLastA = sBlockA-B_remaining; eLastA = sBlockA-B_remaining+block_size; sLastB = eLastA; eLastB = eLastA+B_remaining; sBlockA += block_size; if(eBlockA-sBlockA == 0) break; } else if(eBlockB-sBlockB < block_size) { AARRAY_aSortRotate( array, sBlockB-sBlockA, sBlockA, eBlockB, cache, 0); sLastB = sBlockA; eLastB = sBlockA+(eBlockB-sBlockB); sBlockA += eBlockB-sBlockB; eBlockA += eBlockB-sBlockB; eBlockB = sBlockB; } else { for(size_t n = 0; n < block_size; n++) { int64_t temp = array[sBlockA+n]; array[sBlockA+n] = array[sBlockB+n]; array[sBlockB+n] = temp; }; sLastB = sBlockA; eLastB = sBlockA+block_size; sBlockA += block_size; eBlockA += block_size; sBlockB += block_size; if(eBlockB > eB-block_size) eBlockB = eB; else eBlockB += block_size; } } } if(eLastA-sLastA <= AARRAY_sortCache) AARRAY_aSortMergeExternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); else if(eBuff2-sBuff2 > 0) AARRAY_aSortMergeInternal_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, sBuff2); else AARRAY_aSortMergeInPlace_LAMBDA( array, sLastA, eLastA, eLastA, eB, f, cache); } } // insertion sort size_t i, j; for(i = sBuff2+1; i < eBuff2; i++) { const int64_t temp = array[i]; for(j = i; j > sBuff2 && f(temp, array[j-1]); j--) array[j] = array[j-1]; array[j] = temp; } for(pull_index = 0; pull_index < 2; pull_index++) { size_t amount, unique = pull[pull_index].count*2; if(pull[pull_index].from > pull[pull_index].to) { size_t sBuff = pull[pull_index].sRange, eBuff = pull[pull_index].sRange+pull[pull_index].count; while(eBuff-sBuff > 0) { if(pull[pull_index].eRange-eBuff == 0) index = eBuff; else { int indexSet = 0; size_t skip = (pull[pull_index].eRange-eBuff)/(unique); if(!skip) skip = 1; for(index = eBuff+skip; f(array[index-1], array[sBuff]); index += skip) if(index >= pull[pull_index].eRange-skip) { index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index, pull[pull_index].eRange, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryFirst_LAMBDA(array, array[sBuff], index-skip, index, f); } ; amount = index-eBuff; AARRAY_aSortRotate(array, eBuff-sBuff, sBuff, index, cache, AARRAY_sortCache); sBuff += (amount+1); eBuff += amount; unique -= 2; } } else if(pull[pull_index].from < pull[pull_index].to) { size_t sBuff = pull[pull_index].eRange-pull[pull_index].count, eBuff = pull[pull_index].eRange; while(eBuff-sBuff > 0) { if(sBuff-pull[pull_index].sRange == 0) index = pull[pull_index].sRange; else { int indexSet = 0; size_t skip = (sBuff-pull[pull_index].sRange)/(unique); if(!skip) skip = 1; for(index = sBuff-skip; index > pull[pull_index].sRange && f(array[eBuff-1], array[index-1]); index -= skip) if(index < pull[pull_index].sRange+skip) { index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], pull[pull_index].sRange, index, f); indexSet = 1; break; } if(!indexSet) index = AARRAY_aSortBinaryLast_LAMBDA(array, array[eBuff-1], index, index+skip, f); }; amount = sBuff-index; AARRAY_aSortRotate( array, amount, index, eBuff, cache, AARRAY_sortCache); sBuff -= amount; eBuff -= (amount+1); unique -= 2; } } } } if(!AARRAY_aSortNextLevel(array, &it)) break; } return array; }) static void(*const AARRAY_sort_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_sort_LAMBDA_int8_t, (void(*)(void))&AARRAY_sort_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_sort_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_sort_LAMBDA_int64_t }; #define aSortF_LAMBDA(vec, f) \ (AARRAY_typeof(vec, (uint64_t*(*)(void*, \ std::function<int(int64_t,int64_t)>)) \ AARRAY_sort_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ ((void*)vec, (std::function<int(int64_t,int64_t)>)f)) #endif # 17119 "./aArray.h" // our own shmancy algorithm, to make your life more enjoyable AARRAY_define(int8_t AARRAY_searchCompare__int8_t(int8_t a, int8_t b), { return a-b; }) AARRAY_define(int16_t AARRAY_searchCompare__int16_t(int16_t a, int16_t b), { return a-b; }) AARRAY_define(int32_t AARRAY_searchCompare__int32_t(int32_t a, int32_t b), { return a-b; }) AARRAY_define(int64_t AARRAY_searchCompare__int64_t(int64_t a, int64_t b), { return a-b; }) static void(*const AARRAY_searchCompare__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_searchCompare__int8_t, (void(*)(void))&AARRAY_searchCompare__int16_t, 0, (void(*)(void))&AARRAY_searchCompare__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_searchCompare__int64_t }; AARRAY_define(int AARRAY_binary10_FUNC_int8_t( int8_t*vec, size_t*index, int8_t key, int8_t(*f)(int8_t,int8_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int8_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_FUNC_int16_t( int16_t*vec, size_t*index, int16_t key, int16_t(*f)(int16_t,int16_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int16_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_FUNC_int32_t( int32_t*vec, size_t*index, int32_t key, int32_t(*f)(int32_t,int32_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int32_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_FUNC_int64_t( int64_t*vec, size_t*index, int64_t key, int64_t(*f)(int64_t,int64_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int64_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) static void(*const AARRAY_binary10_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_binary10_FUNC_int8_t, (void(*)(void))&AARRAY_binary10_FUNC_int16_t, 0, (void(*)(void))&AARRAY_binary10_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_binary10_FUNC_int64_t }; AARRAY_define(int AARRAY_pingpong_FUNC_int8_t( int8_t*vec, size_t*index, int8_t key, int8_t(*f)(int8_t,int8_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int8_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_FUNC_int16_t( int16_t*vec, size_t*index, int16_t key, int16_t(*f)(int16_t,int16_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int16_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_FUNC_int32_t( int32_t*vec, size_t*index, int32_t key, int32_t(*f)(int32_t,int32_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int32_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_FUNC_int64_t( int64_t*vec, size_t*index, int64_t key, int64_t(*f)(int64_t,int64_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int64_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) static void(*const AARRAY_pingpong_FUNC_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_pingpong_FUNC_int8_t, (void(*)(void))&AARRAY_pingpong_FUNC_int16_t, 0, (void(*)(void))&AARRAY_pingpong_FUNC_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_pingpong_FUNC_int64_t }; #define aSearch(vec, index, key) \ ((int(*)(void*, size_t*, uint64_t, void(*)(void))) \ AARRAY_binary10_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, \ (void(*)(void))AARRAY_searchCompare__FUNCTIONS[sizeof(*vec)-1]) #define aSearchF_FUNC(vec, index, key, f) \ ((int(*)(void*, size_t*, uint64_t, void(*)(void))) \ AARRAY_binary10_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, (void(*)(void))f) #define aSearchF_ALT_FUNC(vec, index, key, f) \ ((int(*)(void*, size_t*, uint64_t, void(*)(void))) \ AARRAY_pingpong_FUNC_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, (void(*)(void))f) #if __has_extension(blocks) AARRAY_define(int AARRAY_binary10_BLOCK_int8_t( int8_t*vec, size_t*index, int8_t key, int8_t(^f)(int8_t,int8_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int8_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_BLOCK_int16_t( int16_t*vec, size_t*index, int16_t key, int16_t(^f)(int16_t,int16_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int16_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_BLOCK_int32_t( int32_t*vec, size_t*index, int32_t key, int32_t(^f)(int32_t,int32_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int32_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_BLOCK_int64_t( int64_t*vec, size_t*index, int64_t key, int64_t(^f)(int64_t,int64_t)), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int64_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) static void(*const AARRAY_binary10_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_binary10_BLOCK_int8_t, (void(*)(void))&AARRAY_binary10_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_binary10_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_binary10_BLOCK_int64_t }; AARRAY_define(int AARRAY_pingpong_BLOCK_int8_t( int8_t*vec, size_t*index, int8_t key, int8_t(^f)(int8_t,int8_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int8_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_BLOCK_int16_t( int16_t*vec, size_t*index, int16_t key, int16_t(^f)(int16_t,int16_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int16_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_BLOCK_int32_t( int32_t*vec, size_t*index, int32_t key, int32_t(^f)(int32_t,int32_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int32_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_BLOCK_int64_t( int64_t*vec, size_t*index, int64_t key, int64_t(^f)(int64_t,int64_t)), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int64_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) static void(*const AARRAY_pingpong_BLOCK_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_pingpong_BLOCK_int8_t, (void(*)(void))&AARRAY_pingpong_BLOCK_int16_t, 0, (void(*)(void))&AARRAY_pingpong_BLOCK_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_pingpong_BLOCK_int64_t }; #define aSearchF_BLOCK(vec, index, key, f) \ ((int(*)(void*, size_t*, uint64_t, void*)) \ AARRAY_binary10_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, (void*)f) #define aSearchF_ALT_BLOCK(vec, index, key, f) \ ((int(*)(void*, size_t*, uint64_t, void*)) \ AARRAY_pingpong_BLOCK_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, (void*)f) #endif # 17397 "./aArray.h" #if defined(__cplusplus) AARRAY_define(int AARRAY_binary10_LAMBDA_int8_t( int8_t*vec, size_t*index, int8_t key, std::function<int8_t(int8_t, int8_t)>f), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int8_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_LAMBDA_int16_t( int16_t*vec, size_t*index, int16_t key, std::function<int16_t(int16_t, int16_t)>f), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int16_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_LAMBDA_int32_t( int32_t*vec, size_t*index, int32_t key, std::function<int32_t(int32_t, int32_t)>f), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int32_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) AARRAY_define(int AARRAY_binary10_LAMBDA_int64_t( int64_t*vec, size_t*index, int64_t key, std::function<int64_t(int64_t, int64_t)>f), { size_t min = 0, mid = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // protect initial lookups while(min < max) { mid = (min + max) >> 1; // potential integer overflow int64_t cmp = f(key, vec[mid]); if(cmp == 0) { *index = mid; return 1; } if(cmp < 0) max = mid; else min = ++mid; } *index = mid; return 0; }) static void(*const AARRAY_binary10_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_binary10_LAMBDA_int8_t, (void(*)(void))&AARRAY_binary10_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_binary10_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_binary10_LAMBDA_int64_t }; AARRAY_define(int AARRAY_pingpong_LAMBDA_int8_t( int8_t*vec, size_t*index, int8_t key, std::function<int8_t(int8_t, int8_t)>f), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int8_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_LAMBDA_int16_t( int16_t*vec, size_t*index, int16_t key, std::function<int16_t(int16_t, int16_t)>f), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int16_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_LAMBDA_int32_t( int32_t*vec, size_t*index, int32_t key, std::function<int32_t(int32_t, int32_t)>f), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int32_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) AARRAY_define(int AARRAY_pingpong_LAMBDA_int64_t( int64_t*vec, size_t*index, int64_t key, std::function<int64_t(int64_t, int64_t)>f), { size_t min = 0, max = aLength(vec); if(!max) { *index = 0; return 0; } // start secant 1/8th of the way into the array, because why not size_t a = min+(max>>3), b = max-1-(max>>3), c; int64_t fa = f(key, vec[a]), fb = f(key, vec[b]); while(min < max) { // divide by non-zero? interpolate : bisect c = fb-fa? (size_t)(b - fb * (double)(b-a) / (fb-fa)) : max-((max-min)>>1); // keep the pingpong ball on the table a = b; b = c < min ? min : c >= max ? max-1 : c; fa = fb; fb = f(key, vec[b]); if(fb > 0) min = b+1; else max = b; if(fb == 0) { *index = b; return 1; } } *index = max; return 0; }) static void(*const AARRAY_pingpong_LAMBDA_FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_pingpong_LAMBDA_int8_t, (void(*)(void))&AARRAY_pingpong_LAMBDA_int16_t, 0, (void(*)(void))&AARRAY_pingpong_LAMBDA_int32_t, 0, 0, 0, (void(*)(void))&AARRAY_pingpong_LAMBDA_int64_t }; #define aSearchF_LAMBDA(vec, index, key, f) \ ((int(*)(void*, size_t*, uint64_t, \ std::function<uint64_t(uint64_t,uint64_t)>)) \ AARRAY_binary10_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, \ (std::function<uint64_t(uint64_t,uint64_t)>)f) #define aSearchF_ALT_LAMBDA(vec, index, key, f) \ ((int(*)(void*, size_t*, uint64_t, \ std::function<uint64_t(uint64_t,uint64_t)>)) \ AARRAY_pingpong_LAMBDA_FUNCTIONS[sizeof(*vec)-1]) \ (vec, index, (uint64_t)key, \ (std::function<uint64_t(uint64_t,uint64_t)>)f) #endif # 17529 "./aArray.h" #if !defined(AARRAY_NOCONVENIENCE) #if __has_extension(blocks) #define aMap aMap_BLOCK #define aFilter aFilter_BLOCK #define aFold aFold_BLOCK #define aLoop aLoop_BLOCK #define aSortF aSortF_BLOCK #define aSearchF aSearchF_BLOCK #define aSearchF_ALT aSearchF_ALT_BLOCK #elif defined(__cplusplus) # 17543 "./aArray.h" #define aMap aMap_LAMBDA #define aFilter aFilter_LAMBDA #define aFold aFold_LAMBDA #define aLoop aLoop_LAMBDA #define aSortF aSortF_LAMBDA #define aSearchF aSearchF_LAMBDA #define aSearchF_ALT aSearchF_ALT_LAMBDA #else # 17551 "./aArray.h" #define aMap aMap_FUNC #define aFilter aFilter_FUNC #define aFold aFold_FUNC #define aLoop aLoop_FUNC #define aSortF aSortF_FUNC #define aSearchF aSearchF_FUNC #define aSearchF_ALT aSearchF_ALT_FUNC #endif # 17559 "./aArray.h" #endif # 17560 "./aArray.h" //// api to quickly print arrays without '\0' endings AARRAY_define(int AARRAY_Write__int8_t( char errLoc[], FILE*file, size_t vecsCount, uintptr_t vecs[]), { AARRAY_safety((void)errLoc, if(!file) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n] && *((size_t*)vecs[n]-1) > fwrite((void*)vecs[n], sizeof(int8_t), *((size_t*)vecs[n]-1), file)) return -1; return 0; }) AARRAY_define(int AARRAY_Write__int16_t( char errLoc[], FILE*file, size_t vecsCount, uintptr_t vecs[]), { AARRAY_safety((void)errLoc, if(!file) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n] && *((size_t*)vecs[n]-1) > fwrite((void*)vecs[n], sizeof(int16_t), *((size_t*)vecs[n]-1), file)) return -1; return 0; }) AARRAY_define(int AARRAY_Write__int32_t( char errLoc[], FILE*file, size_t vecsCount, uintptr_t vecs[]), { AARRAY_safety((void)errLoc, if(!file) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n] && *((size_t*)vecs[n]-1) > fwrite((void*)vecs[n], sizeof(int32_t), *((size_t*)vecs[n]-1), file)) return -1; return 0; }) AARRAY_define(int AARRAY_Write__int64_t( char errLoc[], FILE*file, size_t vecsCount, uintptr_t vecs[]), { AARRAY_safety((void)errLoc, if(!file) AARRAY_Error_NullParameter); size_t n = (size_t)-1; while(++n < vecsCount) if(vecs[n] && *((size_t*)vecs[n]-1) > fwrite((void*)vecs[n], sizeof(int64_t), *((size_t*)vecs[n]-1), file)) return -1; return 0; }) static void(*const AARRAY_Write__FUNCTIONS[8])(void) = { (void(*)(void))&AARRAY_Write__int8_t, (void(*)(void))&AARRAY_Write__int16_t, 0, (void(*)(void))&AARRAY_Write__int32_t, 0, 0, 0, (void(*)(void))&AARRAY_Write__int64_t }; #define AARRAY_ArgsHead(A, ...) A #define aWrite(file, ...) \ ((int(*)(char[], FILE*, size_t, uintptr_t[])) \ AARRAY_Write__FUNCTIONS[sizeof(*AARRAY_ArgsHead(__VA_ARGS__, NULL))-1]) \ (AARRAY_LINE, file, \ AARRAY_nowarn_internal_start AARRAY_nowarn_internal_start \ sizeof((uintptr_t[]){(uintptr_t)__VA_ARGS__}) / sizeof(uintptr_t), \ (uintptr_t*)AARRAY_move((uintptr_t[]){(uintptr_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end \ AARRAY_nowarn_internal_end) //// api to emulate printf for arrays AARRAY_define(void AARRAY_percent_parse( char errLoc[], const char fmt[], size_t*pptr, char*pspecifier, unsigned long*pnum1, unsigned long*pnum2, size_t*pstart, size_t*pend, size_t*doublePercent), { // get parser values char specifier = *pspecifier; unsigned long num1 = *pnum1, num2 = *pnum2; size_t start = *pstart; size_t end = *pend; size_t ptr = *pptr; while(1) { if(fmt[ptr] == '\0') { end = ptr; specifier = 'e'; break; } else if(0==strncmp(fmt+ptr, "%v", 2)) { end = ptr; ptr = start = ptr+2; specifier = 'v'; break; } else if(0==strncmp(fmt+ptr, "%s", 2)) { end = ptr; ptr = start = ptr+2; specifier = 's'; break; } else if(0==strncmp(fmt+ptr, "%c", 2)) { end = ptr; ptr = start = ptr+2; specifier = 'c'; break; } else if(0==strncmp(fmt+ptr, "%%", 2)) { end = ptr; ptr = start = ptr+2; *doublePercent = ptr; specifier = '%'; break; } else if(fmt[ptr] == '%') { end = ptr; ptr++; size_t ptr_start = ptr; AARRAY_safety((void)errLoc;, if(fmt[ptr]=='\0') AARRAY_Error_FormatStringMalformed); num1 = 0; num2 = 0; // get base to print number in char num_str[] = "10"; while(fmt[ptr] >= '0' && fmt[ptr] <= '9') ptr++; AARRAY_safety(, if(ptr-ptr_start > 2) AARRAY_Error_FormatStringMalformed else) if(ptr != ptr_start) { num_str[0] = fmt[ptr_start]; num_str[1] = (ptr != ptr_start+1 ? fmt[ptr_start+1] : '\0'); num1 = strtoul(num_str, NULL, 10); } else num1 = 10; // get number's type specifier = fmt[ptr++]; AARRAY_safety(, if((specifier != 'i' && specifier != 'u' && specifier != 'f' && specifier != 'd') || (num1 < 2 || num1 > 64)) AARRAY_Error_FormatStringMalformed); // get number's bit width if(specifier == 'i' || specifier == 'u') { if(0==strncmp(fmt+ptr, "ll", 2)) { num2 = sizeof(long long)*8; ptr+=2; } else if(0==strncmp(fmt+ptr, "16", 2)) { num2 = 16; ptr+=2; } else if(0==strncmp(fmt+ptr, "32", 2)) { num2 = 32; ptr+=2; } else if(0==strncmp(fmt+ptr, "64", 2)) { num2 = 64; ptr+=2; } else switch(fmt[ptr]) { case 'c': case '8': num2 = sizeof(char)*8; ptr++; break; case 's': num2 = sizeof(short)*8; ptr++; break; case 'i': num2 = sizeof(int)*8; ptr++; break; case 'l': num2 = sizeof(long)*8; ptr++; break; case 'z': num2 = sizeof(size_t)*8; ptr++; break; case 'm': num2 = sizeof(intmax_t)*8; ptr++; break; case 'p': num2 = sizeof(intptr_t)*8; ptr++; break; default: num2 = sizeof(int)*8; } } else if(specifier == 'f'){ num2 = sizeof(float)*8; } else if(specifier == 'd'){ num2 = sizeof(double)*8; } else { AARRAY_safety(, AARRAY_Error_FormatStringMalformed); } AARRAY_safety(,if(!num2) AARRAY_Error_FormatStringMalformed); // we only parse floats, not yet done code to print them... //AARRAY_safety(, if(specifier == 'f') // AARRAY_Error_FormatStringMalformed); start = ptr; break; } ptr++; } // return parser values *pspecifier = specifier; *pnum1 = num1; *pnum2 = num2; *pend = end; *pstart = start; *pptr = ptr; }) static const char AARRAY_baseChars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUaWXYZ._"; AARRAY_define(void AARRAY_u_to_str( uintmax_t value, char str[(8 * sizeof(uintmax_t))+1], unsigned long base), { char*walkstr=str; // validate base if(base<2 || base>64) base = 10; // reverse number do *walkstr++ = AARRAY_baseChars[value%base]; while(value/=base); *walkstr='\0'; char aux; while(--walkstr>str) aux=*walkstr, *walkstr=*str, *str++=aux; }) AARRAY_define(void AARRAY_i_to_str( intmax_t value, char str[(8 * sizeof(uintmax_t))+1], unsigned long base), { char*walkstr=str; // validate base if(base<2 || base>64) base = 10; uint8_t sign = value < 0; if(sign) value = -value; // reverse number do *walkstr++ = AARRAY_baseChars[value%(int)base]; while(value/=base); if(sign) *walkstr++ = '-'; else *walkstr++ = '+'; *walkstr='\0'; char aux; while(--walkstr>str) aux=*walkstr, *walkstr=*str, *str++=aux; }) // cppp let Fmt be defined once, but output to both streams and arrays AARRAY_define(int AARRAY_Fmt_File(char errLoc[], FILE* fmtOut, size_t vecCount, uint64_t vec[]), { AARRAY_safety(, if(!fmtOut) AARRAY_Error_NullParameter); size_t ptr= 0, prevStart = 0, start = 0, end = 0, vc = 0; char specifier = 0; size_t doublePercent; unsigned long num1, num2; if(!vecCount) return 0; char*fmt = (char*)vec[vc++]; AARRAY_safety(, if(!fmt) AARRAY_Error_NullParameter ); // big enough for binary INTMAX_MAX char buffer[(8 * sizeof(intmax_t))+1]; while(1) { prevStart = start; AARRAY_percent_parse(errLoc, fmt, &ptr, &specifier, &num1, &num2, &start, &end, &doublePercent); if(end-prevStart < fwrite(fmt+prevStart, sizeof(char), end-prevStart, fmtOut)) return -1; switch(specifier) { case 'e': return 0; case '%': { if(EOF==fputc('%', fmtOut)) return -1; break; } case 's': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_safety(, if(!vec[vc]) AARRAY_Error_NullParameter) if(EOF==fputs((char*)vec[vc], fmtOut)) return -1; break; } case 'c': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); if(EOF==fputc((char)vec[vc], fmtOut)) return -1; break; } case 'u': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_u_to_str((num2==8? (uint8_t)vec[vc] : (num2==16? (uint16_t)vec[vc] : (num2==32? (uint32_t)vec[vc] :(uint64_t)vec[vc]))), buffer, num1); if(EOF==fputs(buffer, fmtOut)) return -1; break; } case 'i': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_i_to_str((num2==8? (int8_t)(uint8_t)vec[vc] : (num2==16? (int16_t)(uint16_t)vec[vc] : (num2==32? (int32_t)(uint32_t)vec[vc] : (int64_t)(uint64_t)vec[vc]))), buffer, num1); if(EOF==fputs(buffer, fmtOut)) return -1; break; } case 'f': case 'd': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); if(EOF==fprintf(fmtOut, "%g", specifier=='f'?(double)*(float*)&vec[vc]:*(double*)&vec[vc])) return -1; break; } case 'v': AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); prevStart = end+2; doublePercent = 0; do { AARRAY_percent_parse(errLoc, fmt, &ptr, &specifier, &num1, &num2, &start, &end, &doublePercent); } while(specifier == '%'); AARRAY_safety(, if(specifier=='e' || specifier=='v') AARRAY_Error_FormatStringMalformed); size_t nn = (size_t)-1; while(++nn < aLength((uintptr_t*)(vec[vc]))) { if(nn) { // resolving %% to % is a pain, since we now have to // loop through %v's separator again, doing the conversion if(doublePercent) { size_t ptr2 = prevStart; while(ptr2 < doublePercent) switch(fmt[ptr2]) { case '%': ptr2+=2; fputc('%', fmtOut); break; default: fputc(fmt[ptr2++], fmtOut); } prevStart = doublePercent; } if(end-prevStart <fwrite(fmt+prevStart, sizeof(char), end-prevStart, fmtOut)) return -1; } switch(specifier) { case '%': { if(EOF==fputc('%', fmtOut)) return -1; break; } case 's': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_safety(, if(!vec[vc]) AARRAY_Error_NullParameter) if(EOF==fputs(((char**)vec[vc])[nn], fmtOut)) return -1; break; } case 'c': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); if(EOF==fputc(((char*)vec[vc])[nn], fmtOut)) return -1; break; } case 'u': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_u_to_str((num2==8? ((uint8_t*)vec[vc])[nn] : (num2==16? ((uint16_t*)vec[vc])[nn] : (num2==32? ((uint32_t*)vec[vc])[nn] :((uint64_t*)vec[vc])[nn]))), buffer, num1); if(EOF==fputs(buffer, fmtOut)) return -1; break; } case 'i': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_i_to_str((num2==8? (int8_t)((uint8_t*)vec[vc])[nn] : (num2==16? (int16_t)((uint16_t*)vec[vc])[nn] : (num2==32? (int32_t)((uint32_t*)vec[vc])[nn] : (int64_t)((uint64_t*)vec[vc])[nn]))), buffer, num1); if(EOF==fputs(buffer, fmtOut)) return -1; break; } case 'f': case 'd': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); if(EOF==fprintf(fmtOut, "%g", specifier=='f'?(double)((float*)vec[vc])[nn]:((double*)vec[vc])[nn])) return -1; break; }; } } break; } vc++; specifier = 0; } return 0; }) AARRAY_define(int AARRAY_Fmt_Array(char errLoc[], char** fmtOut, size_t vecCount, uint64_t vec[]), { AARRAY_safety(, if(!fmtOut) AARRAY_Error_NullParameter); size_t ptr= 0, prevStart = 0, start = 0, end = 0, vc = 0; char specifier = 0; size_t doublePercent; unsigned long num1, num2; if(!vecCount) return 0; char*fmt = (char*)vec[vc++]; AARRAY_safety(, if(!fmt) AARRAY_Error_NullParameter ); // big enough for binary INTMAX_MAX char buffer[(8 * sizeof(intmax_t))+1]; while(1) { prevStart = start; AARRAY_percent_parse(errLoc, fmt, &ptr, &specifier, &num1, &num2, &start, &end, &doublePercent); (void)aAppendArray(fmtOut, end-prevStart, (uintptr_t)AARRAY_move(&fmt[prevStart])); switch(specifier) { case 'e': return 0; case '%': { (void)aAppend(fmtOut, '%'); break; } case 's': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_safety(, if(!vec[vc]) AARRAY_Error_NullParameter) (void)aAppendArray(fmtOut, SIZE_MAX, (uintptr_t)AARRAY_move((char*)vec[vc])); break; } case 'c': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); (void)aAppend(fmtOut, (uint8_t)(char)vec[vc]); break; } case 'u': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_u_to_str((num2==8? (uint8_t)vec[vc] : (num2==16? (uint16_t)vec[vc] : (num2==32? (uint32_t)vec[vc] :(uint64_t)vec[vc]))), buffer, num1); (void)aAppendArray(fmtOut, SIZE_MAX, (uintptr_t)AARRAY_move(buffer)); break; } case 'i': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_i_to_str((num2==8? (int8_t)(uint8_t)vec[vc] : (num2==16? (int16_t)(uint16_t)vec[vc] : (num2==32? (int32_t)(uint32_t)vec[vc] : (int64_t)(uint64_t)vec[vc]))), buffer, num1); (void)aAppendArray(fmtOut, SIZE_MAX, (uintptr_t)AARRAY_move(buffer)); break; } case 'f': case 'd': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); int len = snprintf(*fmtOut, 0, "%g", specifier=='f'?(double)*(float*)&vec[vc]:*(double*)&vec[vc]); // safe to assume no errors from snprintf size_t oldlen = aLength(*fmtOut); (void)aMulti(fmtOut, oldlen, 0, 0, (uintptr_t)len+1, 0); snprintf(&(*fmtOut)[oldlen], (size_t)len+1, "%g", specifier=='f'?(double)*(float*)&vec[vc]:*(double*)&vec[vc]); (void)aZLength2(*fmtOut, 1); break; } case 'v': AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); prevStart = end+2; doublePercent = 0; do { AARRAY_percent_parse(errLoc, fmt, &ptr, &specifier, &num1, &num2, &start, &end, &doublePercent); } while(specifier == '%'); AARRAY_safety(, if(specifier=='e' || specifier=='v') AARRAY_Error_FormatStringMalformed); size_t nn = (size_t)-1; while(++nn < aLength((uintptr_t*)(vec[vc]))) { if(nn) { // resolving %% to % is a pain, since we now have to // loop through %v's separator again, doing the conversion if(doublePercent) { size_t ptr2 = prevStart; while(ptr2 < doublePercent) switch(fmt[ptr2]) { case '%': ptr2+=2; (void)aAppend(fmtOut, '%'); break; default: (void)aAppend(fmtOut, (uint8_t)fmt[ptr2++]); } prevStart = doublePercent; } (void)aAppendArray(fmtOut, end-prevStart, (uintptr_t)AARRAY_move(&fmt[prevStart])); } switch(specifier) { case '%': { (void)aAppend(fmtOut, '%'); break; } case 's': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_safety(, if(!vec[vc]) AARRAY_Error_NullParameter) (void)aAppendArray(fmtOut, SIZE_MAX, (uintptr_t)AARRAY_move(((char**)vec[vc])[nn])); break; } case 'c': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); (void)aAppend(fmtOut, (uint8_t)((char*)vec[vc])[nn]); break; } case 'u': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_u_to_str((num2==8? ((uint8_t*)vec[vc])[nn] : (num2==16? ((uint16_t*)vec[vc])[nn] : (num2==32? ((uint32_t*)vec[vc])[nn] :((uint64_t*)vec[vc])[nn]))), buffer, num1); (void)aAppendArray(fmtOut, SIZE_MAX, (uintptr_t)AARRAY_move(buffer)); break; } case 'i': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); AARRAY_i_to_str((num2==8? (int8_t)((uint8_t*)vec[vc])[nn] : (num2==16? (int16_t)((uint16_t*)vec[vc])[nn] : (num2==32? (int32_t)((uint32_t*)vec[vc])[nn] : (int64_t)((uint64_t*)vec[vc])[nn]))), buffer, num1); (void)aAppendArray(fmtOut, SIZE_MAX, (uintptr_t)AARRAY_move(buffer)); break; } case 'f': case 'd': { AARRAY_safety(, if(vc>=vecCount) AARRAY_Error_FormatStringArgs); int len = snprintf(*fmtOut, 0, "%g", specifier=='f'?(double)((float*)vec[vc])[nn]:((double*)vec[vc])[nn]); // safe to assume no errors from snprintf size_t oldlen = aLength(*fmtOut); (void)aMulti(fmtOut, oldlen, 0, 0, (uintptr_t)len+1, 0); snprintf(&(*fmtOut)[oldlen], (size_t)len+1, "%g", specifier=='f'?(double)((float*)vec[vc])[nn]:((double*)vec[vc])[nn]); (void)aZLength2(*fmtOut, 1); break; }; } } break; } vc++; specifier = 0; } return 0; }) AARRAY_define(int AARRAY_Fmt_Error( char errLoc[], size_t vecCount, uint64_t vec[]), { fflush(stdout); int returnValue = AARRAY_Fmt_File(errLoc, stderr, vecCount, vec); fflush(stderr); return returnValue; }) #define aFmtF(file, ...) AARRAY_Fmt_File (AARRAY_LINE, file, \ AARRAY_nowarn_internal_start \ sizeof((uint64_t[]){(uint64_t)__VA_ARGS__}) / sizeof(uint64_t), \ (uint64_t*)AARRAY_move((uint64_t[]){(uint64_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end) #define aFmt(...) AARRAY_Fmt_File (AARRAY_LINE, stdout, \ AARRAY_nowarn_internal_start \ sizeof((uint64_t[]){(uint64_t)__VA_ARGS__}) / sizeof(uint64_t), \ (uint64_t*)AARRAY_move((uint64_t[]){(uint64_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end) #define aFmtE(...) AARRAY_Fmt_Error(AARRAY_LINE, \ AARRAY_nowarn_internal_start \ sizeof((uint64_t[]){(uint64_t)__VA_ARGS__}) / sizeof(uint64_t), \ (uint64_t*)AARRAY_move((uint64_t[]){(uint64_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end) #define aFmtA(array, ...) AARRAY_Fmt_Array(AARRAY_LINE, array, \ AARRAY_nowarn_internal_start \ sizeof((uint64_t[]){(uint64_t)__VA_ARGS__}) / sizeof(uint64_t), \ (uint64_t*)AARRAY_move((uint64_t[]){(uint64_t)__VA_ARGS__}) \ AARRAY_nowarn_internal_end) #if !defined(AARRAY_NOCONVENIENCE) #define aA aAppend #define aR aReplace #define aAA aAppendArray #define aRA aReplaceArray #define aD aDelete #define aC aConcat #define aM aMulti #define aL aLength #define aL2 aLength2 #define aZL2 aZLength2 #define aF aFmt #define aFE aFmtE #define aFF aFmtF #define aFA aFmtA #define aW aWrite #define aStr(string) aAppendArray((char**)NULL, SIZE_MAX, (uintptr_t)string) #endif # 18030 "./aArray.h" #if defined(__cplusplus) AARRAY_nowarn_pedantic_cpp_end #endif # 18034 "./aArray.h" #endif # 18036 "./aArray.h" # 14 "./helpers.h" 2 extern char*error_text; #define OOM(_var, _size) _var = malloc(sizeof(_size)); if(!_var) panic("out of memory"); #define oom(_var) ({ if(!_var) panic("out of memory"); }) //// windows abort gets uppity -- shouldn't use abort anywhere #define panic(...) ({ fflush(stdout); aFE(error_text); aFE(__VA_ARGS__); aFE("\n"); exit(1); }) // hashmap store for strings void name_init(); void name_free(); char*string_to_name(char*ptr, size_t name_len); char*name_to_string(char**name); // is marked test for algorithms bool mark_test(void*m); void mark_set (void*m); void mark_init(void(*root_walker)(void(*f)(void*))); // dynamic library loading void*library_open(char*path, bool showError); void library_close(void*lib, bool); void*library_read(void*lib, char*name, bool); // stack backtrace char*printbacktrace(); # 12 "core.c" 2 #if 0 #include "core.h" #endif # 12 "core.c" # 1 "./core.h" 1 #if 0 #pragma once #endif # 9 "./core.h" #if 0 #include <fcntl.h> #endif # 10 "./core.h" # 1 "/usr/include/fcntl.h" 1 3 4 #ifndef _SYS_FCNTL_H_ #define _SYS_FCNTL_H_ #if 0 #include <sys/cdefs.h> #endif # 41 "/usr/include/fcntl.h" 3 4 # 42 "/usr/include/fcntl.h" 3 4 #ifndef _SYS_TYPES_H_ #if 0 #include <sys/types.h> #endif # 43 "/usr/include/fcntl.h" 3 4 # 44 "/usr/include/fcntl.h" 3 4 #endif # 45 "/usr/include/fcntl.h" 3 4 #define O_RDONLY 0x0000 #define O_WRONLY 0x0001 #define O_RDWR 0x0002 #define O_ACCMODE 0x0003 #if __BSD_VISIBLE #define FREAD 0x0001 #define FWRITE 0x0002 #endif # 71 "/usr/include/fcntl.h" 3 4 #define O_NONBLOCK 0x0004 #define O_APPEND 0x0008 #if __BSD_VISIBLE #define O_SHLOCK 0x0010 #define O_EXLOCK 0x0020 #define O_ASYNC 0x0040 #define O_FSYNC 0x0080 #endif # 79 "/usr/include/fcntl.h" 3 4 #define O_SYNC 0x0080 #if __POSIX_VISIBLE >= 200809 #define O_NOFOLLOW 0x0100 #endif # 83 "/usr/include/fcntl.h" 3 4 #define O_CREAT 0x0200 #define O_TRUNC 0x0400 #define O_EXCL 0x0800 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) #define FMARK 0x1000 #define FDEFER 0x2000 #define FHASLOCK 0x4000 #endif # 91 "/usr/include/fcntl.h" 3 4 #define O_NOCTTY 0x8000 #if __BSD_VISIBLE #define O_DIRECT 0x00010000 #endif # 99 "/usr/include/fcntl.h" 3 4 #if __POSIX_VISIBLE >= 200809 #define O_CLOEXEC 0x00020000 #endif # 103 "/usr/include/fcntl.h" 3 4 #define O_FBLOCKING 0x00040000 #define O_FNONBLOCKING 0x00080000 #define O_FAPPEND 0x00100000 #define O_FOFFSET 0x00200000 #define O_FSYNCWRITE 0x00400000 #define O_FASYNCWRITE 0x00800000 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) #define O_UNUSED24 0x01000000 #define O_UNUSED25 0x02000000 #define O_UNUSED26 0x04000000 #endif # 114 "/usr/include/fcntl.h" 3 4 #if __POSIX_VISIBLE >= 200809 #define O_DIRECTORY 0x08000000 #endif # 118 "/usr/include/fcntl.h" 3 4 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) #define FREVOKED 0x10000000 #define FAPPENDONLY 0x20000000 #define FOFFSETLOCK 0x40000000 #define FOFFSETWAKE 0x80000000 #endif # 125 "/usr/include/fcntl.h" 3 4 #define O_FMASK (O_FBLOCKING|O_FNONBLOCKING|O_FAPPEND|O_FOFFSET|\ O_FSYNCWRITE|O_FASYNCWRITE) #ifdef _KERNEL #define FFLAGS(oflags) ((oflags) + 1) #define OFLAGS(fflags) ((fflags) - 1) #define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK|\ FAPPENDONLY|FREVOKED|O_DIRECT) #define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FPOSIXSHM|\ O_DIRECT) #endif # 143 "/usr/include/fcntl.h" 3 4 #if __BSD_VISIBLE #define FAPPEND O_APPEND #define FASYNC O_ASYNC #define FFSYNC O_FSYNC #define FNONBLOCK O_NONBLOCK #define FNDELAY O_NONBLOCK #define O_NDELAY O_NONBLOCK #endif # 157 "/usr/include/fcntl.h" 3 4 #if __BSD_VISIBLE #define FPOSIXSHM O_NOFOLLOW #endif # 173 "/usr/include/fcntl.h" 3 4 #if __POSIX_VISIBLE >= 200809 #define AT_FDCWD 0xFFFAFDCD #define AT_SYMLINK_NOFOLLOW 1 #define AT_REMOVEDIR 2 #define AT_EACCESS 4 #define AT_SYMLINK_FOLLOW 8 #endif # 184 "/usr/include/fcntl.h" 3 4 #define F_DUPFD 0 #define F_GETFD 1 #define F_SETFD 2 #define F_GETFL 3 #define F_SETFL 4 #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112 #define F_GETOWN 5 #define F_SETOWN 6 #endif # 199 "/usr/include/fcntl.h" 3 4 #define F_GETLK 7 #define F_SETLK 8 #define F_SETLKW 9 #if __BSD_VISIBLE #define F_DUP2FD 10 #endif # 205 "/usr/include/fcntl.h" 3 4 #if __POSIX_VISIBLE >= 200809 #define F_DUPFD_CLOEXEC 17 #endif # 208 "/usr/include/fcntl.h" 3 4 #if __BSD_VISIBLE #define F_DUP2FD_CLOEXEC 18 #endif # 211 "/usr/include/fcntl.h" 3 4 #define FD_CLOEXEC 1 #define F_RDLCK 1 #define F_UNLCK 2 #define F_WRLCK 3 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) #define F_WAIT 0x010 #define F_UNUSED020 0x020 #define F_POSIX 0x040 #define F_NOEND 0x080 #endif # 225 "/usr/include/fcntl.h" 3 4 struct flock { off_t l_start; off_t l_len; pid_t l_pid; short l_type; short l_whence; }; #ifdef _KERNEL union fcntl_dat { int fc_fd; int fc_cloexec; int fc_flags; int fc_owner; struct flock fc_flock; }; #endif # 248 "/usr/include/fcntl.h" 3 4 #if __BSD_VISIBLE #define LOCK_SH 0x01 #define LOCK_EX 0x02 #define LOCK_NB 0x04 #define LOCK_UN 0x08 #endif # 257 "/usr/include/fcntl.h" 3 4 #ifndef SEEK_SET #define SEEK_SET 0 #endif # 262 "/usr/include/fcntl.h" 3 4 #ifndef SEEK_CUR #define SEEK_CUR 1 #endif # 265 "/usr/include/fcntl.h" 3 4 #ifndef SEEK_END #define SEEK_END 2 #endif # 268 "/usr/include/fcntl.h" 3 4 #ifndef S_ISUID #define S_ISUID 0004000 #endif # 273 "/usr/include/fcntl.h" 3 4 #ifndef S_ISGID #define S_ISGID 0002000 #endif # 276 "/usr/include/fcntl.h" 3 4 #ifndef S_IRWXU #define S_IRWXU 0000700 #endif # 279 "/usr/include/fcntl.h" 3 4 #ifndef S_IRUSR #define S_IRUSR 0000400 #endif # 282 "/usr/include/fcntl.h" 3 4 #ifndef S_IWUSR #define S_IWUSR 0000200 #endif # 285 "/usr/include/fcntl.h" 3 4 #ifndef S_IXUSR #define S_IXUSR 0000100 #endif # 288 "/usr/include/fcntl.h" 3 4 #ifndef S_IRWXG #define S_IRWXG 0000070 #endif # 291 "/usr/include/fcntl.h" 3 4 #ifndef S_IRGRP #define S_IRGRP 0000040 #endif # 294 "/usr/include/fcntl.h" 3 4 #ifndef S_IWGRP #define S_IWGRP 0000020 #endif # 297 "/usr/include/fcntl.h" 3 4 #ifndef S_IXGRP #define S_IXGRP 0000010 #endif # 300 "/usr/include/fcntl.h" 3 4 #ifndef S_IRWXO #define S_IRWXO 0000007 #endif # 303 "/usr/include/fcntl.h" 3 4 #ifndef S_IROTH #define S_IROTH 0000004 #endif # 306 "/usr/include/fcntl.h" 3 4 #ifndef S_IWOTH #define S_IWOTH 0000002 #endif # 309 "/usr/include/fcntl.h" 3 4 #ifndef S_IXOTH #define S_IXOTH 0000001 #endif # 312 "/usr/include/fcntl.h" 3 4 #if !defined(_KERNEL) && __POSIX_VISIBLE >= 200112 #define POSIX_FADV_NORMAL 0 #define POSIX_FADV_SEQUENTIAL 1 #define POSIX_FADV_RANDOM 2 #define POSIX_FADV_WILLNEED 3 #define POSIX_FADV_DONTNEED 4 #define POSIX_FADV_NOREUSE 5 #endif # 325 "/usr/include/fcntl.h" 3 4 #if !defined(_KERNEL) || defined(_KERNEL_VIRTUAL) __BEGIN_DECLS int open(const char *, int, ...); #if __POSIX_VISIBLE >= 200809 int openat(int, const char *, int, ...); #endif # 332 "/usr/include/fcntl.h" 3 4 int creat(const char *, mode_t); int fcntl(int, int, ...); #if __BSD_VISIBLE int flock(int, int); #endif # 337 "/usr/include/fcntl.h" 3 4 #if __POSIX_VISIBLE >= 200112 int posix_fadvise(int, off_t, off_t, int); #if 0 int posix_fallocate(int, off_t, off_t); #endif # 342 "/usr/include/fcntl.h" 3 4 #endif # 343 "/usr/include/fcntl.h" 3 4 __END_DECLS #endif # 345 "/usr/include/fcntl.h" 3 4 #endif # 347 "/usr/include/fcntl.h" 3 4 # 11 "./core.h" 2 #if 0 #include "assert.h" #endif # 11 "./core.h" # 1 "/usr/include/assert.h" 1 3 4 #if 0 #include <sys/cdefs.h> #endif # 40 "/usr/include/assert.h" 3 4 # 41 "/usr/include/assert.h" 3 4 #undef assert #undef _assert #ifdef NDEBUG #define assert(e) ((void)0) #define _assert(e) ((void)0) #else # 54 "/usr/include/assert.h" 3 4 #define _assert(e) assert(e) #define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \ __LINE__, #e)) #endif # 59 "/usr/include/assert.h" 3 4 #undef _DIAGASSERT #ifdef _DIAGNOSTIC #define _DIAGASSERT(e) ((e) ? (void)0 : __diagassert(__FILE__, __LINE__, \ __func__, #e)) #else # 65 "/usr/include/assert.h" 3 4 #define _DIAGASSERT(e) ((void)0) #endif # 67 "/usr/include/assert.h" 3 4 #ifndef _ASSERT_H_ #define _ASSERT_H_ #if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus) #define static_assert _Static_assert #endif # 83 "/usr/include/assert.h" 3 4 __BEGIN_DECLS void __assert(const char *, const char *, int, const char *) __dead2; void __diagassert(const char *, int, const char *, const char *); __END_DECLS #endif # 90 "/usr/include/assert.h" 3 4 # 12 "./core.h" 2 #define AARRAY_h #if 0 #include "aArray.h" #endif # 13 "./core.h" # 14 "./core.h" #if 0 #include "helpers.h" #endif # 14 "./core.h" # 15 "./core.h" typedef enum { m_literal, // builtins can create literal data m_intake, // intakes are parameters: function define(intake) {...}(value) m_frame, // function-call holders for 'return_ptr' and 'code_ptr' m_define, m_builtin, m_give, // explicit function-return m_error // poison errors, so we only report them once } m_type; typedef struct define define; typedef struct id { // represent every expression in moses size_t mark; // see helpers.c -- a generic algorithm marker m_type type; char*name; char*name_ptr; // name's location in moses sourcecode // absolute depth of intakes and defines in scope // so not deBruijin indexing; this lets us do upwards-fun-args without creating a closure size_t scope; struct id*id__chain; // linked list of all ids // === m_define & m_builtin === struct define*define; } id; // frame holds return_point, and a code_ptr #define frame_size (size_t)2 // builtins want access to these extern const id*id__true, *id__false, *id__empty, *id__empty_group, *id__error; typedef struct define { // represent functions bool public, closure, regex_group, regex_or, regex_exit; // define->stack is group/or array (ab|c)* char*open_token; // "(" or "[" id**intakes; id*regex; id**inners; // holds public object/methods, but also used for scoping private methods id**stack; // the expression body } define; typedef void(*builtin)(id***, size_t); typedef void(*macro)(char**,size_t); typedef macro(*parser_predicate)(char*,size_t*); extern id**builtins; extern char*program_name; // normally "m" or "fuzz" void moses_init(); void moses_free(); char*moses_errorMessages(); char*type_name(m_type type); bool isRoot(id*i); id*parse(char*text_name, char*text_start, size_t text_length, bool repl, int showErrorLine); void parse_free(); id*create_id(char*from); id*create_id_with(char*name, m_type type, size_t scope, builtin def, char*from); void id_duplicate(id**i); void root_walker(void(*f)(id*)); char*id_name(id*i); void id_print_name(char**text, id*i, size_t max); char*id_text(id*i); define*create_define(); id*create_error(char*msg, id*ids[]); void error(char*msg, id*ids[]); void stack_print_to_text(id**s, char**text); void builtin__inner(id***stack, size_t intakes_point); # 13 "core.c" 2 #if 0 #include "build/builtin_generic_gen.h" #endif # 13 "core.c" # 1 "./build/builtin_generic_gen.h" 1 // This file is generated #if 0 #pragma once #endif # 3 "./build/builtin_generic_gen.h" #if 0 // #include "../core.h" #endif # 3 "./build/builtin_generic_gen.h" # 4 "./build/builtin_generic_gen.h" extern id**builtins; void builtins_init(); void builtin__zm(id***stack, size_t intakes_point); void builtin__om(id***stack, size_t intakes_point); void builtin__or(id***stack, size_t intakes_point); void builtin__not(id***stack, size_t intakes_point); void builtin__error(id***stack, size_t intakes_point); void builtin__say(id***stack, size_t intakes_point); void builtin__assert(id***stack, size_t intakes_point); void builtin__type(id***stack, size_t intakes_point); void builtin__exit(id***stack, size_t intakes_point); void builtin__exact_equality(id***stack, size_t intakes_point); void builtin__help(id***stack, size_t intakes_point); void builtin__h(id***stack, size_t intakes_point); //; void builtin__name_to_number(id***stack, size_t intakes_point); void builtin__number_to_name(id***stack, size_t intakes_point); void builtin__number_plus(id***stack, size_t intakes_point); void builtin__number_sub(id***stack, size_t intakes_point); void builtin__number_mult(id***stack, size_t intakes_point); void builtin__number_div(id***stack, size_t intakes_point); void builtin__number_pow(id***stack, size_t intakes_point); void builtin__number_log(id***stack, size_t intakes_point); void builtin__number_root(id***stack, size_t intakes_point); void builtin__number_eq(id***stack, size_t intakes_point); void builtin__number_lesseq(id***stack, size_t intakes_point); void builtin__number_greateq(id***stack, size_t intakes_point); void builtin__number_less(id***stack, size_t intakes_point); void builtin__number_great(id***stack, size_t intakes_point); void builtin__number_leftshift(id***stack, size_t intakes_point); void builtin__number_rightshift(id***stack, size_t intakes_point); //; void builtin__name_to_text(id***stack, size_t intakes_point); void builtin__text_to_name(id***stack, size_t intakes_point); void builtin__text_plus(id***stack, size_t intakes_point); void builtin__text_sub(id***stack, size_t intakes_point); void builtin__text_number_mult(id***stack, size_t intakes_point); void builtin__text_div(id***stack, size_t intakes_point); void builtin__text_eq(id***stack, size_t intakes_point); void builtin__text_greateq(id***stack, size_t intakes_point); void builtin__text_great(id***stack, size_t intakes_point); void builtin__text_lesseq(id***stack, size_t intakes_point); void builtin__text_less(id***stack, size_t intakes_point); void builtin__text_number_leftshift(id***stack, size_t intakes_point); void builtin__text_number_rightshift(id***stack, size_t intakes_point); void builtin__text_contains(id***stack, size_t intakes_point); //; void builtin__define_plus(id***stack, size_t intakes_point); void builtin__define_number_n(id***stack, size_t intakes_point); void builtin__define_number_leftshift(id***stack, size_t intakes_point); void builtin__define_number_rightshift(id***stack, size_t intakes_point); void builtin__define_count(id***stack, size_t intakes_point); void builtin__define_expose(id***stack, size_t intakes_point); //; enum file_flags {f_create = O_CREAT | O_EXCL, f_create_if_needed = O_CREAT }; void file_free(void*ptr, size_t length); char*file_read(char*path, size_t*file_length); void file_write(char*path, char*text, size_t text_length, enum file_flags flags); bool file_exists(char*path); void file_delete(char*path); # 14 "core.c" 2 #if 0 #include "builtin_print.h" #endif # 14 "core.c" # 1 "./builtin_print.h" 1 extern char*help_text; // prettier output void pretty_terminal(); void pretty_code(char**code); char*pretty_print(id*i); # 15 "core.c" 2 typedef struct { char*name; char*start; char*end; // -3==file-name-only, -2==for-unittests, -1==yes-if-bigfile, 0==no, 1==yes int showErrorLine; } file; file*currFile; file**files = NULL; file*create_file(char*name, char*start, char*end, int showErrorLine) { file* OOM(f, file); f->name = name; f->start = start; f->end = end; f->showErrorLine = showErrorLine; aA(&files, f); return f; } // get direct access to some builtins const id*id__inner, *id__error, *id__empty, *id__empty_group, *id__true, *id__false, *id__number, *id__text; char*type_name(m_type type) { switch(type) { case m_literal: return "Literal"; case m_intake: return "Intake"; case m_frame: return "Frame"; case m_define: return "Define"; case m_builtin: return "Builtin"; case m_give: return "Give"; case m_error: return "Error"; } } typedef struct { // the parser and compiler context file scratch_file; // file to test predicates to see if a name needs escaping // == id*id__root; // the root define; it holds the builtin defines, expression tree, etc id*id__chain; // helps create a linked list of all ids // === parse === parser_predicate*predicates; id*discarded_name; // m_intake ids can get overwritten, so we save them here, to save a malloc // === reduce === id**scope; // track names in lexical scoping char*error_msg; } moses_ctx; __thread moses_ctx*moses = NULL; char*moses_errorMessages() { return moses->error_msg; } bool isRoot(id*i) { return i==moses->id__root; } id*id_malloc() { id*i = malloc(sizeof(id)); oom(i); i->id__chain = moses->id__chain; moses->id__chain = i; return i; } void id_copy(id*i, id*to) { id*chain = to->id__chain; memcpy(to, i, sizeof(id)); to->id__chain = chain; } id*create_id_with(char*name, m_type type, size_t scope, builtin def, char*file_ptr) { // we convert ->name to opaque uint64_t when id type is m_literal assert(sizeof(char*) >= sizeof(size_t)); assert(moses); // moses_init id*i; if(moses->discarded_name) { i = moses->discarded_name; moses->discarded_name = NULL; } else i = id_malloc(); i->mark = 0; i->name = !name?NULL:string_to_name(name, strlen(name)); i->type = type; i->scope = scope; i->define = (define*)def; i->name_ptr = file_ptr; return i; } id*create_id (char*from) { return create_id_with(NULL, m_intake, SIZE_MAX-1, NULL, from); } id*create_returnpoint(char*from) { return create_id_with("^", m_frame, -2, NULL, from); } id*create_callpoint (char*from) { return create_id_with(".", m_frame, 0, NULL, from); } define*create_define() { define* OOM(d, define); d->public = false; d->closure = false; d->regex_group = false; d->regex_or = false; d->regex_exit = false; d->regex = NULL; d->open_token = NULL; d->intakes = NULL; d->inners = NULL; d->stack = NULL; return d; } void id_free(id*i) { //// file_ptr should fully be in id struct aswell... //// How can RefDelete call this special cleanup? free(i); } char*id_name(id*i) { return name_to_string(&i->name); } void id_walker_helper(id*i, void(*f)(id*)) { // visit each intake and stack, and do f() // mark_init itself uses f here, to make sure every id->mark==0 f(i); if(i->type!=m_define) return; if(mark_test(i)) return; mark_set(i); size_t n = -1; while(++n < aL(i->define->stack)) id_walker_helper(aAt(i->define->stack, n), f); n = -1; while(++n < aL(i->define->intakes)) id_walker_helper(aAt(i->define->intakes, n), f); } void root_walker(void(*f)(id*)) { id_walker_helper(moses->id__root, f); } char*id_text_helper(id*i, id***visited_ids) { // convert anything to aArray char* char*t = NULL; if(i->type!=m_define || aFold(*visited_ids, false, ^(bool base, id*visited){ return base || i==visited; })) { if(i->type==m_give) return NULL; if(i->type==m_frame && i->name==string_to_name("^", 1)) return NULL; return aAA(&t, SIZE_MAX, id_name(i)); } aA(visited_ids, i); if(i->name) { aAA(&t, SIZE_MAX, id_name(i)); if(i->type==m_literal) aA(&t, '`'); return t; } size_t n = -1; while(++n <aL(i->define->stack)) { if(aAt(i->define->stack, n)->type==m_give) break; char*tt = id_text_helper(aAt(i->define->stack, n), visited_ids); if(aL(tt)) { if(aL(t) && aAt(i->define->stack, n)->type!=m_frame) (void)aA(&t, ' '); (void)aAA(&t, aL(tt), tt); aFree(&tt); } } return t; } char*id_text(id*i) { // convert anything to aArray char* id**visited_ids = NULL; char*text = id_text_helper(i, &visited_ids); aA(&text, '\0'); assert(text[aL(text)-1]==aZAt(text,0)); aFree(&visited_ids); return text; } void id_print_name(char**text, id*i, size_t max) { // '' quote escape name to max length char*name = NULL; if(i->type==m_error) aAA(&name, SIZE_MAX, "ERR"); else name = aAA(&name, SIZE_MAX, id_name(i)); if(!aL(name)) { if(i->type==m_define && aL(i->define->intakes)) { // print the intakes size_t n = -1; while(++n < aL(i->define->intakes)) { if(n) (void)aAA(&name, 1, " "); id*ii = aAt(i->define->intakes, n); char*iiname = id_name(ii); if(!strlen(iiname)) iiname = "()"; (void)aAA(&name, SIZE_MAX, iiname); }; aAA(&name, SIZE_MAX, " :"); } else { aFree(&name); name = id_text(i); aZL2(name, 1); } } if(i->type==m_define) max -= 2; if(i->type==m_literal) max -= 1; if(aL(name) > max) { aL2(name, max); aZAt2(name, 0, '+'); } size_t n = -1; bool isEdited = false; // use parsing predicates to detect escaping char*store_start = currFile->start; currFile->start = name; char*store_end = currFile->end; currFile->end = name+aL(name); while(++n < aL(name)) { size_t m = -1; while(++m < aL(moses->predicates)) { size_t unused; if(aAt(moses->predicates, m)(aAtPtr(name, n), &unused) || aAt(name, n)=='\'' || aAt(name, n)<=31 || aAt(name, n)==127 // DEL ) { //if(!(aAt(name, n)==' ' && i->type==m_define)) isEdited = true; if(aAt(name, n)=='\'') { aR(&name, n++, 0, '\\'); currFile->start = name; currFile->end = name+aL(name); } m = -1; break; } } m = -1; } currFile->start = store_start; currFile->end = store_end; if(i->type==m_define && !i->name) { char*o = name_to_string(&i->define->open_token); aR(&name, 0, 0, o[0]=='('?'(':'['); aA(&name, o[0]=='('?')':']'); } else if((isEdited || !aL(name)) && i->type!=m_define) { aR(&name, 0, 0, '\''); aA(&name, '\''); } aC(text, name); aFree(&name); if(i->type==m_literal) aA(text, '`'); } void stack_print(id**stack); void id_print(id*i); // these are temporary aArrays that get reset to zero-length, // but there's no point allocating and freeing them all the time void fileLineCol(file*f, size_t*fByte, size_t errByte, size_t*line, size_t*col) { while(++*fByte < errByte) { ++*col; switch(f->start[*fByte]) { case '\r': if(*fByte < errByte && f->start[(*fByte)+1]=='\n') ++*fByte; case '\n': ++*line; *col = 1; default: break; } } } char*out = NULL; size_t*locations = NULL; void error(char*msg, id*ids[]) { // if moses->error_msg exists, then store the msg there, otherwise print it // error msg swaps '$' for id_name(ids[i++]) // '#' is for ids with relevant locations, but not show in the error msg aL2(out, 0); aL2(locations, 0); size_t i = 0; size_t n = -1; while(msg[++n]) if(msg[n]=='$' || msg[n]=='#') { aAA(&out, n, msg); if(msg[n]=='$') id_print_name(&out, ids[i], 15); char*fp = ids[i]->name_ptr; size_t nn = aL(files); while(nn--) if(fp >= files[nn]->start && fp <= files[nn]->end) break; if(nn!=SIZE_MAX) { // locations holds (id, file, bytepos)* aA(&locations, ids[i], files[nn], fp - files[nn]->start); } msg = msg+n+1; n = -1; i++; } aAA(&out, SIZE_MAX, msg); if(currFile->showErrorLine > -2) pretty_code(&out); //// should sort locations, so errors in same file and line are together //// if showErrorLine==-3, then could avoid all locations other than file->name //// -- letting us free the file while(aL(locations)) { // extract the file+line+col containing the error file*f = (file*)aAt(locations, 1); size_t fByte = -1, errByte = aAt(locations, 2), line = 1, col = 1; fileLineCol(f, &fByte, errByte, &line, &col); // limit debug line to terminal width size_t maxlen = 0; if(getenv("TERM")) { struct winsize w; if(ioctl(fileno(stdout), TIOCGWINSZ, &w)==-1) {} //aFE("%s", strerror(errno)); else maxlen = w.ws_col; } if(!maxlen) maxlen = 80; // only show lines if the file is big enough it would help a user find the error if(f->showErrorLine==-1) { f->showErrorLine = 0; if((size_t)f->end - (uintptr_t)f->start > maxlen*2) f->showErrorLine = 1; else { char*t = f->end-1; while(*t=='\r' || *t=='\n') --t; while(--t >= f->start) if(*t=='\r' || *t=='\n') { f->showErrorLine = 1; break; } } } size_t linestart = aL(out); if(f->showErrorLine==1 || f->showErrorLine==-3) aFA(&out, "\n%s:%uz:%uz: ", f->name, line, col); // account for "\n%s:%uz:%uz: " in the line length // allow upto the end of whichever line we're now on maxlen -= (aL(out) - linestart) % maxlen; // an error can happen in multiple locations // but only print lines once, not per-location size_t lastLocation = 0; while(lastLocation+3 < aL(locations)) { if((file*)aAt(locations, lastLocation+3+1)!=f) break; errByte = aAt(locations, lastLocation+3+2); size_t lineDiff = 0; fileLineCol(f, &fByte, errByte, &lineDiff, &col); if(f->showErrorLine==1 && lineDiff) break; lastLocation += 3; } char*errstart = &f->start[aAt(locations, 2)]; char*errend = &f->start[aAt(locations, lastLocation+2)]+ strlen(id_name((id*)aAt(locations, lastLocation+0))); //// once locations are sorted by file>byte, this should no-longer happen if(errstart > errend) { char*temp = errend; errstart = errend; errend = temp; } // go as far to the start of the line and still fit in maxlen while( errstart > f->start && *(errstart-1)!='\n' && *(errstart-1)!='\r' && (size_t)errend - ((uintptr_t)errstart +strlen(id_name((id*)aAt(locations, 0)))) < maxlen) errstart--; // go as far to the end and still fit in maxlen while( errend < f->end && *errend!='\n' && *errend!='\r' && (size_t)errend - (uintptr_t)errstart <= maxlen) errend++; // it may be that we never fitted in maxlen, so trim away if((size_t)errend - (uintptr_t)errstart > maxlen) errend = errstart + maxlen + 1; if(f->showErrorLine==1) aAA(&out, errend - (uintptr_t)errstart, errstart); aD(&locations, 0, lastLocation+3); } if(currFile->showErrorLine > -2) { aFE("%s", error_text); aWrite(stderr, out); aFE("\n"); } else aC(&moses->error_msg, out); } id*create_error(char*msg, id*ids[]) { error(msg, ids); // an m_error is returned to poison the expression -- suppressing future errors return (id*)create_id_with("ERR", m_error, 0, NULL, NULL); } // == Reduce // Parsing '.' denotes calling a function; if possible we reduce it in-place // This means evaluation happens before parsing has finished, // And so allows a moses program to self-extend it's own syntax // // Reduce is similar to eval, but it may have no call-stack, // as parsing can encounter '.' at any depth // So we only reduce intakes (parameters) that are directly passed into the call // -- nested intakes can be reduced at later '.' calls // == Reducable intakes // Scope is the depth at which defines (functions) and intakes are defined: // (intake{scope 1} intake_B{scope 2} define{scope 3}: (in_C{scope 4} def_B{scope 5}:__)) // So reducing an intake, irrespective of call-depth is: // if(define->scope - intake->scope <= define->number_of_intakes) // intake_result = the_call[the_call_length - (define->scope - intake->scope)]; // This is different to deBruijin indexing, but it means call-depth is abstracted away, // and so we get upwards-fun-args without any effort // == Downwards-fun-args (closures) is (was) also simple // When the called function returns an un-called define, // define is simply made to look like the called function; reduce_call() is used, // then the define is converted back // // This means closures are not special -- they are just a new define with // its in-scope intakes reduced // // This was true, but now the closure is walked, replacing and reducing as far as possible // == Redefines // // == Why? // The beauty of this system is: // 1) It maximally reduces a program // 2) Compile-time is runtime // // Meaning syntax errors can be runtime exceptions // Also the parser can be replaced or extended by the running program bool stack_loops(id*caller, id**stack, size_t return_point) { // test if call at return point will loop size_t n = return_point; assert( aAt(stack, n)->type==m_frame && aAt(stack, n)->name==string_to_name("^", 1)); assert( aAt(stack, n+1)->type==m_frame && aAt(stack, n+1)->name==string_to_name(".", 1)); size_t callee_repeats = 0; id*callee = aAt(stack, n-1); if( callee->type==m_builtin || callee->type==m_intake || callee->type==m_frame || callee->type==m_literal || callee->type==m_error) return false; assert(callee->type==m_define); if(caller==callee) { if(return_point==-frame_size) return false; //if(!aL(callee->define->intakes)) return true; // err... something like this for(size_t n = 0; n < aL(callee->define->stack); n++) if( aAt(callee->define->stack, n)==callee && aAt(callee->define->stack, n+1)->type==m_frame) return true; return false; } //aFE("\n--(%uz)>",n-1);id_print(callee); while(1) { size_t nn = aAt(stack, n)->scope; if(nn==-frame_size) break; ///if(aAt(stack, nn)->type==m_define) { /// stack_print(stack); /// aFE("\n> ");stack_print(moses->scope); } //aFE("\n==(%uz)(%uz)>",n-1,nn-1);stack_print(stack);aFE("(%uz)-----",nn);id_print(aAt(stack, nn));aFE(""); assert(aAt(stack, nn)->type==m_frame); assert(aAt(stack, nn)->name==string_to_name("^", 1)); assert( aAt(stack, nn-1)->type==m_define || aAt(stack, nn-1)->type==m_builtin); if(callee==aAt(stack, nn-1)) { // set a hard loop limit // pathological inputs can have exponential explosion // so limit==25 is too high //// or do stack size comparison -- and stop at lower number if explosion is happening //// and rewind stack, and set callee->define->loopy if(callee_repeats++==3) return true; // callee is on the call stack // so make sure at least one intake is different from last time n = aL(callee->define->intakes); while(n--) { id*in = aAt(stack, return_point-2-n); if( in->type!=m_intake && in!=aAt(stack, nn-2-n)) break; } if(n==(size_t)-1) return true; } n = nn; } return false; } void id_duplicate(id**i) { // duplicate i, aswell as i->define, i->define->stack, and i->define->inners //id*ii = create_id(NULL); memcpy(ii, *i, sizeof(id)); *i = ii; id*ii = create_id(NULL); id_copy(*i, ii); *i = ii; if(ii->define) { define*d = create_define(); memcpy(d, ii->define, sizeof(define)); ii->define = d; if(d->inners) d->inners = aC((id***)NULL, d->inners); if(d->stack) d->stack = aC((id***)NULL, d->stack); } } id*peel(id*old_i, id*i, id**stack, size_t n, id*change) { // duplicate i only as necessary if(aAt(stack, n)==change) return i; if(i==old_i) { i = id_malloc(); id_copy(old_i, i); OOM(i->define, define); memcpy(i->define, old_i->define, sizeof(define)); } if(stack==old_i->define->inners) stack = i->define->inners = aC((id***)NULL, old_i->define->inners); else if(stack==old_i->define->stack) stack = i->define->stack = aC((id***)NULL, old_i->define->stack); aAt2(stack, n, change); return i; } void id_reduce(id***stack); id*closure_peel(id*i, size_t parent_scope, id**intakes, size_t intakes_length, id***visited_ids) { // return the original i, or // a new i reduced with new intakes if(i->type==m_error) return i; assert(i->type==m_define); if(parent_scope+aL(i->define->intakes)>=i->scope) return i; if(!i->define->closure) return i; for(size_t n = 0; n < aL(*visited_ids); n+=2) if(aAt(*visited_ids, n)==i) { if(aAt(*visited_ids, n+1)) return aAt(*visited_ids, n+1); // i has not yet been peeled out of the directed-cyclic-graph of ids // but we're also encountering it now for the second time // so we sneeky convert it to an intake with ->scope==i->scope, // this lets id_reduce auto reduce it back down to i without looping // So simple and efficient, but it occasionally leaves 'intake^.' unreduced // even though intake is known to be 'i.' // If we were to reduce that intake, we would have to ensure that: // reduce->closure->reduce didn't form a loop // AND link up this i with it's potential future peeling // A simple way might be to: // pre-emptively peel everything, then reclaim any unused defines for next time // AND link up stack_loops with extra info? // creating an intake to an outer parent must mark closures // thankful they already will be id*intake = create_id(NULL); id_copy(i, intake); intake->type = m_intake; intake->define = NULL; return intake; } aA(visited_ids, i, NULL); size_t visited_ids_index = aL(*visited_ids)-1; // These are not normal closures... // Normally an extra data structure would just store the intakes (parameters), // and the closure's intakes would point into them. // But here we duplicate the whole closure, creating a new function with replaced intakes // So slower than normal closure creation (but faster calls) // The main reason for doing it though is that when intakes are replaced, // new opportunities for reduction (evaluation) may become available. // Duplicating closures lets us do this id*old_i = i; for(size_t n = 0; n < aL(i->define->inners); n++) { id*ii = aAt(i->define->inners, n), *cii = ii; cii = closure_peel(ii, parent_scope, intakes, intakes_length, visited_ids); i = peel(old_i, i, i->define->inners, n, cii); } for(size_t n = 0; n < aL(i->define->stack); n++) { id*ii = aAt(i->define->stack, n); id*cii; switch(ii->type) { case m_literal: case m_builtin: case m_give: case m_error: continue; case m_intake: if(parent_scope - ii->scope<=intakes_length+1) { cii = intakes[intakes_length - (parent_scope - ii->scope)]; // propagate change i = peel(old_i, i, i->define->stack, n, cii); } continue; case m_define: cii = closure_peel(ii, parent_scope, intakes, intakes_length, visited_ids); i = peel(old_i, i, i->define->stack, n, cii); continue; case m_frame: if(ii->name!=string_to_name(".", 1) || ii->scope!=0) continue; ////if(n<3) return create_error("'.' has nothing to call", NULL); id*callee = aAt(i->define->stack, n-2); // we would like to not have this line, but then we skip stack_loops //if(stack_loops(callee, i->define->stack, n+1-frame_size)) {aFE("z");continue;} if(callee->scope >= parent_scope) continue; id**new_stack = aAA((id***)NULL, n+1, i->define->stack); id_reduce(&new_stack); if( aL(new_stack)!=n+1 || !memcmp(new_stack, i->define->stack, aL(new_stack)*sizeof(id*))) { id**stack_end = aAtPtr(i->define->stack, n+1); size_t prev_n = aL(new_stack)-1; aAA(&new_stack, aL(i->define->stack) - (n+1), stack_end); n = prev_n; if(i==old_i) { // forced peel propagation i = create_id(NULL); id_copy(old_i, i); i->define = create_define(); memcpy(i->define, old_i->define, sizeof(define)); } i->define->stack = new_stack; } else aFree(&new_stack); continue; } } if(visited_ids_index) aAt2(*visited_ids, visited_ids_index, i); return i; } id*id_closure(id*i, size_t parent_scope, id**intakes, size_t intakes_length) { assert(i->type==m_define); id**visited_ids = NULL; i = closure_peel(i, parent_scope, intakes, intakes_length, &visited_ids); aFree(&visited_ids); return i; } void id_reduce(id***stack) { // reduce function calls to their minimum (+loops), or ERR // === stack is of the form: // [(intakes*, callee, return_pointer, call_pointer)*] // frame_size==2 and refers to return_pointer + call_pointer size_t return_point = (size_t)-frame_size; assert(aZAt(*stack, 0)->type==m_frame); assert(aZAt(*stack, 1)->type==m_frame); assert(aZAt(*stack, 0)->scope==0); assert(aZAt(*stack, 1)->scope==-frame_size); // not necessary aZAt(*stack, 1)->scope = -frame_size; // === start a new function call // aFE("\n=========="); loop_begin: // aFE("\n> ");stack_print(*stack);aFE(""); // === check the basics if(aL(*stack) <= frame_size) return (void)aR(stack, 0, aL(*stack), create_error("#'.' has nothing to call", (id*[]){aZAt(*stack, 0)})); assert(aZAt(*stack, 0)->type==m_frame); assert(aZAt(*stack, 1)->type==m_frame); id*callee = aZAt(*stack, 2); // === check callee and intakes size_t arity; switch(callee->type) { case m_builtin: arity = callee->scope; break; case m_define: arity = aL(callee->define->intakes); break; case m_intake: case m_frame: goto bailout; default: callee = create_error("$# is not callable", (id*[]){callee,aZAt(*stack, 0)}); // fallthrough case m_error: return (void)aR(stack, 0, aL(*stack), callee); } if(arity > aL(*stack) - (return_point+frame_size) - frame_size - 1) return (void)aR(stack, 0, aL(*stack), create_error("$# needs more intakes", (id*[]){callee, aZAt(*stack, 0)})); for(size_t n = -1; ++n<arity;) { // It would be nice to let m_defines reduce m_intake intakes // but but this would let intakes cross closure boundaries. // We must check that all define children were at a greater scope depth (or something) if( (aZAt(*stack, n+frame_size+1)->type==m_intake && ( callee->type==m_builtin || callee->scope <= aZAt(*stack, n+frame_size+1)->scope || callee->define->closure)) || aZAt(*stack, n+frame_size+1)->type==m_frame) goto bailout; if( aZAt(*stack, n+frame_size+1)->type==m_error) return (void)aR(stack, 0, aL(*stack), aZAt(*stack, n+frame_size+1)); } // === handle m_builtin if(callee->type==m_builtin) { // get the start of intakes // callee->scope is intake arity size_t first_intake = aL(*stack)-frame_size-callee->scope-1; // Naughty naughty Mr. Fuzzer #if defined(fuzz) goto bailout; #endif # 546 "core.c" ((builtin)callee->define)(stack, first_intake); if(aL(*stack) > first_intake && aAt(*stack, first_intake)->type==m_error) return (void)aR(stack, 0, aL(*stack), id__error); // really a bailout of treating callee as an m_define goto bailout; } // === m_define only // we've not even finished parsing this call, so let's skip it if(aZAt(callee->define->stack, 0)->type!=m_give) return; assert(callee->define->stack!=*stack); return_point = aL(*stack)-frame_size; // === bailout if(false) { // bailing out of a call can happen anywhere in the function head, // so we skip messy error checks by jumping straight here bailout: if(return_point==-frame_size) return; // 'return' to the previous call callee = aAt(*stack, return_point-1); goto loop_middle; } // === let the Good Times roll // get and apply each step of the function stack in turn loop_middle: // aFE("\n>> ");stack_print(*stack);aFE(""); //aFE("---(%uz)", return_point); assert(aAt(*stack,return_point+0)->type==m_frame); assert(aAt(*stack,return_point+1)->type==m_frame); // get current code_point (in function stack), then shift code_pointer id**cp = aAtPtr(*stack, return_point+1); id*i = aAt(callee->define->stack, (*cp)->scope); // aFE("\n--");id_print(i);aFE(""); (*cp)->scope += 1; switch(i->type) { case m_literal: case m_builtin: case m_error: aA(stack, i); goto loop_middle; case m_intake: {} if(callee->scope - i->scope <= aL(callee->define->intakes) +1) aA(stack, aAt(*stack, return_point - 1 - (callee->scope - i->scope))); else aA(stack, i); goto loop_middle; case m_define: // closure creation and dynamic_lookup can create intakes to defines // so this if statement could cause problems 0.1% of the time //if(aL(callee->define->intakes)) // sort out defines containing intakes going out of scope i = id_closure(i, callee->scope, aAtPtr(*stack, return_point-aL(callee->define->intakes)-1), aL(callee->define->intakes)); aA(stack, i); goto loop_middle; case m_frame:{} id_duplicate(&i); if(return_point+2==aL(*stack)) // there is no space between our frame and the prior frame return (void)aR(stack, 0, aL(*stack), create_error("#'.' has nothing to call", (id*[]){i})); aA(stack, i);//aFE("\n>> ");stack_print(*stack);aFE("<%uz> ", return_point); if( i->name==string_to_name(".", 1) && i->scope==0) { aZAt(*stack, 1)->scope = return_point; id*callee = aZAt(*stack, 2); if((callee->type==m_intake || callee->type==m_frame)) goto loop_middle; if(stack_loops(callee, *stack, aL(*stack)-frame_size)) goto loop_middle; goto loop_begin; } goto loop_middle; case m_give: {} // return from a define or redefine size_t new_return_point = aAt(*stack, return_point)->scope; if(callee->scope == aZAt(callee->define->stack, 0)->scope) // define -- replace intakes+define+frame with result aD(stack, return_point-aL(callee->define->intakes)-1, aL(callee->define->intakes)+1+frame_size); else {// redefine id*caller = aAt(*stack, new_return_point-1); id*temp = id_malloc(); id_copy(callee, temp); callee = temp; // to update scope aR(stack, new_return_point+2, aL(*stack) - new_return_point-2, callee, create_returnpoint(NULL), create_callpoint(NULL)); aAt(*stack, new_return_point+1)->scope = aL(caller->define->stack)-1; callee->scope -= 1; // move callee down to same level as parent if(callee->scope == aZAt(callee->define->stack, 0)->scope) { // set up the define being returned from aZAt(*stack, 1)->scope = new_return_point; new_return_point = aL(*stack)-2; } else callee->scope -= aL(caller->define->intakes); } //aFE("\n===> ");stack_print(*stack); if(new_return_point==-frame_size) { if( aL(*stack)>1 && aZAt(*stack, 1)->type==m_frame && aZAt(*stack, 1)->name==string_to_name("^", 1)) aZAt(*stack, 1)->scope = -frame_size; return; bool restart = false; size_t n = return_point+frame_size; while(--n < aL(*stack)) { id*i = aAt(*stack, n);//id_print(i); if(!(i->type==m_frame && i->name==string_to_name(".",1))) continue; if(i->scope==0) break; aFE("--restarting--");assert(false); // === there is a partly reduced call still on the stack // this happens because we reduce as we parse // we could reset the call to a point that can be restarted from with: //i->scope = 0; //aL2(*stack, n+1); return; // but that would undo some work // so lets instead just restart it! id*call = aAt(*stack, n-2); id*rt = aAt(*stack, n-1); assert(rt->type==m_frame); assert(call->type==m_define); restart = true; // exit at the end of the restarted call rt->scope = -2; //aAA(stack, frame_size+1+aL(call->define->stack)); new_return_point = n-1; } if(!restart) return; } callee = aAt(*stack, new_return_point-1); return_point = new_return_point; goto loop_middle; } } // === parse === // Recurisve descent, mostly handling reverse polish // Works as a runtime changeable list of predicates // If any predicate matches, it returns a macro function // I wanted to expose PEG parsing within moses // and PEG is essentially sugar over recursive descent void macro__escape(char**text, size_t token_length) { assert(false); } macro predicate__escape(char*text, size_t*token_length) { if(*text=='\\' && text+1 < currFile->end && *(text+1)=='\\') { *token_length = 1; return macro__escape; } return NULL; } bool isEscaped(char*text) { if(text > currFile->start && *(text-1)=='\\') { // check that the previous \ isn't escaped itself size_t n = 2; while(text-n >= currFile->start && *(text-n)=='\\') ++n; return (n+1) % 2; } return false; } void macro__space(char**text, size_t token_length) { // Ignore space *text += token_length; } bool is_space(char c) { return (c & 0b101000) && (c==' ' || c=='\t' || c=='\r' || c=='\n'); } macro predicate__space(char*text, size_t*token_length) { if(isEscaped(text)) return NULL; *token_length = 0; while(text+*token_length < currFile->end && is_space(text[*token_length])) (*token_length)++; if(!*token_length) return NULL; return macro__space; } void macro__literal(char**text, size_t token_length) { *text += token_length; id***stack = &aZAt(moses->scope, frame_size)->define->stack; if(token_length!=1 || aL(*stack)==0) { aA(stack, create_error( token_length!=1?"#literals use single '`'":"#nothing to be made literal", (id*[]){create_id(*text-token_length)})); return; } id**ip = aZAtPtr(*stack, 0); if((*ip)->type==m_error) return; if((*ip)->type==m_literal) { *ip = create_error("$ is already literal", (id*[]){(*ip)}); return; } else if(!(*ip)->name || (*ip)->type==m_frame) { *ip = create_error("$ cannot be literal", (id*[]){(*ip)}); return; } assert(sizeof(char*) <= sizeof(size_t)); // scope!=SIZE_MAX means intake is shared between ids if((*ip)->type == m_intake && (*ip)->scope==SIZE_MAX) (*ip)->type = m_literal; else *ip = create_id_with(name_to_string(&(*ip)->name), m_literal, (size_t)(*ip)->name, NULL, *text); } macro predicate__literal(char*text, size_t*token_length) { if(*text!='`') return NULL; if(isEscaped(text)) return NULL; *token_length = 1; while(text+*token_length < currFile->end && *(text+*token_length)=='`') (*token_length)++; return macro__literal; } void macro__name(char**text, size_t token_length); macro predicate__byset(char*text, size_t*token_length, parser_predicate*predicates) { char*text_start = text; macro next = NULL; // if any predicate returns a macro; // return that macro, otherwise return macro__name size_t n = 0; while(1) { if((next = aAt(predicates, n)(text, token_length))) { assert(text <= currFile->end); if(next==macro__escape) { text += *token_length; continue; } if(text_start==text) return next; *token_length = text - text_start; return macro__name; } if(++n==aL(predicates)) { n = 0; text++; } } } macro predicate__all(char*text, size_t*token_length) { return predicate__byset(text, token_length, moses->predicates); } void scope_lookup(id**iptr) { id*i = *iptr; i->scope = SIZE_MAX; // == lookup name in scope id*old_parent, *parent = NULL; // iterate back through scope intakes/defines, to see if any match i->name size_t n = aL(moses->scope); while(n) { old_parent = parent; parent = aAt(moses->scope, n-1-frame_size); define*d = parent->define; n -= aL(d->intakes)+1+frame_size; // we allow scoping to errors, so that they propagate assert(parent->type==m_define || parent->type==m_error); size_t nn = aL(d->inners); while(nn--) { id*ii = aAt(d->inners, nn); // see if parent contains an inner define with the same name if((ii->type==m_define || ii->type==m_builtin) && ii->name==i->name) { moses->discarded_name = i; *iptr = ii; if(ii->define->closure) goto mark_closures; return; } } if(parent->name==i->name) { // see if the parent has the same name moses->discarded_name = i; // don't break -- since no need to mark closures *iptr = parent; return; } nn = aL(d->intakes); while(nn--) { id*ii = aAt(d->intakes, nn); // see if parent has an intake of the same name if(ii->name==i->name) { if(old_parent && old_parent->define->public) { error("/$ callable without access to $", (id*[]){old_parent, ii}); (*iptr)->type = m_error; return; } else { moses->discarded_name = i; *iptr = ii; goto mark_closures; } } } } return; // == if name resolved to an external intake or inner, then mark closures mark_closures: n = aL(moses->scope); while(n) { define*d = aAt(moses->scope, n-1-frame_size)->define; if(parent->define==d) break; d->closure = true; n -= aL(d->intakes)+1+frame_size; } } void macro__name(char**text, size_t token_length) { // This macro has no predicate. It is called when no predicate matches // So moses names work for any language + any symbol // == create the name id*i; assert(*text+token_length <= currFile->end); i = create_id(*text); i->type = m_intake; id***stack = &aZAt(moses->scope, frame_size)->define->stack; // strip escapes char*escape = NULL; size_t nn = 0; size_t n = -1; while(++n < token_length) if((*text)[n]=='\\') { aAA(&escape, token_length, *text); n--; break; } if(escape) { while(++n < aL(escape)) if(aAt(escape, n)=='\\') { if(n+1<aL(escape) && aAt(escape, n+1)=='\\') { ++n; continue; } aD(&escape, n, 1); ++nn; // nn tracks pos in *text // check if escape is actually used by a parser predicate file*store_file = currFile; moses->scratch_file.name = currFile->name; moses->scratch_file.showErrorLine = currFile->showErrorLine; moses->scratch_file.start = (*text)+n+nn; moses->scratch_file.end = (*text)+n+nn+1; currFile = &moses->scratch_file; if(currFile->end > store_file->end) currFile->end = store_file->end; size_t _token_length; assert(*text < currFile->end); macro next = predicate__all(currFile->start, &_token_length); if( currFile->start==currFile->end || next==macro__name) { aRA(&escape, 0, aL(escape), currFile->end - (uintptr_t)currFile->start+1, currFile->start-1, 1, ""); currFile = store_file; aA(stack, create_error("$ escape is not needed", (id*[]){create_id_with(escape, m_intake, SIZE_MAX-1, NULL, (*text)+n+nn-1)})); *text += token_length; return; } currFile = store_file; } i->name = string_to_name(escape, aL(escape)); aFree(&escape); } else i->name = string_to_name(*text, token_length); if(!i->name) // same as id_name(i)!=NULL && !strlen(id_name(i)) i = create_error("name $ has no length", (id*[]){i}); *text += token_length; assert(*text <= currFile->end); //aF("-%uz-{%s}",token_length, id_name(i)); assert(aL(*stack)==0 || (aAt(*stack,0) && id_name(aAt(*stack, 0)))); scope_lookup(&i); aA(stack, i); } void macro__call(char**text, size_t token_length) { //id***stack = &aZAt(moses->scope, frame_size)->define->stack; //aA(stack, create_returnpoint(*text), // create_callpoint(*text)); id_reduce(stack); id**stack = NULL; //// duplicate the stack incase it is shared //// not necessary aC(&stack, aZAt(moses->scope, frame_size)->define->stack); aA(&stack, create_returnpoint(*text), create_callpoint(*text)); id_reduce(&stack); aZAt(moses->scope, frame_size)->define->stack = stack; *text += token_length; } macro predicate__call(char*text, size_t*token_length) { if(*text!='.') return NULL; if(isEscaped(text)) return NULL; *token_length = 1; return macro__call; } void macro__exprBegin(char**text, size_t token_length); void macro__expr(char**text, size_t token_length); void define_tidy(id*i); bool match_brackets(char*a, char*b, size_t b_length) { if(strlen(a)==0 && b_length==0) return true; //if(strlen(a)!=1 || b_length!=1) return false; return (a[0]=='(' && b[0]==')') || (a[0]=='[' && b[0]==']') || (a[0]==b[0]); } void macro__exprEnd(char**text, size_t token_length) { // id_duplicate(&define_id);//aZAt2(moses->scope, frame_size, i); id*i = aZAt(moses->scope, frame_size); assert(i->type==m_define || i->type==m_error); define*d = i->define; define_tidy(i); char*open_token = name_to_string(&d->open_token); if(!match_brackets(open_token, *text, token_length)) { id*open = create_id(NULL); open->name_ptr = i->name_ptr; id*close= create_id(*text); open->name = string_to_name(name_to_string(&i->define->open_token), 1); close->name = string_to_name(*text, token_length); if(!token_length) { error("no closing bracket for $", (id*[]){open}); aZL2(moses->scope, aL(d->intakes)+1+frame_size); i->type = m_error; } else if(!strlen(open_token)) { error("no opening bracket for $", (id*[]){close}); aL2(moses->id__root->define->stack, 0); aL2(moses->id__root->define->inners, 0); aL2(moses->scope, 1+frame_size); aA(&moses->id__root->define->stack, id__error); } else { error("brackets $ and $ do not match", (id*[]){open, close}); aZL2(moses->scope, aL(d->intakes)+1+frame_size); i->type = m_error; } *text += token_length; assert(*text <= currFile->end); return (void)macro__expr(text, 0); } *text += token_length; aZL2(moses->scope, aL(d->intakes)+1+frame_size); } macro predicate__exprEnd(char*text, size_t*token_length) { assert(text <= currFile->end); if(text==currFile->end) { *token_length = 0; return macro__exprEnd; } if(*text!=')' && *text!=']') return NULL; if(isEscaped(text)) return NULL; *token_length = 1; return macro__exprEnd; } void macro__expr(char**text, size_t token_length) { while(1) { macro next = predicate__all(*text, &token_length); if(next==macro__exprEnd) break; assert(*text < currFile->end); next(text, token_length); } } void macro__exprBegin(char**text, size_t token_length) { // brackets are '(anonymous defines)', but are elided if they contain ':' assert(*text <= currFile->end); id*i; id***stack; if(!aL(moses->scope)) { stack = &moses->id__root->define->stack; i = moses->id__root; } else { i = create_id(*text); define*d = create_define(); id*parent = aZAt(moses->scope, frame_size); d->open_token = string_to_name(*text, token_length); i->type = m_define; i->define = d; i->scope = parent->scope+1; assert( parent->type==m_define || parent->type==m_error); stack = &parent->define->stack; aA(stack, i); } aA(&moses->scope, i, create_returnpoint(*text), create_callpoint(*text)); *text+=token_length; assert(*text <= currFile->end); macro__expr(text, 0); macro next = predicate__exprEnd(*text, &token_length); assert(next==macro__exprEnd); next(text, token_length); } macro predicate__exprBegin(char*text, size_t*token_length) { assert(text < currFile->end); if(*(text)!='(' && *(text)!='[') return NULL; if(isEscaped(text)) return NULL; *token_length = 1; return macro__exprBegin; } void define_tidy(id*i) { define*d = i->define; // strip non-public inner defines if(i!=moses->id__root) { size_t n = 0; while(n < aL(d->inners)) { if( aAt(d->inners, n)->type==m_define && aAt(d->inners, n)->define->public) n++; else aD(&d->inners, n, 1); } } // make sure all stacks end with m_give if(!aL(d->stack) || aZAt(d->stack, 0)->type!=m_give) aA(&d->stack, create_id_with("give", m_give, i->scope, NULL, NULL)); } void intake_binding(id*define_id, id**intakes) { size_t n = -1; while(++n < aL(intakes)) { id*intake = aAt(intakes, n); // must be an named unused m_intake if(intake->type==m_error) { define_id->type = m_error; continue; } if(intake->type==m_frame) { error("#'.' not intake", (id*[]){intake}); define_id->type = m_error; n++; continue; } if(intake==id__inner) { error("#'/' not intake", (id*[]){intake}); define_id->type = m_error; continue; } if(!intake->name) { error("$ not intake", (id*[]){intake}); define_id->type = m_error; continue; } if(intake->scope!=SIZE_MAX || intake->type!=m_intake) { error("$ already defined", (id*[]){intake}); define_id->type = m_error; continue; } intake->scope = define_id->scope - aL(intakes) + n; } } void macro__define(char**text, size_t token_length) { assert(*text < currFile->end); id*parent_id = aZAt(moses->scope, frame_size); assert(parent_id->type==m_define || parent_id->type==m_error); if(parent_id->type==m_error && !parent_id->define) parent_id->define = create_define(); define*pd = parent_id->define; id*define_id = NULL; define*d; bool define_is_public = false; size_t redefine_scope = SIZE_MAX; if(aL(pd->stack) && !is_space(*((*text)-1))) { define_id = aZAt(pd->stack, 0); // x:: and x::: take the scope of x if(token_length>1 && define_id->type==m_define && define_id->name && aZAt(define_id->define->stack, 0)->type!=m_give) redefine_scope = define_id->scope; if(define_id->define && define_id->type!=m_builtin) { if(define_id->define->public) define_is_public = true; } if(define_id==parent_id) { // avoid pd elision over itself define_id = create_id(*text); define_id->name = parent_id->name; aZAt2(pd->stack, 0, define_id); } } // create anonymous define if(!define_id) { define_id = create_id_with("", m_intake, SIZE_MAX-1, NULL, *text); aA(&pd->stack, define_id); } if(redefine_scope==SIZE_MAX && token_length>1) { // :: ::: take scope of the last named define size_t n = aL(moses->scope); while(n) { id*parent = aAt(moses->scope, n-1-frame_size); if( parent->name && parent!=moses->id__root && (!define_id->name || define_id->name==parent->name)) { redefine_scope = parent->scope; define_id->name = parent->name; break; } n -= aL(parent->define->intakes)+1+frame_size; } if(redefine_scope==SIZE_MAX && define_id->type!=m_error) define_id = create_error("#:: and ::: only redefine named defines", (id*[]){define_id}); } assert(define_id!=parent_id); assert(define_id->define!=parent_id->define); // handle errors, and duplicate memory, so no overwite of id__call, etc if(define_id->type!=m_error && !(define_id->type==m_define && token_length!=1) && (define_id->type!=m_intake || define_id->scope<SIZE_MAX-1)) define_id = create_error("$ already defined", (id*[]){define_id}); if(define_id->type==m_define) { id*temp = create_id(*text); temp->name = define_id->name; define_id = temp; } aZAt2(pd->stack, 0, define_id); // overwrite old define_id assert(*text < currFile->end); *text += token_length; assert(*text <= currFile->end); if(token_length > 3 && define_id->type!=m_error) { error("$ must use one of = : :: :::", (id*[]){define_id}); define_id->type = m_error; } // === create define // assume pd is root, or a named define -- 'pd: a:b' d = create_define(); define_id->define = d;//aF("<%up>",aZAt(pd->stack, 0)); if(token_length==1) { d->intakes = pd->stack; aZL2(d->intakes, 1); d->stack = NULL; d->open_token = string_to_name(":", 1); pd->stack = aA((id***)NULL, define_id); } // set scope to previous define+1+intakes if(define_id->type!=m_error) define_id->type = m_define; d->public = define_is_public; define_id->type = m_error; bool addedExprToScope = true; char*open_token = name_to_string(&parent_id->define->open_token); // new define, where pd->open_token is: // ( --> (: // (: --> (: : // : --> : : // \0 --> \0 : if(define_id!=m_error && open_token[0]!='\0' && open_token[0]!=':' && open_token[1]!=':') { addedExprToScope = false; // elide pd since it is an anonymous bracket -- '(a:b)' --> 'a:b' assert(!aL(parent_id->define->intakes)); aZL2(moses->scope, frame_size+1); assert(aZAt(aZAt(moses->scope, frame_size)->define->stack, 0)==parent_id); moses->discarded_name = parent_id; //// ? parent_id = aZAt(moses->scope, frame_size); aZAt2(parent_id->define->stack, 0, define_id); pd = parent_id->define; assert(strlen(open_token)<=1); open_token[1] = ':'; define_id->define->open_token = string_to_name(open_token, 2); } define_id->scope = aZAt(moses->scope, frame_size)->scope+aL(d->intakes)+1; intake_binding(define_id, d->intakes); // parse needs pd->inners, // because reduce might remove defines from the stack, as parsing happens ////if(define_id->type!=m_error) aA(&pd->inners, define_id); aC(&moses->scope, define_id->define->intakes); aA(&moses->scope, define_id, create_returnpoint(*text), create_callpoint(*text)); assert(*text <= currFile->end); macro__expr(text, 0); if(token_length>1) { if(redefine_scope==SIZE_MAX) redefine_scope = define_id->scope-1; id*give = create_id_with(NULL, m_give, redefine_scope, NULL, NULL); give->name = define_id->name; aA(&define_id->define->stack, give); id***stack = &aZAt(moses->scope, 5)->define->stack; if(aL(*stack)>1) { // we can strip anything that isn't a call, since this redefine will skip over them size_t n = aL(*stack)-1; while(n--) if(aAt(*stack, n)->type==m_frame) break; aD(stack, n+1, aL(*stack)-2-n); } aA(stack, create_returnpoint(NULL), create_callpoint(NULL)); } if(addedExprToScope) { // expr wasn't added with exprBegin/exprEnd, so we need to tidy up ourselves define_tidy(define_id); aZL2(moses->scope, aL(define_id->define->intakes)+1+frame_size); } } macro predicate__define(char*text, size_t*token_length) { if(*text!=':') return NULL; if(isEscaped(text)) return NULL; *token_length = 1; while(text+*token_length < currFile->end && *(text+*token_length)==':') (*token_length)++; return macro__define; } macro predicate__inner(char*text, size_t*token_length); void macro__create_inner(char**text, size_t token_length) { *text += token_length; assert(*text <= currFile->end); // must be of the form '/inner:define' id*parent = aZAt(moses->scope, frame_size); id***stack = &parent->define->stack; macro next = predicate__all(*text, &token_length); if(next!=macro__name) { error("/ needs define/name#", (id*[]){create_id(*text)}); return (void)aA(stack, id__error); } next(text, token_length); if(*text!=currFile->end) next = predicate__define(*text, &token_length); if(next!=macro__define) { error("/$ needs to be /$: or define/$", (id*[]){aZAt(*stack, 0), aZAt(*stack, 0), aZAt(*stack, 0)}); aZAt(*stack, 0)->type = m_error; return (void)aZAt2(*stack, 0, id__error); } assert(*text <= currFile->end); // signify public using an m_define with ->define->public = true id*inner = aZAt(*stack, 0); if(inner->define) { inner = create_id_with(name_to_string(&inner->name), m_define, 0, NULL, *text); aZAt2(*stack, 0, inner); } inner->define = create_define(); inner->define->public = true; next(text, token_length); } void macro__inner(char**text, size_t token_length) { // must be of the form 'define/inner', already matched 'define/' id*parent = aZAt(moses->scope, frame_size); id***stack = &parent->define->stack; // test if next token is a name *text += token_length; // parse name as anything ending in / . or \s predicates // this is to allow inner to be "==", etc char*text_start = *text; parser_predicate*predicates = NULL; aA(&predicates, predicate__exprEnd, predicate__exprBegin, predicate__call, predicate__inner, predicate__space); macro next = predicate__byset(*text, &token_length, predicates); aFree(&predicates); *text = text_start; id*i = create_id(*text); i->name = string_to_name(*text, token_length); i->type = m_define; i->define = create_define(); // create an m_define just for prettyprint aA(&i->define->stack, create_id_with("give", m_give, i->scope, NULL, NULL)); *text += token_length; //if(aL(*stack) && aZAt(*stack, 0)->type==m_error) return; if(next!=macro__name) { if(aL(*stack)) { error("$/name has no name", (id*[]){aZAt(*stack, 0)}); aZAt(*stack, 0)->type = m_error; return (void)aZAt2(*stack, 0, id__error); } error("define/name has no define or name", NULL); return (void)aA(stack, id__error); } aA(stack, i, id__inner, create_returnpoint(*text), create_callpoint(*text)); id_reduce(stack); } macro predicate__inner(char*text, size_t*token_length) { if(*text!='/') return NULL; if(isEscaped(text)) return NULL; *token_length = 1; // check for name in name/___ if(aL(moses->scope) && aL(aZAt(moses->scope, frame_size)->define->stack) && !is_space(*(text-1))) return macro__inner; return macro__create_inner; } void builtin__inner(id***stack, size_t intakes_point) { id**args = aAtPtr(*stack, intakes_point); id*define_id = args[0], *inner_id = args[1]; if(define_id->type==m_intake) return; aL2(*stack, intakes_point+1); if(define_id->type!=m_define) { error("$/$# does not begin with a Define", (id*[]){define_id, inner_id, aZAt(*stack, 0)}); define_id->type = m_error; return; } if(!inner_id->name) { error("/$# has no name", (id*[]){inner_id, aZAt(*stack, 0)}); inner_id->type = m_error; return; } id**inners = define_id->define->inners; size_t n = -1; while(++n < aL(inners)) if(aAt(inners, n)->name==inner_id->name) { args[0] = aAt(inners, n); return; } // inner not found, so look up handle in scope // this should be an overridable generic handler for when inner not found //id*handle = create_id_with("handle", m_intake, 0, NULL, NULL); //scope_lookup(&handle); //if(handle->type==m_define) { // id**temp_stack = aA((id***)NULL, define_id, inner_id, handle, // create_returnpoint(NULL), create_callpoint(NULL)); // id_reduce(&temp_stack); // aRA(stack, intakes_point, aL(*stack)-intakes_point, aL(temp_stack), temp_stack); // aFree(&temp_stack); return; } args[0] = create_error("$/$# was not found", (id*[]){define_id,inner_id, aZAt(*stack, 0)}); } id*parse(char*text_name, char*text_start, size_t text_length, bool repl, int showErrorLine) { // setup parsing state currFile = create_file(text_name, text_start, text_start+text_length, showErrorLine); moses->id__chain = NULL; moses->id__root = create_id_with("exit", m_define, 0, (builtin)create_define(), NULL); aL2(moses->error_msg, 0); aL2(moses->scope, 0); aC(&moses->id__root->define->inners, builtins); // begin parsing macro__exprBegin(&text_start, 0); // update what the repl remembers if(repl && moses->id__root->type!=m_error) { aL2(builtins, 0); aC(&builtins, moses->id__root->define->inners); } // test for unused intakes id*i = moses->id__chain; id*invert = NULL; while(i) { id*temp = i->id__chain; if(i->type == m_intake && i->scope == SIZE_MAX) { i->id__chain = invert; invert = i; } i = temp; } // print errors in reverse order while(invert) { id*temp = invert->id__chain; error("$ is not used", (id*[]){invert}); invert->type = m_error; invert = temp; } return moses->id__root; } void parse_free() { return; while(moses->id__chain) { id*temp = moses->id__chain->id__chain; //free(moses->id__chain); moses->id__chain = temp; } } id*create_id_with_code(char*code) { id*exit = parse("builtin", code, strlen(code), true, 0); aL2(moses->id__root->define->inners, 0); //stack_print(moses->id__root->define->stack); if(aL(exit->define->stack)) return aAt(exit->define->stack, 0); return exit; } void stack_print_to_text_helper(id**s, char**text, bool isIntakes, bool isRegexOr); void id_print_to_text_helper(id*i, char**text, bool isIntakes) { if(i==id__true) return (void)aFA(text, "#T"); if(i==id__false) return (void)aFA(text, "#F"); switch(i->type) { case m_literal: id_print_name(text, i, SIZE_MAX); break; case m_error: aFA(text, "ERR"); break; case m_builtin: aFA(text, "#%s", id_name(i)); break; case m_intake: if(isIntakes) id_print_name(text, i, SIZE_MAX); else aFA(text, "%s-%uz", id_name(i), i->scope); break; case m_frame: if(i->name==string_to_name("^",1) && i->scope==(size_t)-2) aFA(text, "^"); else if(i->name==string_to_name(".",1) && i->scope==(size_t)0) aFA(text, "."); else aFA(text, "%s%uz", id_name(i), i->scope); break; case m_give: aFA(text, "$%uz", i->scope); break; case m_define: if(i->define->closure) aFA(text, "C"); if(mark_test(i)) { aFA(text, "#", i->scope); id_print_name(text, i, SIZE_MAX); return; } else mark_set(i); if(!isIntakes && !i->define->regex_group && !i->define->regex_or) { id*give = aZAt(i->define->stack, 0); assert(give->type==m_give); if(give->scope!=i->scope) { aFA(text, "[%s::", id_name(give), i->scope); stack_print_to_text_helper(i->define->stack, text, false, i->define->regex_or); aFA(text, "]"); break; } } aFA(text, i->define->regex_group?"{":"(",i->scope); if(aL(i->define->intakes)) { stack_print_to_text_helper(i->define->intakes, text, true, i->define->regex_or); aFA(text, " "); } if(aL(i->define->intakes) || id_name(i)[0]) { aFA(text, "%s%s:", i->define->public?"/":"", id_name(i)[0]?id_name(i):"''", i->scope); } stack_print_to_text_helper(i->define->stack, text, false, i->define->regex_or); aFA(text, i->define->regex_group?"}":")"); break; } } void stack_print_to_text_helper(id**s, char**text, bool isIntakes, bool isRegexOr) { aLoop(s, 0, ^(size_t n) { // can be useful to comment this, as it hides stack ending give+yield if(!isIntakes && n==aL(s)-1 && aZAt(s, 0)->type==m_give) return 0; if(n && aAt(s, n)->type!=m_frame) aFA(text, isRegexOr?"|":" "); id_print_to_text_helper(aAt(s, n), text, isIntakes); return 1; }); } void stack_print_to_text(id**s, char**text) { mark_init((void(*)())root_walker); stack_print_to_text_helper(s, text, false, false); } void stack_print(id**s) { char*text = NULL; mark_init((void(*)())root_walker); stack_print_to_text_helper(s,&text, false, false); aWrite(stdout, text); aFree(&text); } void id_print(id*i) { char*text = NULL; mark_init((void(*)())root_walker); id_print_to_text_helper (i,&text, false); aWrite(stdout, text); aFree(&text); } void moses_init() { name_init(); assert(!moses); OOM(moses, moses_ctx); moses->predicates = NULL; moses->discarded_name = NULL; moses->scope = NULL; moses->error_msg = NULL; builtins_init(); // setup predicates (:.!/) for parsing aA(&moses->predicates, predicate__exprEnd, // first for EOF, just incase predicate__exprBegin, predicate__space, predicate__escape, predicate__literal, predicate__call, predicate__define, predicate__inner); // bootstrap functions id__empty = create_id_with_code("()"); id__error = create_id_with("ERR", m_error, 0, NULL, NULL); id__inner = create_id_with("inner", m_builtin, 2, builtin__inner, NULL); id__true = create_id_with_code("a _ T: (/name:T`) ::a."); id__false = create_id_with_code("_ b F: (/name:F`) ::b."); id__empty_group = create_id_with("", m_define, 0, (builtin)create_define(), NULL); id__empty_group->define->regex_group = true; aA(&moses->scope, moses->id__root, create_returnpoint(NULL), create_callpoint(NULL)); } void moses_free() { name_free(); aFree(&moses->predicates); id_free((id*)id__error); id_free(moses->id__root); free(moses); }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Compiler Explorer Shop
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
CE on Bluesky
Statistics
Changelog
Version tree