Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C++ (Circle)
CIRCT
Clean
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
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Nim
Objective-C
Objective-C++
OCaml
OpenCL C
Pascal
Pony
Python
Racket
Ruby
Rust
Snowball
Scala
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
TypeScript Native
V
Vala
Visual Basic
Vyper
WASM
Zig
Javascript
GIMPLE
Ygen
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 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 14.1.0
ARM GCC 14.1.0 (unknown-eabi)
ARM GCC 14.2.0
ARM GCC 14.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 (WINE)
ARM msvc v19.10 (WINE)
ARM msvc v19.14 (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 13.1.0
ARM64 gcc 13.2.0
ARM64 gcc 13.3.0
ARM64 gcc 14.1.0
ARM64 gcc 14.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 (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 13.1.0
AVR gcc 13.2.0
AVR gcc 13.3.0
AVR gcc 14.1.0
AVR gcc 14.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 gcc 13.1.0
BPF gcc 13.2.0
BPF gcc 13.3.0
BPF gcc trunk
EDG (experimental reflection)
EDG 6.5
EDG 6.5 (GNU mode gcc 13)
EDG 6.6
EDG 6.6 (GNU mode gcc 13)
FRC 2019
FRC 2020
FRC 2023
HPPA gcc 14.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
M68K gcc 13.1.0
M68K gcc 13.2.0
M68K gcc 13.3.0
M68K gcc 14.1.0
M68K gcc 14.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
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 13.1.0
RISC-V (32-bits) gcc 13.2.0
RISC-V (32-bits) gcc 13.3.0
RISC-V (32-bits) gcc 14.1.0
RISC-V (32-bits) gcc 14.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 13.1.0
RISC-V (64-bits) gcc 13.2.0
RISC-V (64-bits) gcc 13.3.0
RISC-V (64-bits) gcc 14.1.0
RISC-V (64-bits) gcc 14.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 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 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 13.1.0
SPARC LEON gcc 13.2.0
SPARC LEON gcc 13.3.0
SPARC LEON gcc 14.1.0
SPARC LEON gcc 14.2.0
SPARC gcc 12.2.0
SPARC gcc 12.3.0
SPARC gcc 12.4.0
SPARC gcc 13.1.0
SPARC gcc 13.2.0
SPARC gcc 13.3.0
SPARC gcc 14.1.0
SPARC gcc 14.2.0
SPARC64 gcc 12.2.0
SPARC64 gcc 12.3.0
SPARC64 gcc 12.4.0
SPARC64 gcc 13.1.0
SPARC64 gcc 13.2.0
SPARC64 gcc 13.3.0
SPARC64 gcc 14.1.0
SPARC64 gcc 14.2.0
TI C6x gcc 12.2.0
TI C6x gcc 12.3.0
TI C6x gcc 12.4.0
TI C6x gcc 13.1.0
TI C6x gcc 13.2.0
TI C6x gcc 13.3.0
TI C6x gcc 14.1.0
TI C6x gcc 14.2.0
TI CL430 21.6.1
VAX gcc NetBSDELF 10.4.0
VAX gcc NetBSDELF 10.5.0 (Nov 15 03:50:22 2023)
WebAssembly clang (trunk)
Xtensa ESP32 gcc 11.2.0 (2022r1)
Xtensa ESP32 gcc 12.2.0 (20230208)
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 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 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.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 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 9.0.0
armv8-a clang 9.0.1
clang-cl 18.1.0
ellcc 0.1.33
ellcc 0.1.34
ellcc 2017-07-16
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 13.1.0
loongarch64 gcc 13.2.0
loongarch64 gcc 13.3.0
loongarch64 gcc 14.1.0
loongarch64 gcc 14.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 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 13.1.0
mips gcc 13.2.0
mips gcc 13.3.0
mips gcc 14.1.0
mips gcc 14.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 13.1.0
mips64 (el) gcc 13.2.0
mips64 (el) gcc 13.3.0
mips64 (el) gcc 14.1.0
mips64 (el) gcc 14.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 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 13.1.0
mips64 gcc 13.2.0
mips64 gcc 13.3.0
mips64 gcc 14.1.0
mips64 gcc 14.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
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 gcc 12.1.0
mipsel gcc 12.2.0
mipsel gcc 12.3.0
mipsel gcc 12.4.0
mipsel gcc 13.1.0
mipsel gcc 13.2.0
mipsel gcc 13.3.0
mipsel gcc 14.1.0
mipsel gcc 14.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 13.1.0
power gcc 13.2.0
power gcc 13.3.0
power gcc 14.1.0
power gcc 14.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 13.1.0
power64 gcc 13.2.0
power64 gcc 13.3.0
power64 gcc 14.1.0
power64 gcc 14.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 13.1.0
power64le gcc 13.2.0
power64le gcc 13.3.0
power64le gcc 14.1.0
power64le gcc 14.2.0
power64le gcc 6.3.0
power64le gcc trunk
powerpc64 clang (trunk)
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 13.1.0
s390x gcc 13.2.0
s390x gcc 13.3.0
s390x gcc 14.1.0
s390x gcc 14.2.0
sh gcc 12.2.0
sh gcc 12.3.0
sh gcc 12.4.0
sh gcc 13.1.0
sh gcc 13.2.0
sh gcc 13.3.0
sh gcc 14.1.0
sh gcc 14.2.0
sh gcc 4.9.4
sh gcc 9.5.0
vast (trunk)
x64 msvc v19.0 (WINE)
x64 msvc v19.10 (WINE)
x64 msvc v19.14 (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.latest
x86 djgpp 4.9.4
x86 djgpp 5.5.0
x86 djgpp 6.4.0
x86 djgpp 7.2.0
x86 msvc v19.0 (WINE)
x86 msvc v19.10 (WINE)
x86 msvc v19.14 (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.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-64 Zapcc 190308
x86-64 clang (EricWF contracts)
x86-64 clang (amd-staging)
x86-64 clang (assertions trunk)
x86-64 clang (clangir)
x86-64 clang (dascandy contracts)
x86-64 clang (experimental -Wlifetime)
x86-64 clang (experimental P1061)
x86-64 clang (experimental P1144)
x86-64 clang (experimental P1221)
x86-64 clang (experimental P2996)
x86-64 clang (experimental P3068)
x86-64 clang (experimental P3309)
x86-64 clang (experimental P3367)
x86-64 clang (experimental P3372)
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)
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 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 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.4
x86-64 gcc 10.5
x86-64 gcc 11.1
x86-64 gcc 11.2
x86-64 gcc 11.3
x86-64 gcc 11.4
x86-64 gcc 12.1
x86-64 gcc 12.2
x86-64 gcc 12.3
x86-64 gcc 12.4
x86-64 gcc 13.1
x86-64 gcc 13.2
x86-64 gcc 13.3
x86-64 gcc 14.1
x86-64 gcc 14.2
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 2025.0.0
x86-64 icx 2025.0.0
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.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
#ifndef STD_EXPERIMENTAL_FIXED_CAPACITY_VECTOR #define STD_EXPERIMENTAL_FIXED_CAPACITY_VECTOR /// \file /// /// Dynamically-resizable vector with fixed-capacity. /// /// Copyright Gonzalo Brito Gadeschi 2015-2017 /// Copyright Eric Niebler 2013-2014 /// Copyright Casey Carter 2016 /// /// This file is released under the Boost Software License: // // Boost Software License - Version 1.0 - August 17th, 2003 // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // Some of the code has been adapted from the range-v3 library: // // https://github.com/ericniebler/range-v3/ // // which is also under the Boost Software license. // // Some of the code has been adapted from libc++: // // and is annotated with "adapted from libc++" below, and is thus under the // following license: // //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // #include <array> #include <cstddef> // for size_t #include <cstdint> // for fixed-width integer types #include <functional> // for less and equal_to #include <iterator> // for reverse_iterator and iterator traits #include <limits> // for numeric_limits #include <stdexcept> // for length_error #include <type_traits> // for aligned_storage and all meta-functions #include <stdio.h> // for assertion diagnostics /// Unreachable code #define FCV_UNREACHABLE __builtin_unreachable() /// Optimizer allowed to assume that EXPR evaluates to true #define FCV_ASSUME(EXPR) \ static_cast<void>((EXPR) ? void(0) : __builtin_unreachable()) /// Assert pretty printer #define FCV_ASSERT(...) \ static_cast<void>((__VA_ARGS__) \ ? void(0) \ : ::std::experimental::fcv_detail::assert_failure( \ static_cast<const char*>(__FILE__), __LINE__, \ "assertion failed: " #__VA_ARGS__)) /// Likely/unlikely branches #define FCV_LIKELY(boolean_expr) __builtin_expect(!!(boolean_expr), 1) #define FCV_UNLIKELY(boolean_expr) __builtin_expect(!!(boolean_expr), 0) /// Expect asserts the condition in debug builds and assumes the condition to be /// true in release builds. #ifdef NDEBUG #define FCV_EXPECT(EXPR) FCV_ASSUME(EXPR) #else #define FCV_EXPECT(EXPR) FCV_ASSERT(EXPR) #endif #define FCV_CONCEPT_PP_CAT_(X, Y) X##Y #define FCV_CONCEPT_PP_CAT(X, Y) FCV_CONCEPT_PP_CAT_(X, Y) /// Requires-clause emulation with SFINAE (for templates) #define FCV_REQUIRES_(...) \ int FCV_CONCEPT_PP_CAT(_concept_requires_, __LINE__) \ = 42, \ typename ::std::enable_if \ < (FCV_CONCEPT_PP_CAT(_concept_requires_, __LINE__) == 43) \ || (__VA_ARGS__), \ int > ::type = 0 /**/ /// Requires-clause emulation with SFINAE (for "non-templates") #define FCV_REQUIRES(...) \ template <int FCV_CONCEPT_PP_CAT(_concept_requires_, __LINE__) = 42, \ typename ::std::enable_if< \ (FCV_CONCEPT_PP_CAT(_concept_requires_, __LINE__) == 43) \ || (__VA_ARGS__), \ int>::type \ = 0> /**/ namespace std { namespace experimental { // Private utilites (each std lib should already have this) namespace fcv_detail { /// \name Utilities ///@{ template <class = void> [[noreturn]] void assert_failure(char const* file, int line, char const* msg) { fprintf(stderr, "%s(%d): %s\n", file, line, msg); abort(); } template <bool v> using bool_ = integral_constant<bool, v>; /// \name Concepts (poor-man emulation using type traits) ///@{ template <typename T, typename... Args> static constexpr bool Constructible = is_constructible_v<T, Args...>; template <typename T> static constexpr bool CopyConstructible = is_copy_constructible_v<T>; template <typename T> static constexpr bool MoveConstructible = is_move_constructible_v<T>; template <typename T, typename U> static constexpr bool Assignable = is_assignable_v<T, U>; template <typename T> static constexpr bool Movable = is_object_v<T>&& Assignable<T&, T>&& MoveConstructible<T>&& is_swappable_v<T&>; template <typename From, typename To> static constexpr bool Convertible = is_convertible_v<From, To>; template <typename T> static constexpr bool Trivial = is_trivial_v<T>; template <typename T> static constexpr bool Const = is_const_v<T>; template <typename T> static constexpr bool Pointer = is_pointer_v<T>; ///@} // Concepts template <typename Rng> using range_iterator_t = decltype(begin(declval<Rng>())); template <typename T> using iterator_reference_t = typename iterator_traits<T>::reference; template <typename T> using iterator_category_t = typename iterator_traits<T>::iterator_category; template <typename T, typename Cat, typename = void> struct Iterator_ : false_type { }; template <typename T, typename Cat> struct Iterator_<T, Cat, void_t<iterator_category_t<T>>> : bool_<Convertible<iterator_category_t<T>, Cat>> { }; /// \name Concepts (poor-man emulation using type traits) ///@{ template <typename T> static constexpr bool InputIterator = Iterator_<T, input_iterator_tag>{}; template <typename T> static constexpr bool ForwardIterator = Iterator_<T, forward_iterator_tag>{}; template <typename T> static constexpr bool OutputIterator = Iterator_<T, output_iterator_tag>{} || ForwardIterator<T>; template <typename T> static constexpr bool BidirectionalIterator = Iterator_<T, bidirectional_iterator_tag>{}; template <typename T> static constexpr bool RandomAccessIterator = Iterator_<T, random_access_iterator_tag>{}; template <typename T> static constexpr bool RandomAccessRange = RandomAccessIterator<range_iterator_t<T>>; ///@} // Concepts // clang-format off /// Smallest fixed-width unsigned integer type that can represent /// values in the range [0, N]. template <size_t N> using smallest_size_t = conditional_t<(N < numeric_limits<uint8_t>::max()), uint8_t, conditional_t<(N < numeric_limits<uint16_t>::max()), uint16_t, conditional_t<(N < numeric_limits<uint32_t>::max()), uint32_t, conditional_t<(N < numeric_limits<uint64_t>::max()), uint64_t, size_t>>>>; // clang-format on /// Index a range doing bound checks in debug builds template <typename Rng, typename Index, FCV_REQUIRES_(RandomAccessRange<Rng>)> constexpr decltype(auto) index(Rng&& rng, Index&& i) noexcept { FCV_EXPECT(static_cast<ptrdiff_t>(i) < (end(rng) - begin(rng))); return begin(::std::forward<Rng>(rng))[::std::forward<Index>(i)]; } /// \name Workarounds ///@{ // WORKAROUND: std::rotate is not constexpr template <typename ForwardIt, FCV_REQUIRES_(ForwardIterator<ForwardIt>)> constexpr void slow_rotate(ForwardIt first, ForwardIt n_first, ForwardIt last) { ForwardIt next = n_first; while (first != next) { swap(*(first++), *(next++)); if (next == last) { next = n_first; } else if (first == n_first) { n_first = next; } } } // WORKAROUND: std::move is not constexpr template <typename InputIt, typename OutputIt, FCV_REQUIRES_( InputIterator<InputIt>&& OutputIterator<OutputIt>)> constexpr OutputIt move(InputIt b, InputIt e, OutputIt to) { for (; b != e; ++b, (void)++to) { *to = ::std::move(*b); } return to; } // WORKAROUND: std::equal is not constexpr template <class BinaryPredicate, class InputIterator1, class InputIterator2, FCV_REQUIRES_(InputIterator<InputIterator1>&& InputIterator<InputIterator2>)> constexpr bool cmp(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { if (!pred(*first1, *first2)) { return false; } } return first1 == last1 && first2 == last2; } ///@} // Workarounds ///@} // Utilities /// Types implementing the `fixed_capactiy_vector`'s storage namespace storage { /// Storage for zero elements. template <typename T> struct zero_sized { using size_type = uint8_t; using value_type = T; using difference_type = ptrdiff_t; using pointer = T*; using const_pointer = T const*; /// Pointer to the data in the storage. static constexpr pointer data() noexcept { return nullptr; } /// Number of elements currently stored. static constexpr size_type size() noexcept { return 0; } /// Capacity of the storage. static constexpr size_type capacity() noexcept { return 0; } /// Is the storage empty? static constexpr bool empty() noexcept { return true; } /// Is the storage full? static constexpr bool full() noexcept { return true; } /// Constructs a new element at the end of the storage /// in-place. /// /// Increases size of the storage by one. /// Always fails for empty storage. template <typename... Args, FCV_REQUIRES_(Constructible<T, Args...>)> static constexpr void emplace_back(Args&&...) noexcept { FCV_EXPECT(false && "tried to emplace_back on empty storage"); } /// Removes the last element of the storage. /// Always fails for empty storage. static constexpr void pop_back() noexcept { FCV_EXPECT(false && "tried to pop_back on empty storage"); } /// Changes the size of the storage without adding or /// removing elements (unsafe). /// /// The size of an empty storage can only be changed to 0. static constexpr void unsafe_set_size( size_t new_size) noexcept { FCV_EXPECT( new_size == 0 && "tried to change size of empty storage to " "non-zero value"); } /// Destroys all elements of the storage in range [begin, /// end) without changings its size (unsafe). /// /// Nothing to destroy since the storage is empty. template <typename InputIt, FCV_REQUIRES_(InputIterator<InputIt>)> static constexpr void unsafe_destroy( InputIt /* begin */, InputIt /* end */) noexcept { } /// Destroys all elements of the storage without changing /// its size (unsafe). /// /// Nothing to destroy since the storage is empty. static constexpr void unsafe_destroy_all() noexcept { } constexpr zero_sized() = default; constexpr zero_sized(zero_sized const&) = default; constexpr zero_sized& operator =(zero_sized const&) = default; constexpr zero_sized(zero_sized&&) = default; constexpr zero_sized& operator=(zero_sized&&) = default; ~zero_sized() = default; /// Constructs an empty storage from an initializer list of /// zero elements. template <typename U, FCV_REQUIRES_(Convertible<U, T>)> constexpr zero_sized(initializer_list<U> il) noexcept { FCV_EXPECT( il.size() == 0 && "tried to construct storage::empty from a " "non-empty initializer list"); } }; /// Storage for trivial types. template <typename T, size_t Capacity> struct trivial { static_assert(Trivial<T>, "storage::trivial<T, C> requires Trivial<T>"); static_assert(Capacity != size_t{0}, "Capacity must be greater " "than zero (use " "storage::zero_sized instead)"); using size_type = smallest_size_t<Capacity>; using value_type = T; using difference_type = ptrdiff_t; using pointer = T*; using const_pointer = T const*; private: // If the value_type is const, make a const array of // non-const elements: using data_t = conditional_t< !Const<T>, array<T, Capacity>, const array<remove_const_t<T>, Capacity>>; alignas(alignof(T)) data_t data_{}; /// Number of elements allocated in the storage: size_type size_ = 0; public: /// Direct access to the underlying storage. /// /// Complexity: O(1) in time and space. constexpr const_pointer data() const noexcept { return data_.data(); } /// Direct access to the underlying storage. /// /// Complexity: O(1) in time and space. constexpr pointer data() noexcept { return data_.data(); } /// Number of elements in the storage. /// /// Complexity: O(1) in time and space. constexpr size_type size() const noexcept { return size_; } /// Maximum number of elements that can be allocated in the /// storage. /// /// Complexity: O(1) in time and space. static constexpr size_type capacity() noexcept { return Capacity; } /// Is the storage empty? constexpr bool empty() const noexcept { return size() == size_type{0}; } /// Is the storage full? constexpr bool full() const noexcept { return size() == Capacity; } /// Constructs an element in-place at the end of the /// storage. /// /// Complexity: O(1) in time and space. /// Contract: the storage is not full. template <typename... Args, FCV_REQUIRES_(Constructible<T, Args...>and Assignable<value_type&, T>)> constexpr void emplace_back(Args&&... args) noexcept { FCV_EXPECT(!full() && "tried to emplace_back on full storage!"); index(data_, size()) = T(::std::forward<Args>(args)...); unsafe_set_size(size() + 1); } /// Remove the last element from the container. /// /// Complexity: O(1) in time and space. /// Contract: the storage is not empty. constexpr void pop_back() noexcept { FCV_EXPECT(!empty() && "tried to pop_back from empty storage!"); unsafe_set_size(size() - 1); } /// (unsafe) Changes the container size to \p new_size. /// /// Contract: `new_size <= capacity()`. /// \warning No elements are constructed or destroyed. constexpr void unsafe_set_size(size_t new_size) noexcept { FCV_EXPECT(new_size <= Capacity && "new_size out-of-bounds [0, Capacity]"); size_ = size_type(new_size); } /// (unsafe) Destroy elements in the range [begin, end). /// /// \warning: The size of the storage is not changed. template <typename InputIt, FCV_REQUIRES_(InputIterator<InputIt>)> constexpr void unsafe_destroy(InputIt, InputIt) noexcept { } /// (unsafe) Destroys all elements of the storage. /// /// \warning: The size of the storage is not changed. static constexpr void unsafe_destroy_all() noexcept { } constexpr trivial() noexcept = default; constexpr trivial(trivial const&) noexcept = default; constexpr trivial& operator=(trivial const&) noexcept = default; constexpr trivial(trivial&&) noexcept = default; constexpr trivial& operator=(trivial&&) noexcept = default; ~trivial() = default; private: template <typename U, FCV_REQUIRES_(Convertible<U, T>)> static constexpr array<remove_const_t<T>, Capacity> unsafe_recast_init_list(initializer_list<U>& il) noexcept { FCV_EXPECT( il.size() <= capacity() && "trying to construct storage from an " "initializer_list " "whose size exceeds the storage capacity"); array<remove_const_t<T>, Capacity> d_{}; for (size_t i = 0, e = il.size(); i < e; ++i) { index(d_, i) = index(il, i); } return d_; } public: /// Constructor from initializer list. /// /// Contract: `il.size() <= capacity()`. template <typename U, FCV_REQUIRES_(Convertible<U, T>)> constexpr trivial(initializer_list<U> il) noexcept : data_(unsafe_recast_init_list(il)) { unsafe_set_size(static_cast<size_type>(il.size())); } }; /// Storage for non-trivial elements. template <typename T, size_t Capacity> struct non_trivial { static_assert( !Trivial<T>, "use storage::trivial for Trivial<T> elements"); static_assert(Capacity != size_t{0}, "Capacity must be greater than zero!"); /// Smallest size_type that can represent Capacity: using size_type = smallest_size_t<Capacity>; using value_type = T; using difference_type = ptrdiff_t; using pointer = T*; using const_pointer = T const*; private: /// Number of elements allocated in the embedded storage: size_type size_ = 0; using aligned_storage_t = aligned_storage_t<sizeof(remove_const_t<T>), alignof(remove_const_t<T>)>; using data_t = conditional_t<!Const<T>, aligned_storage_t, const aligned_storage_t>; alignas(alignof(T)) data_t data_[Capacity]{}; // FIXME: ^ this won't work for types with "broken" alignof // like SIMD types (one would also need to provide an // overload of operator new to make heap allocations of this // type work for these types). public: /// Direct access to the underlying storage. /// /// Complexity: O(1) in time and space. const_pointer data() const noexcept { return reinterpret_cast<const_pointer>(data_); } /// Direct access to the underlying storage. /// /// Complexity: O(1) in time and space. pointer data() noexcept { return reinterpret_cast<pointer>(data_); } /// Pointer to one-past-the-end. const_pointer end() const noexcept { return data() + size(); } /// Pointer to one-past-the-end. pointer end() noexcept { return data() + size(); } /// Number of elements in the storage. /// /// Complexity: O(1) in time and space. constexpr size_type size() const noexcept { return size_; } /// Maximum number of elements that can be allocated in the /// storage. /// /// Complexity: O(1) in time and space. static constexpr size_type capacity() noexcept { return Capacity; } /// Is the storage empty? constexpr bool empty() const noexcept { return size() == size_type{0}; } /// Is the storage full? constexpr bool full() const noexcept { return size() == Capacity; } /// Constructs an element in-place at the end of the /// embedded storage. /// /// Complexity: O(1) in time and space. /// Contract: the storage is not full. template <typename... Args, FCV_REQUIRES_(Constructible<T, Args...>)> void emplace_back(Args&&... args) noexcept( noexcept(new (end()) T(::std::forward<Args>(args)...))) { FCV_EXPECT(!full() && "tried to emplace_back on full storage"); new (end()) T(::std::forward<Args>(args)...); unsafe_set_size(size() + 1); } /// Remove the last element from the container. /// /// Complexity: O(1) in time and space. /// Contract: the storage is not empty. void pop_back() noexcept(is_nothrow_destructible_v<T>) { FCV_EXPECT(!empty() && "tried to pop_back from empty storage!"); auto ptr = end() - 1; ptr->~T(); unsafe_set_size(size() - 1); } /// (unsafe) Changes the container size to \p new_size. /// /// Contract: `new_size <= capacity()`. /// \warning No elements are constructed or destroyed. constexpr void unsafe_set_size(size_t new_size) noexcept { FCV_EXPECT(new_size <= Capacity && "new_size out-of-bounds [0, Capacity)"); size_ = size_type(new_size); } /// (unsafe) Destroy elements in the range [begin, end). /// /// \warning: The size of the storage is not changed. template <typename InputIt, FCV_REQUIRES_(InputIterator<InputIt>)> void unsafe_destroy(InputIt first, InputIt last) noexcept( is_nothrow_destructible_v<T>) { FCV_EXPECT(first >= data() && first <= end() && "first is out-of-bounds"); FCV_EXPECT(last >= data() && last <= end() && "last is out-of-bounds"); for (; first != last; ++first) { first->~T(); } } /// (unsafe) Destroys all elements of the storage. /// /// \warning: The size of the storage is not changed. void unsafe_destroy_all() noexcept( is_nothrow_destructible_v<T>) { unsafe_destroy(data(), end()); } constexpr non_trivial() = default; constexpr non_trivial(non_trivial const&) = default; constexpr non_trivial& operator=(non_trivial const&) = default; constexpr non_trivial(non_trivial&&) = default; constexpr non_trivial& operator=(non_trivial&&) = default; ~non_trivial() noexcept(is_nothrow_destructible_v<T>) { unsafe_destroy_all(); } /// Constructor from initializer list. /// /// Contract: `il.size() <= capacity()`. template <typename U, FCV_REQUIRES_(Convertible<U, T>)> constexpr non_trivial(initializer_list<U> il) noexcept( noexcept(emplace_back(index(il, 0)))) { FCV_EXPECT( il.size() <= capacity() && "trying to construct storage from an " "initializer_list " "whose size exceeds the storage capacity"); for (size_t i = 0; i < il.size(); ++i) { emplace_back(index(il, i)); } } }; /// Selects the vector storage. template <typename T, size_t Capacity> using _t = conditional_t< Capacity == 0, zero_sized<T>, conditional_t<Trivial<T>, trivial<T, Capacity>, non_trivial<T, Capacity>>>; } // namespace storage } // namespace fcv_detail /// Dynamically-resizable fixed-capacity vector. template <typename T, size_t Capacity> struct fixed_capacity_vector : private fcv_detail::storage::_t<T, Capacity> { private: static_assert(is_nothrow_destructible_v<T>, "T must be nothrow destructible"); using base_t = fcv_detail::storage::_t<T, Capacity>; using self = fixed_capacity_vector<T, Capacity>; using base_t::unsafe_destroy; using base_t::unsafe_destroy_all; using base_t::unsafe_set_size; public: using value_type = typename base_t::value_type; using difference_type = ptrdiff_t; using reference = value_type&; using const_reference = value_type const&; using pointer = typename base_t::pointer; using const_pointer = typename base_t::const_pointer; using iterator = typename base_t::pointer; using const_iterator = typename base_t::const_pointer; using size_type = size_t; using reverse_iterator = ::std::reverse_iterator<iterator>; using const_reverse_iterator = ::std::reverse_iterator<const_iterator>; /// \name Size / capacity ///@{ using base_t::empty; using base_t::full; /// Number of elements in the vector constexpr size_type size() const noexcept { return base_t::size(); } /// Maximum number of elements that can be allocated in the vector static constexpr size_type capacity() noexcept { return base_t::capacity(); } /// Maximum number of elements that can be allocated in the vector static constexpr size_type max_size() noexcept { return capacity(); } ///@} // Size / capacity /// \name Data access ///@{ using base_t::data; ///@} // Data access /// \name Iterators ///@{ constexpr iterator begin() noexcept { return data(); } constexpr const_iterator begin() const noexcept { return data(); } constexpr iterator end() noexcept { return data() + size(); } constexpr const_iterator end() const noexcept { return data() + size(); } reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } reverse_iterator rend() noexcept { return reverse_iterator(begin()); } const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } constexpr const_iterator cbegin() noexcept { return begin(); } constexpr const_iterator cbegin() const noexcept { return begin(); } constexpr const_iterator cend() noexcept { return end(); } constexpr const_iterator cend() const noexcept { return end(); } ///@} // Iterators private: /// \name Iterator bound-check utilites ///@{ template <typename It> constexpr void assert_iterator_in_range(It it) noexcept { static_assert(fcv_detail::Pointer<It>); FCV_EXPECT(begin() <= it && "iterator not in range"); FCV_EXPECT(it <= end() && "iterator not in range"); } template <typename It0, typename It1> constexpr void assert_valid_iterator_pair(It0 first, It1 last) noexcept { static_assert(fcv_detail::Pointer<It0>); static_assert(fcv_detail::Pointer<It1>); FCV_EXPECT(first <= last && "invalid iterator pair"); } template <typename It0, typename It1> constexpr void assert_iterator_pair_in_range(It0 first, It1 last) noexcept { assert_iterator_in_range(first); assert_iterator_in_range(last); assert_valid_iterator_pair(first, last); } ///@} public: /// \name Element access /// ///@{ /// Unchecked access to element at index \p pos (UB if index not in /// range) constexpr reference operator[](size_type pos) noexcept { return fcv_detail::index(*this, pos); } /// Unchecked access to element at index \p pos (UB if index not in /// range) constexpr const_reference operator[](size_type pos) const noexcept { return fcv_detail::index(*this, pos); } /// Checked access to element at index \p pos (throws `out_of_range` /// if index not in range) constexpr reference at(size_type pos) { if (FCV_UNLIKELY(pos >= size())) { throw out_of_range("fixed_capacity_vector::at"); } return fcv_detail::index(*this, pos); } /// Checked access to element at index \p pos (throws `out_of_range` /// if index not in range) constexpr const_reference at(size_type pos) const { if (FCV_UNLIKELY(pos >= size())) { throw out_of_range("fixed_capacity_vector::at"); } return fcv_detail::index(*this, pos); } /// constexpr reference front() noexcept { return fcv_detail::index(*this, 0); } constexpr const_reference front() const noexcept { return fcv_detail::index(*this, 0); } constexpr reference back() noexcept { FCV_EXPECT(!empty() && "calling back on an empty vector"); return fcv_detail::index(*this, size() - 1); } constexpr const_reference back() const noexcept { FCV_EXPECT(!empty() && "calling back on an empty vector"); return fcv_detail::index(*this, size() - 1); } ///@} // Element access /// \name Modifiers ///@{ using base_t::emplace_back; using base_t::pop_back; /// Clears the vector. constexpr void clear() noexcept { unsafe_destroy_all(); unsafe_set_size(0); } /// Appends \p value at the end of the vector. template <typename U, FCV_REQUIRES_(fcv_detail::Constructible<T, U>&& fcv_detail::Assignable<reference, U&&>)> constexpr void push_back(U&& value) noexcept( noexcept(emplace_back(::std::forward<U>(value)))) { FCV_EXPECT(!full() && "vector is full!"); emplace_back(::std::forward<U>(value)); } /// Appends a default constructed `T` at the end of the vector. FCV_REQUIRES(fcv_detail::Constructible<T, T>&& fcv_detail::Assignable<reference, T&&>) void push_back() noexcept(noexcept(emplace_back(T{}))) { FCV_EXPECT(!full() && "vector is full!"); emplace_back(T{}); } template <typename... Args, FCV_REQUIRES_(fcv_detail::Constructible<T, Args...>)> constexpr iterator emplace(const_iterator position, Args&&... args) noexcept( noexcept(move_insert(position, declval<value_type*>(), declval<value_type*>()))) { FCV_EXPECT(!full() && "tried emplace on full fixed_capacity_vector!"); assert_iterator_in_range(position); value_type a(::std::forward<Args>(args)...); return move_insert(position, &a, &a + 1); } FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr iterator insert( const_iterator position, const_reference x) noexcept(noexcept(insert(position, size_type(1), x))) { FCV_EXPECT(!full() && "tried insert on full fixed_capacity_vector!"); assert_iterator_in_range(position); return insert(position, size_type(1), x); } FCV_REQUIRES(fcv_detail::MoveConstructible<T>) constexpr iterator insert( const_iterator position, value_type&& x) noexcept(noexcept(move_insert(position, &x, &x + 1))) { FCV_EXPECT(!full() && "tried insert on full fixed_capacity_vector!"); assert_iterator_in_range(position); return move_insert(position, &x, &x + 1); } FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr iterator insert( const_iterator position, size_type n, const T& x) noexcept(noexcept(push_back(x))) { assert_iterator_in_range(position); const auto new_size = size() + n; FCV_EXPECT(new_size <= capacity() && "trying to insert beyond capacity!"); auto b = end(); while (n != 0) { push_back(x); --n; } auto writable_position = begin() + (position - begin()); fcv_detail::slow_rotate(writable_position, b, end()); return writable_position; } template <class InputIt, FCV_REQUIRES_( fcv_detail::InputIterator<InputIt>and fcv_detail::Constructible< value_type, fcv_detail::iterator_reference_t<InputIt>>)> constexpr iterator insert( const_iterator position, InputIt first, InputIt last) noexcept(noexcept(emplace_back(*first))) { assert_iterator_in_range(position); assert_valid_iterator_pair(first, last); if constexpr (fcv_detail::RandomAccessIterator<InputIt>) { FCV_EXPECT(size() + static_cast<size_type>(last - first) <= capacity() && "trying to insert beyond capacity!"); } auto b = end(); // insert at the end and then just rotate: // cannot use try in constexpr function // try { // if copy_constructor throws you get basic-guarantee? for (; first != last; ++first) { emplace_back(*first); } // } catch (...) { // erase(b, end()); // throw; // } auto writable_position = begin() + (position - begin()); fcv_detail::slow_rotate(writable_position, b, end()); return writable_position; } template <class InputIt, FCV_REQUIRES_(fcv_detail::InputIterator<InputIt>)> constexpr iterator move_insert( const_iterator position, InputIt first, InputIt last) noexcept(noexcept(emplace_back(::std::move(*first)))) { assert_iterator_in_range(position); assert_valid_iterator_pair(first, last); if constexpr (fcv_detail::RandomAccessIterator<InputIt>) { FCV_EXPECT(size() + static_cast<size_type>(last - first) <= capacity() && "trying to insert beyond capacity!"); } iterator b = end(); // we insert at the end and then just rotate: for (; first != last; ++first) { emplace_back(::std::move(*first)); } auto writable_position = begin() + (position - begin()); fcv_detail::slow_rotate<iterator>(writable_position, b, end()); return writable_position; } FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr iterator insert( const_iterator position, initializer_list<T> il) noexcept(noexcept(insert(position, il.begin(), il.end()))) { assert_iterator_in_range(position); return insert(position, il.begin(), il.end()); } FCV_REQUIRES(fcv_detail::Movable<value_type>) constexpr iterator erase(const_iterator position) noexcept { assert_iterator_in_range(position); return erase(position, position + 1); } FCV_REQUIRES(fcv_detail::Movable<value_type>) constexpr iterator erase(const_iterator first, const_iterator last) noexcept { assert_iterator_pair_in_range(first, last); iterator p = begin() + (first - begin()); if (first != last) { unsafe_destroy( fcv_detail::move(p + (last - first), end(), p), end()); unsafe_set_size(size() - static_cast<size_type>(last - first)); } return p; } FCV_REQUIRES(fcv_detail::Assignable<T&, T&&>) constexpr void swap(fixed_capacity_vector& other) noexcept( is_nothrow_swappable_v<T>) { fixed_capacity_vector tmp = ::std::move(other); other = ::std::move(*this); (*this) = ::std::move(tmp); } /// Resizes the container to contain \p sz elements. If elements /// need to be appended, these are copy-constructed from \p value. /// FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr void resize(size_type sz, T const& value) noexcept( is_nothrow_copy_constructible_v<T>) { if (sz == size()) { return; } if (sz > size()) { FCV_EXPECT(sz <= capacity() && "fixed_capacity_vector cannot be resized to " "a size greater than capacity"); insert(end(), sz - size(), value); } else { erase(end() - (size() - sz), end()); } } private: FCV_REQUIRES(fcv_detail::MoveConstructible< T> or fcv_detail::CopyConstructible<T>) constexpr void emplace_n(size_type n) noexcept( (fcv_detail::MoveConstructible< T> && is_nothrow_move_constructible_v<T>) || (fcv_detail::CopyConstructible< T> && is_nothrow_copy_constructible_v<T>)) { FCV_EXPECT(n <= capacity() && "fixed_capacity_vector cannot be " "resized to a size greater than " "capacity"); while (n != size()) { emplace_back(T{}); } } public: /// Resizes the container to contain \p sz elements. If elements /// need to be appended, these are move-constructed from `T{}` (or /// copy-constructed if `T` is not `fcv_detail::MoveConstructible`). FCV_REQUIRES(fcv_detail::Movable<value_type>) constexpr void resize(size_type sz) noexcept( (fcv_detail::MoveConstructible< T> && is_nothrow_move_constructible_v<T>) || (fcv_detail::CopyConstructible< T> && is_nothrow_copy_constructible_v<T>)) { if (sz == size()) { return; } if (sz > size()) { emplace_n(sz); } else { erase(end() - (size() - sz), end()); } } ///@} // Modifiers /// \name Construct/copy/move/destroy ///@{ /// Default constructor. constexpr fixed_capacity_vector() = default; /// Copy constructor. FCV_REQUIRES(fcv_detail::CopyConstructible<value_type>) constexpr fixed_capacity_vector( fixed_capacity_vector const& other) noexcept(noexcept(insert(begin(), other.begin(), other.end()))) { // nothin to assert: size of other cannot exceed capacity // because both vectors have the same type insert(begin(), other.begin(), other.end()); } /// Move constructor. FCV_REQUIRES(fcv_detail::MoveConstructible<value_type>) constexpr fixed_capacity_vector( fixed_capacity_vector&& other) noexcept(noexcept(move_insert(begin(), other.begin(), other.end()))) { // nothin to assert: size of other cannot exceed capacity // because both vectors have the same type move_insert(begin(), other.begin(), other.end()); } /// Copy assignment. FCV_REQUIRES(fcv_detail::Assignable<reference, const_reference>) constexpr fixed_capacity_vector& operator=(fixed_capacity_vector const& other) noexcept( noexcept(clear()) && noexcept(insert(begin(), other.begin(), other.end()))) { // nothin to assert: size of other cannot exceed capacity // because both vectors have the same type clear(); insert(this->begin(), other.begin(), other.end()); return *this; } /// Move assignment. FCV_REQUIRES(fcv_detail::Assignable<reference, reference>) constexpr fixed_capacity_vector& operator=(fixed_capacity_vector&& other) noexcept( noexcept(clear()) and noexcept(move_insert(begin(), other.begin(), other.end()))) { // nothin to assert: size of other cannot exceed capacity // because both vectors have the same type clear(); move_insert(this->begin(), other.begin(), other.end()); return *this; } /// Initializes vector with \p n default-constructed elements. FCV_REQUIRES(fcv_detail::CopyConstructible< T> or fcv_detail::MoveConstructible<T>) explicit constexpr fixed_capacity_vector(size_type n) noexcept( noexcept(emplace_n(n))) { FCV_EXPECT(n <= capacity() && "size exceeds capacity"); emplace_n(n); } /// Initializes vector with \p n with \p value. FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr fixed_capacity_vector( size_type n, T const& value) noexcept(noexcept(insert(begin(), n, value))) { FCV_EXPECT(n <= capacity() && "size exceeds capacity"); insert(begin(), n, value); } /// Initialize vector from range [first, last). template <class InputIt, FCV_REQUIRES_(fcv_detail::InputIterator<InputIt>)> constexpr fixed_capacity_vector(InputIt first, InputIt last) { if constexpr (fcv_detail::RandomAccessIterator<InputIt>) { FCV_EXPECT(last - first >= 0); FCV_EXPECT(static_cast<size_type>(last - first) <= capacity() && "range size exceeds capacity"); } insert(begin(), first, last); } template <typename U, FCV_REQUIRES_(fcv_detail::Convertible<U, value_type>)> constexpr fixed_capacity_vector(initializer_list<U> il) noexcept( noexcept(base_t(::std::move(il)))) : base_t(::std::move(il)) { // assert happens in base_t constructor } template <class InputIt, FCV_REQUIRES_(fcv_detail::InputIterator<InputIt>)> constexpr void assign(InputIt first, InputIt last) noexcept( noexcept(clear()) and noexcept(insert(begin(), first, last))) { if constexpr (fcv_detail::RandomAccessIterator<InputIt>) { FCV_EXPECT(last - first >= 0); FCV_EXPECT(static_cast<size_type>(last - first) <= capacity() && "range size exceeds capacity"); } clear(); insert(begin(), first, last); } FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr void assign(size_type n, const T& u) { FCV_EXPECT(n <= capacity() && "size exceeds capacity"); clear(); insert(begin(), n, u); } FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr void assign(initializer_list<T> const& il) { FCV_EXPECT(il.size() <= capacity() && "initializer_list size exceeds capacity"); clear(); insert(this->begin(), il.begin(), il.end()); } FCV_REQUIRES(fcv_detail::CopyConstructible<T>) constexpr void assign(initializer_list<T>&& il) { FCV_EXPECT(il.size() <= capacity() && "initializer_list size exceeds capacity"); clear(); insert(this->begin(), il.begin(), il.end()); } ///@} // Construct/copy/move/destroy/assign }; template <typename T, size_t Capacity> constexpr bool operator==( fixed_capacity_vector<T, Capacity> const& a, fixed_capacity_vector<T, Capacity> const& b) noexcept { return a.size() == b.size() and fcv_detail::cmp(a.begin(), a.end(), b.begin(), b.end(), equal_to<>{}); } template <typename T, size_t Capacity> constexpr bool operator<( fixed_capacity_vector<T, Capacity> const& a, fixed_capacity_vector<T, Capacity> const& b) noexcept { return fcv_detail::cmp(a.begin(), a.end(), b.begin(), b.end(), less<>{}); } template <typename T, size_t Capacity> constexpr bool operator!=( fixed_capacity_vector<T, Capacity> const& a, fixed_capacity_vector<T, Capacity> const& b) noexcept { return not(a == b); } template <typename T, size_t Capacity> constexpr bool operator<=( fixed_capacity_vector<T, Capacity> const& a, fixed_capacity_vector<T, Capacity> const& b) noexcept { return fcv_detail::cmp(a.begin(), a.end(), b.begin(), b.end(), less_equal<>{}); } template <typename T, size_t Capacity> constexpr bool operator>( fixed_capacity_vector<T, Capacity> const& a, fixed_capacity_vector<T, Capacity> const& b) noexcept { return fcv_detail::cmp(a.begin(), a.end(), b.begin(), b.end(), greater<>{}); } template <typename T, size_t Capacity> constexpr bool operator>=( fixed_capacity_vector<T, Capacity> const& a, fixed_capacity_vector<T, Capacity> const& b) noexcept { return fcv_detail::cmp(a.begin(), a.end(), b.begin(), b.end(), greater_equal<>{}); } } // namespace experimental } // namespace std // undefine all the internal macros #undef FCV_UNREACHABLE #undef FCV_ASSUME #undef FCV_ASSERT #undef FCV_LIKELY #undef FCV_UNLIKELY #undef FCV_EXPECT #undef FCV_CONCEPT_PP_CAT_ #undef FCV_CONCEPT_PP_CAT #undef FCV_REQUIRES_ #undef FCV_REQUIRES #endif // STD_EXPERIMENTAL_FIXED_CAPACITY_VECTOR
c++ source #2
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 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 14.1.0
ARM GCC 14.1.0 (unknown-eabi)
ARM GCC 14.2.0
ARM GCC 14.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 (WINE)
ARM msvc v19.10 (WINE)
ARM msvc v19.14 (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 13.1.0
ARM64 gcc 13.2.0
ARM64 gcc 13.3.0
ARM64 gcc 14.1.0
ARM64 gcc 14.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 (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 13.1.0
AVR gcc 13.2.0
AVR gcc 13.3.0
AVR gcc 14.1.0
AVR gcc 14.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 gcc 13.1.0
BPF gcc 13.2.0
BPF gcc 13.3.0
BPF gcc trunk
EDG (experimental reflection)
EDG 6.5
EDG 6.5 (GNU mode gcc 13)
EDG 6.6
EDG 6.6 (GNU mode gcc 13)
FRC 2019
FRC 2020
FRC 2023
HPPA gcc 14.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
M68K gcc 13.1.0
M68K gcc 13.2.0
M68K gcc 13.3.0
M68K gcc 14.1.0
M68K gcc 14.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
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 13.1.0
RISC-V (32-bits) gcc 13.2.0
RISC-V (32-bits) gcc 13.3.0
RISC-V (32-bits) gcc 14.1.0
RISC-V (32-bits) gcc 14.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 13.1.0
RISC-V (64-bits) gcc 13.2.0
RISC-V (64-bits) gcc 13.3.0
RISC-V (64-bits) gcc 14.1.0
RISC-V (64-bits) gcc 14.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 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 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 13.1.0
SPARC LEON gcc 13.2.0
SPARC LEON gcc 13.3.0
SPARC LEON gcc 14.1.0
SPARC LEON gcc 14.2.0
SPARC gcc 12.2.0
SPARC gcc 12.3.0
SPARC gcc 12.4.0
SPARC gcc 13.1.0
SPARC gcc 13.2.0
SPARC gcc 13.3.0
SPARC gcc 14.1.0
SPARC gcc 14.2.0
SPARC64 gcc 12.2.0
SPARC64 gcc 12.3.0
SPARC64 gcc 12.4.0
SPARC64 gcc 13.1.0
SPARC64 gcc 13.2.0
SPARC64 gcc 13.3.0
SPARC64 gcc 14.1.0
SPARC64 gcc 14.2.0
TI C6x gcc 12.2.0
TI C6x gcc 12.3.0
TI C6x gcc 12.4.0
TI C6x gcc 13.1.0
TI C6x gcc 13.2.0
TI C6x gcc 13.3.0
TI C6x gcc 14.1.0
TI C6x gcc 14.2.0
TI CL430 21.6.1
VAX gcc NetBSDELF 10.4.0
VAX gcc NetBSDELF 10.5.0 (Nov 15 03:50:22 2023)
WebAssembly clang (trunk)
Xtensa ESP32 gcc 11.2.0 (2022r1)
Xtensa ESP32 gcc 12.2.0 (20230208)
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 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 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.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 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 9.0.0
armv8-a clang 9.0.1
clang-cl 18.1.0
ellcc 0.1.33
ellcc 0.1.34
ellcc 2017-07-16
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 13.1.0
loongarch64 gcc 13.2.0
loongarch64 gcc 13.3.0
loongarch64 gcc 14.1.0
loongarch64 gcc 14.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 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 13.1.0
mips gcc 13.2.0
mips gcc 13.3.0
mips gcc 14.1.0
mips gcc 14.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 13.1.0
mips64 (el) gcc 13.2.0
mips64 (el) gcc 13.3.0
mips64 (el) gcc 14.1.0
mips64 (el) gcc 14.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 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 13.1.0
mips64 gcc 13.2.0
mips64 gcc 13.3.0
mips64 gcc 14.1.0
mips64 gcc 14.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
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 gcc 12.1.0
mipsel gcc 12.2.0
mipsel gcc 12.3.0
mipsel gcc 12.4.0
mipsel gcc 13.1.0
mipsel gcc 13.2.0
mipsel gcc 13.3.0
mipsel gcc 14.1.0
mipsel gcc 14.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 13.1.0
power gcc 13.2.0
power gcc 13.3.0
power gcc 14.1.0
power gcc 14.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 13.1.0
power64 gcc 13.2.0
power64 gcc 13.3.0
power64 gcc 14.1.0
power64 gcc 14.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 13.1.0
power64le gcc 13.2.0
power64le gcc 13.3.0
power64le gcc 14.1.0
power64le gcc 14.2.0
power64le gcc 6.3.0
power64le gcc trunk
powerpc64 clang (trunk)
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 13.1.0
s390x gcc 13.2.0
s390x gcc 13.3.0
s390x gcc 14.1.0
s390x gcc 14.2.0
sh gcc 12.2.0
sh gcc 12.3.0
sh gcc 12.4.0
sh gcc 13.1.0
sh gcc 13.2.0
sh gcc 13.3.0
sh gcc 14.1.0
sh gcc 14.2.0
sh gcc 4.9.4
sh gcc 9.5.0
vast (trunk)
x64 msvc v19.0 (WINE)
x64 msvc v19.10 (WINE)
x64 msvc v19.14 (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.latest
x86 djgpp 4.9.4
x86 djgpp 5.5.0
x86 djgpp 6.4.0
x86 djgpp 7.2.0
x86 msvc v19.0 (WINE)
x86 msvc v19.10 (WINE)
x86 msvc v19.14 (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.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-64 Zapcc 190308
x86-64 clang (EricWF contracts)
x86-64 clang (amd-staging)
x86-64 clang (assertions trunk)
x86-64 clang (clangir)
x86-64 clang (dascandy contracts)
x86-64 clang (experimental -Wlifetime)
x86-64 clang (experimental P1061)
x86-64 clang (experimental P1144)
x86-64 clang (experimental P1221)
x86-64 clang (experimental P2996)
x86-64 clang (experimental P3068)
x86-64 clang (experimental P3309)
x86-64 clang (experimental P3367)
x86-64 clang (experimental P3372)
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)
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 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 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.4
x86-64 gcc 10.5
x86-64 gcc 11.1
x86-64 gcc 11.2
x86-64 gcc 11.3
x86-64 gcc 11.4
x86-64 gcc 12.1
x86-64 gcc 12.2
x86-64 gcc 12.3
x86-64 gcc 12.4
x86-64 gcc 13.1
x86-64 gcc 13.2
x86-64 gcc 13.3
x86-64 gcc 14.1
x86-64 gcc 14.2
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 2025.0.0
x86-64 icx 2025.0.0
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.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
/// \file /// /// Test for inline_vector /// /// Most of the tests below are adapted from libc++: https://libcxx.llvm.org /// under the following license: //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "static_vector.hpp" #include <memory> #include <string> #include <vector> #include <iostream> #define FCV_ASSERT(...) \ static_cast<void>((__VA_ARGS__) \ ? void(0) \ : ::std::experimental::fcv_detail::assert_failure( \ static_cast<const char*>(__FILE__), __LINE__, \ "assertion failed: " #__VA_ARGS__)) template struct std::experimental::fcv_detail::storage::zero_sized<int>; template struct std::experimental::fcv_detail::storage::trivial<int, 10>; template struct std::experimental::fcv_detail::storage::non_trivial< std::unique_ptr<int>, 10>; template struct std::experimental::fcv_detail::storage::zero_sized<const int>; template struct std::experimental::fcv_detail::storage::trivial<const int, 10>; template struct std::experimental::fcv_detail::storage::non_trivial< const std::unique_ptr<int>, 10>; // empty: template struct std::experimental::fixed_capacity_vector<int, 0>; // trivial non-empty: template struct std::experimental::fixed_capacity_vector<int, 1>; template struct std::experimental::fixed_capacity_vector<int, 2>; template struct std::experimental::fixed_capacity_vector<const int, 3>; // non-trivial template struct std::experimental::fixed_capacity_vector<std::string, 3>; template struct std::experimental::fixed_capacity_vector<const std::string, 3>; // move-only: template struct std::experimental::fixed_capacity_vector<std::unique_ptr<int>, 3>; template struct std::experimental::fixed_capacity_vector< const std::unique_ptr<int>, 3>; struct [[gsl::suppress("cppcoreguidelines-special-member-functions")]] tint { std::size_t i; tint() = default; constexpr tint(tint const&) = default; constexpr tint(tint &&) = default; constexpr tint& operator=(tint const&) = default; constexpr tint& operator=(tint&&) = default; // FIXME: ~tint() = default; // ^^^ adding this makes the class non-trivial in clang explicit constexpr tint(std::size_t j) : i(j) { } explicit operator std::size_t() { return i; } }; static_assert(std::is_trivial<tint>{} and std::is_copy_constructible<tint>{} and std::is_move_constructible<tint>{}, ""); // Explicit instantiations template struct std::experimental::fixed_capacity_vector<tint, 0>; // trivial empty template struct std::experimental::fixed_capacity_vector<tint, 1>; // trivial // non-empty template struct std::experimental::fixed_capacity_vector<tint, 2>; // trivial // nom-empty template struct std::experimental::fixed_capacity_vector<tint, 3>; // trivial // nom-empty struct moint final { std::size_t i = 0; moint() = default; moint(moint const&) = delete; moint& operator=(moint const&) = delete; moint(moint&&) = default; moint& operator=(moint&&) = default; ~moint() = default; explicit operator std::size_t() { return i; } explicit constexpr moint(std::size_t j) : i(j) { } // it seems that deleting the copy constructor is not enough to make // this non-trivial using libstdc++: virtual void foo() { } bool operator==(moint b) { return i == b.i; } }; static_assert(!std::is_trivial<moint>{} and !std::is_copy_constructible<moint>{} and std::is_move_constructible<moint>{}, ""); // cannot explicitly instantiate the type for some types // // non-trivial empty: // template struct std::experimental::fixed_capacity_vector<moint, 0>; // // non-trivial non-empty: // template struct std::experimental::fixed_capacity_vector<moint, 1>; // template struct std::experimental::fixed_capacity_vector<moint, 2>; // template struct std::experimental::fixed_capacity_vector<moint, 3>; template <typename T, std::size_t N> using vector = std::experimental::fixed_capacity_vector<T, N>; template <typename T, std::size_t N> constexpr bool test_bounds(vector<T, N> const& v, std::size_t sz) { FCV_ASSERT(v.size() == sz); FCV_ASSERT(v.max_size() == N); FCV_ASSERT(v.capacity() == N); std::decay_t<T> count = std::decay_t<T>(); for (std::size_t i = 0; i != sz; ++i) { ++count; FCV_ASSERT(v[i] == count); } return true; } class non_copyable { int i_; double d_; public: non_copyable(const non_copyable&) = delete; non_copyable& operator=(const non_copyable&) = delete; non_copyable(int i, double d) : i_(i), d_(d) { } non_copyable(non_copyable&& a) noexcept : i_(a.i_), d_(a.d_) { a.i_ = 0; a.d_ = 0; } non_copyable& operator=(non_copyable&& a) noexcept { i_ = a.i_; d_ = a.d_; a.i_ = 0; a.d_ = 0; return *this; } int geti() const { return i_; } double getd() const { return d_; } }; template <typename T, int N> struct vec { vec() = default; vec(std::initializer_list<T> /*il*/) { } }; int main() { { // storage using std::experimental::fcv_detail::storage::_t; using std::experimental::fcv_detail::storage::non_trivial; using std::experimental::fcv_detail::storage::trivial; using std::experimental::fcv_detail::storage::zero_sized; static_assert(std::is_same<_t<int, 0>, zero_sized<int>>{}); static_assert(std::is_same<_t<int, 10>, trivial<int, 10>>{}); static_assert(std::is_same<_t<std::unique_ptr<int>, 10>, non_trivial<std::unique_ptr<int>, 10>>{}, ""); constexpr _t<int, 10> s({1, 2, 3, 4}); static_assert(s.size() == 4); constexpr _t<const int, 10> s2({1, 2, 3, 4}); static_assert(s2.size() == 4); } { // const vector<const int, 0> v0 = {}; test_bounds(v0, 0); constexpr vector<const int, 0> vc0 = {}; test_bounds(vc0, 0); static_assert(test_bounds(vc0, 0), ""); // one and two elements initializer_list don't work vector<const int, 1> v1 = {1}; test_bounds(v1, 1); // // constexpr vector<const int, 1> vc1 = {1}; // test_bounds(vc1, 1); // static_assert(test_bounds(vc1, 1), ""); vector<const int, 3> v3 = {1, 2, 3}; test_bounds(v3, 3); constexpr vector<const int, 3> vc3 = {1, 2, 3}; test_bounds(vc3, 3); static_assert(test_bounds(vc3, 3), ""); } auto test_contiguous = [](auto&& c) { for (size_t i = 0; i < c.size(); ++i) { FCV_ASSERT(*(c.begin() + i) == *(std::addressof(*c.begin()) + i)); } }; { // contiguous using T = int; using C = vector<T, 3>; auto e = C(); FCV_ASSERT(e.empty()); test_contiguous(e); test_contiguous(C(3, 5)); } { // default construct element using T = int; using C = vector<T, 3>; C c(1); FCV_ASSERT(c.back() == 0); FCV_ASSERT(c.front() == 0); FCV_ASSERT(c[0] == 0); } { // iterator using T = int; using C = vector<T, 3>; C c; C::iterator i = c.begin(); C::iterator j = c.end(); FCV_ASSERT(std::distance(i, j) == 0); FCV_ASSERT(i == j); } { // const iterator using T = int; using C = vector<T, 3>; const C c{}; C::const_iterator i = c.begin(); C::const_iterator j = c.end(); FCV_ASSERT(std::distance(i, j) == 0); FCV_ASSERT(i == j); } { // cbegin/cend using T = int; using C = vector<T, 3>; C c; C::const_iterator i = c.cbegin(); C::const_iterator j = c.cend(); FCV_ASSERT(std::distance(i, j) == 0); FCV_ASSERT(i == j); FCV_ASSERT(i == c.end()); } { // iterator constructor using T = int; using C = vector<T, 10>; const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; C c(std::begin(t), std::end(t)); FCV_ASSERT( std::equal(std::begin(t), std::end(t), std::begin(c), std::end(c))); C::iterator i = c.begin(); FCV_ASSERT(*i == 0); ++i; FCV_ASSERT(*i == 1); *i = 10; FCV_ASSERT(*i == 10); FCV_ASSERT(std::distance(std::begin(c), std::end(c)) == 10); } { // N3644 testing using C = vector<int, 10>; C::iterator ii1{}, ii2{}; C::iterator ii4 = ii1; C::const_iterator cii{}; FCV_ASSERT(ii1 == ii2); FCV_ASSERT(ii1 == ii4); FCV_ASSERT(!(ii1 != ii2)); FCV_ASSERT((ii1 == cii)); FCV_ASSERT((cii == ii1)); FCV_ASSERT(!(ii1 != cii)); FCV_ASSERT(!(cii != ii1)); FCV_ASSERT(!(ii1 < cii)); FCV_ASSERT(!(cii < ii1)); FCV_ASSERT((ii1 <= cii)); FCV_ASSERT((cii <= ii1)); FCV_ASSERT(!(ii1 > cii)); FCV_ASSERT(!(cii > ii1)); FCV_ASSERT((ii1 >= cii)); FCV_ASSERT((cii >= ii1)); FCV_ASSERT((cii - ii1) == 0); FCV_ASSERT((ii1 - cii) == 0); } { // capacity vector<int, 10> a; static_assert(a.capacity() == std::size_t(10)); FCV_ASSERT(a.empty()); for (std::size_t i = 0; i != 10; ++i) { a.push_back(0); } static_assert(a.capacity() == std::size_t(10)); FCV_ASSERT(a.size() == std::size_t(10)); FCV_ASSERT(!a.empty()); } { // resize copyable using Copyable = int; vector<Copyable, 10> a(std::size_t(10), 5); FCV_ASSERT(a.size() == std::size_t(10)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); for (std::size_t i = 0; i != 10; ++i) { FCV_ASSERT(a[i] == 5); } a.resize(5); FCV_ASSERT(a.size() == std::size_t(5)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); a.resize(9); FCV_ASSERT(a[4] == 5); for (std::size_t i = 5; i != 9; ++i) { FCV_ASSERT(a[i] == 0); } FCV_ASSERT(a.size() == std::size_t(9)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); a.resize(10, 3); FCV_ASSERT(a[4] == 5); FCV_ASSERT(a[8] == 0); FCV_ASSERT(a[9] == 3); FCV_ASSERT(a.size() == std::size_t(10)); static_assert(a.capacity() == std::size_t(10)); a.resize(5, 2); for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(a[i] == 5); } test_contiguous(a); } { // resize move-only using MoveOnly = std::unique_ptr<int>; vector<MoveOnly, 10> a(10); FCV_ASSERT(a.size() == std::size_t(10)); static_assert(a.capacity() == std::size_t(10)); a.resize(5); test_contiguous(a); FCV_ASSERT(a.size() == std::size_t(5)); static_assert(a.capacity() == std::size_t(10)); a.resize(9); FCV_ASSERT(a.size() == std::size_t(9)); static_assert(a.capacity() == std::size_t(10)); } { // resize value: using Copyable = int; vector<Copyable, 10> a(std::size_t(10)); FCV_ASSERT(a.size() == std::size_t(10)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); for (std::size_t i = 0; i != 10; ++i) { FCV_ASSERT(a[i] == 0); } a.resize(5); FCV_ASSERT(a.size() == std::size_t(5)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(a[i] == 0); } a.resize(9, 5); for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(a[i] == 0); } for (std::size_t i = 5; i != 9; ++i) { FCV_ASSERT(a[i] == 5); } FCV_ASSERT(a.size() == std::size_t(9)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); a.resize(10, 3); for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(a[i] == 0); } for (std::size_t i = 5; i != 9; ++i) { FCV_ASSERT(a[i] == 5); } FCV_ASSERT(a[9] == 3); FCV_ASSERT(a.size() == std::size_t(10)); static_assert(a.capacity() == std::size_t(10)); test_contiguous(a); } { // assign copy vector<int, 3> z(3, 5); vector<int, 3> a = {0, 1, 2}; FCV_ASSERT(a.size() == std::size_t{3}); vector<int, 3> b; FCV_ASSERT(b.size() == std::size_t{0}); b = a; FCV_ASSERT(b.size() == std::size_t{3}); FCV_ASSERT( std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b))); } { // copy construct vector<int, 3> a = {0, 1, 2}; FCV_ASSERT(a.size() == std::size_t{3}); vector<int, 3> b(a); FCV_ASSERT(b.size() == std::size_t{3}); FCV_ASSERT( std::equal(std::begin(a), std::end(a), std::begin(b), std::end(b))); } { // assign move using MoveOnly = std::unique_ptr<int>; vector<MoveOnly, 3> a(3); FCV_ASSERT(a.size() == std::size_t{3}); vector<MoveOnly, 3> b; FCV_ASSERT(b.size() == std::size_t{0}); b = std::move(a); FCV_ASSERT(b.size() == std::size_t{3}); [[gsl::suppress("misc-use-after-move")]] { FCV_ASSERT(a.size() == std::size_t{3}); } } { // move construct using MoveOnly = std::unique_ptr<int>; vector<MoveOnly, 3> a(3); FCV_ASSERT(a.size() == std::size_t{3}); vector<MoveOnly, 3> b(std::move(a)); FCV_ASSERT(b.size() == std::size_t{3}); [[gsl::suppress("misc-use-after-move")]] { FCV_ASSERT(a.size() == std::size_t{3}); } } { // old tests using vec_t = vector<int, 5>; vec_t vec1(5); vec1[0] = 0; vec1[1] = 1; vec1[2] = 2; vec1[3] = 3; vec1[4] = 4; { vec_t vec2; vec2.push_back(5); vec2.push_back(6); vec2.push_back(7); vec2.push_back(8); vec2.push_back(9); FCV_ASSERT(vec1[0] == 0); FCV_ASSERT(vec1[4] == 4); FCV_ASSERT(vec2[0] == 5); FCV_ASSERT(vec2[4] == 9); } { auto vec2 = vec1; FCV_ASSERT(vec2[0] == 0); FCV_ASSERT(vec2[4] == 4); FCV_ASSERT(vec1[0] == 0); FCV_ASSERT(vec1[4] == 4); } { int count_ = 0; for (auto i : vec1) { FCV_ASSERT(i == count_); count_++; } } { std::vector<int> vec2(5); vec2[0] = 4; vec2[1] = 3; vec2[2] = 2; vec2[3] = 1; vec2[4] = 0; vec_t vec(vec2.size()); copy(std::begin(vec2), std::end(vec2), std::begin(vec)); int count_ = 4; for (auto i : vec) { FCV_ASSERT(i == count_); count_--; } } } { using vec_t = vector<int, 0>; static_assert(sizeof(vec_t) == 1, ""); constexpr auto a = vec_t{}; static_assert(a.size() == std::size_t{0}, ""); } { // back and front: using C = vector<int, 2>; C c(1); FCV_ASSERT(c.back() == 0); FCV_ASSERT(c.front() == 0); FCV_ASSERT(c[0] == 0); c.clear(); int one = 1; c.push_back(one); FCV_ASSERT(c.back() == 1); FCV_ASSERT(c.front() == 1); FCV_ASSERT(c[0] == 1); FCV_ASSERT(c.size() == 1); c.push_back(2); FCV_ASSERT(c.back() == 2); FCV_ASSERT(c.front() == 1); FCV_ASSERT(c[0] == 1); FCV_ASSERT(c[1] == 2); FCV_ASSERT(c.size() == 2); c.pop_back(); FCV_ASSERT(c.front() == 1); FCV_ASSERT(c[0] == 1); FCV_ASSERT(c.back() == 1); c.pop_back(); FCV_ASSERT(c.empty()); } { // const back: using C = vector<int, 2>; constexpr C c(1); static_assert(c.back() == 0); static_assert(c.front() == 0); static_assert(c[0] == 0); static_assert(c.size() == 1); } { // swap: same type using C = vector<int, 5>; C c0(3, 5); C c1(5, 1); C c2(0); FCV_ASSERT(c0.size() == std::size_t(3)); FCV_ASSERT(c1.size() == std::size_t(5)); FCV_ASSERT(c2.size() == std::size_t(0)); for (std::size_t i = 0; i != 3; ++i) { FCV_ASSERT(c0[i] == 5); } for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(c1[i] == 1); } c0.swap(c1); FCV_ASSERT(c0.size() == std::size_t(5)); FCV_ASSERT(c1.size() == std::size_t(3)); for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(c0[i] == 1); } for (std::size_t i = 0; i != 3; ++i) { FCV_ASSERT(c1[i] == 5); } c2.swap(c1); FCV_ASSERT(c1.size() == std::size_t(0)); FCV_ASSERT(c2.size() == std::size_t(3)); for (std::size_t i = 0; i != 3; ++i) { FCV_ASSERT(c2[i] == 5); } } { // std::swap: same type using C = vector<int, 5>; C c0(3, 5); C c1(5, 1); C c2(0); FCV_ASSERT(c0.size() == std::size_t(3)); FCV_ASSERT(c1.size() == std::size_t(5)); FCV_ASSERT(c2.size() == std::size_t(0)); for (std::size_t i = 0; i != 3; ++i) { FCV_ASSERT(c0[i] == 5); } for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(c1[i] == 1); } std::swap(c0, c1); FCV_ASSERT(c0.size() == std::size_t(5)); FCV_ASSERT(c1.size() == std::size_t(3)); for (std::size_t i = 0; i != 5; ++i) { FCV_ASSERT(c0[i] == 1); } for (std::size_t i = 0; i != 3; ++i) { FCV_ASSERT(c1[i] == 5); } std::swap(c2, c1); FCV_ASSERT(c1.size() == std::size_t(0)); FCV_ASSERT(c2.size() == std::size_t(3)); for (std::size_t i = 0; i != 3; ++i) { FCV_ASSERT(c2[i] == 5); } } { constexpr vector<int, 5> v; static_assert(v.data() != nullptr); constexpr vector<int, 0> v0; static_assert(v0.data() == nullptr); } {// emplace: {vector<non_copyable, 3> c; vector<non_copyable, 3>::iterator i = c.emplace(c.cbegin(), 2, 3.5); FCV_ASSERT(i == c.begin()); FCV_ASSERT(c.size() == 1); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); i = c.emplace(c.cend(), 3, 4.5); FCV_ASSERT(i == c.end() - 1); FCV_ASSERT(c.size() == 2); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); FCV_ASSERT(c.back().geti() == 3); FCV_ASSERT(c.back().getd() == 4.5); i = c.emplace(c.cbegin() + 1, 4, 6.5); FCV_ASSERT(i == c.begin() + 1); FCV_ASSERT(c.size() == 3); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); FCV_ASSERT(c[1].geti() == 4); FCV_ASSERT(c[1].getd() == 6.5); FCV_ASSERT(c.back().geti() == 3); FCV_ASSERT(c.back().getd() == 4.5); } { vector<non_copyable, 3> c; vector<non_copyable, 3>::iterator i = c.emplace(c.cbegin(), 2, 3.5); FCV_ASSERT(i == c.begin()); FCV_ASSERT(c.size() == 1); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); i = c.emplace(c.cend(), 3, 4.5); FCV_ASSERT(i == c.end() - 1); FCV_ASSERT(c.size() == 2); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); FCV_ASSERT(c.back().geti() == 3); FCV_ASSERT(c.back().getd() == 4.5); i = c.emplace(c.cbegin() + 1, 4, 6.5); FCV_ASSERT(i == c.begin() + 1); FCV_ASSERT(c.size() == 3); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); FCV_ASSERT(c[1].geti() == 4); FCV_ASSERT(c[1].getd() == 6.5); FCV_ASSERT(c.back().geti() == 3); FCV_ASSERT(c.back().getd() == 4.5); } } {// emplace_back {vector<non_copyable, 2> c; c.emplace_back(2, 3.5); FCV_ASSERT(c.size() == 1); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); c.emplace_back(3, 4.5); FCV_ASSERT(c.size() == 2); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); FCV_ASSERT(c.back().geti() == 3); FCV_ASSERT(c.back().getd() == 4.5); } { vector<non_copyable, 2> c; c.emplace_back(2, 3.5); FCV_ASSERT(c.size() == 1); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); c.emplace_back(3, 4.5); FCV_ASSERT(c.size() == 2); FCV_ASSERT(c.front().geti() == 2); FCV_ASSERT(c.front().getd() == 3.5); FCV_ASSERT(c.back().geti() == 3); FCV_ASSERT(c.back().getd() == 4.5); } } { // emplace extra: {// vector<int, 4> v; v = {1, 2, 3}; v.emplace(v.begin(), v.back()); FCV_ASSERT(v[0] == 3); } { vector<int, 4> v; v = {1, 2, 3}; v.emplace(v.begin(), v.back()); FCV_ASSERT(v[0] == 3); } } {// erase {int a1[] = {1, 2, 3}; vector<int, 4> l1(a1, a1 + 3); FCV_ASSERT(l1.size() == 3); vector<int, 4>::const_iterator i = l1.begin(); ++i; vector<int, 4>::iterator j = l1.erase(i); FCV_ASSERT(l1.size() == 2); FCV_ASSERT(std::distance(l1.begin(), l1.end()) == 2); FCV_ASSERT(*j == 3); FCV_ASSERT(*l1.begin() == 1); FCV_ASSERT(*std::next(l1.begin()) == 3); j = l1.erase(j); FCV_ASSERT(j == l1.end()); FCV_ASSERT(l1.size() == 1); FCV_ASSERT(std::distance(l1.begin(), l1.end()) == 1); FCV_ASSERT(*l1.begin() == 1); j = l1.erase(l1.begin()); FCV_ASSERT(j == l1.end()); FCV_ASSERT(l1.empty()); FCV_ASSERT(std::distance(l1.begin(), l1.end()) == 0); } } { // erase iter iter int a1[] = {1, 2, 3}; using vec_t = vector<int, 5>; { vec_t l1(a1, a1 + 3); vec_t::iterator i = l1.erase(l1.cbegin(), l1.cbegin()); FCV_ASSERT(l1.size() == 3); FCV_ASSERT(std::distance(l1.cbegin(), l1.cend()) == 3); FCV_ASSERT(i == l1.begin()); } { vec_t l1(a1, a1 + 3); vec_t::iterator i = l1.erase(l1.cbegin(), std::next(l1.cbegin())); FCV_ASSERT(l1.size() == 2); FCV_ASSERT(std::distance(l1.cbegin(), l1.cend()) == 2); FCV_ASSERT(i == l1.begin()); FCV_ASSERT(l1 == vec_t(a1 + 1, a1 + 3)); } { vec_t l1(a1, a1 + 3); vec_t::iterator i = l1.erase(l1.cbegin(), std::next(l1.cbegin(), 2)); FCV_ASSERT(l1.size() == 1); FCV_ASSERT(std::distance(l1.cbegin(), l1.cend()) == 1); FCV_ASSERT(i == l1.begin()); FCV_ASSERT(l1 == vec_t(a1 + 2, a1 + 3)); } { vec_t l1(a1, a1 + 3); vec_t::iterator i = l1.erase(l1.cbegin(), std::next(l1.cbegin(), 3)); FCV_ASSERT(l1.empty()); FCV_ASSERT(std::distance(l1.cbegin(), l1.cend()) == 0); FCV_ASSERT(i == l1.begin()); } { vector<vec_t, 3> outer(2, vec_t(1)); outer.erase(outer.begin(), outer.begin()); FCV_ASSERT(outer.size() == 2); FCV_ASSERT(outer[0].size() == 1); FCV_ASSERT(outer[1].size() == 1); } } {// insert init list {vector<int, 15> d(10, 1); vector<int, 15>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6}); FCV_ASSERT(d.size() == 14); FCV_ASSERT(i == d.begin() + 2); FCV_ASSERT(d[0] == 1); FCV_ASSERT(d[1] == 1); FCV_ASSERT(d[2] == 3); FCV_ASSERT(d[3] == 4); FCV_ASSERT(d[4] == 5); FCV_ASSERT(d[5] == 6); FCV_ASSERT(d[6] == 1); FCV_ASSERT(d[7] == 1); FCV_ASSERT(d[8] == 1); FCV_ASSERT(d[9] == 1); FCV_ASSERT(d[10] == 1); FCV_ASSERT(d[11] == 1); FCV_ASSERT(d[12] == 1); FCV_ASSERT(d[13] == 1); } } {// insert iter iter {vector<int, 120> v(100); int a[] = {1, 2, 3, 4, 5}; const std::size_t n = sizeof(a) / sizeof(a[0]); vector<int, 120>::iterator i = v.insert(v.cbegin() + 10, (a + 0), (a + n)); FCV_ASSERT(v.size() == 100 + n); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } for (std::size_t k = 0; k < n; ++j, ++k) { FCV_ASSERT(v[j] == a[k]); } for (; j < 105; ++j) { FCV_ASSERT(v[j] == 0); } } [[gsl::suppress("cppcoreguidelines-pro-bounds-pointer-arithmetic")]] { vector<int, 120> v(100); size_t sz = v.size(); int a[] = {1, 2, 3, 4, 5}; const unsigned n = sizeof(a) / sizeof(a[0]); vector<int, 120>::iterator i = v.insert(v.cbegin() + 10, (a + 0), (a + n)); FCV_ASSERT(v.size() == sz + n); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } for (std::size_t k = 0; k < n; ++j, ++k) { FCV_ASSERT(v[j] == a[k]); } for (; j < v.size(); ++j) { FCV_ASSERT(v[j] == 0); } } } {// insert iter rvalue {vector<moint, 103> v(100); vector<moint, 103>::iterator i = v.insert(v.cbegin() + 10, moint(3)); FCV_ASSERT(v.size() == 101); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == moint()); } FCV_ASSERT(v[j] == moint(3)); for (++j; j < 101; ++j) { FCV_ASSERT(v[j] == moint()); } } } {// insert iter size {vector<int, 130> v(100); vector<int, 130>::iterator i = v.insert(v.cbegin() + 10, 5, 1); FCV_ASSERT(v.size() == 105); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } for (; j < 15; ++j) { FCV_ASSERT(v[j] == 1); } for (++j; j < 105; ++j) { FCV_ASSERT(v[j] == 0); } } { vector<int, 130> v(100); size_t sz = v.size(); vector<int, 130>::iterator i = v.insert(v.cbegin() + 10, 5, 1); FCV_ASSERT(v.size() == sz + 5); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } for (; j < 15; ++j) { FCV_ASSERT(v[j] == 1); } for (++j; j < v.size(); ++j) { FCV_ASSERT(v[j] == 0); } } { vector<int, 130> v(100); size_t sz = v.size(); vector<int, 130>::iterator i = v.insert(v.cbegin() + 10, 5, 1); FCV_ASSERT(v.size() == sz + 5); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } for (; j < 15; ++j) { FCV_ASSERT(v[j] == 1); } for (++j; j < v.size(); ++j) { FCV_ASSERT(v[j] == 0); } } } {// iter value: {vector<int, 130> v(100); vector<int, 130>::iterator i = v.insert(v.cbegin() + 10, 1); FCV_ASSERT(v.size() == 101); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } FCV_ASSERT(v[j] == 1); for (++j; j < 101; ++j) { FCV_ASSERT(v[j] == 0); } } { vector<int, 130> v(100); size_t sz = v.size(); vector<int, 130>::iterator i = v.insert(v.cbegin() + 10, 1); FCV_ASSERT(v.size() == sz + 1); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } FCV_ASSERT(v[j] == 1); for (++j; j < v.size(); ++j) { FCV_ASSERT(v[j] == 0); } } { vector<int, 130> v(100); v.pop_back(); v.pop_back(); // force no reallocation size_t sz = v.size(); vector<int, 130>::iterator i = v.insert(v.cbegin() + 10, 1); FCV_ASSERT(v.size() == sz + 1); FCV_ASSERT(i == v.begin() + 10); std::size_t j; for (j = 0; j < 10; ++j) { FCV_ASSERT(v[j] == 0); } FCV_ASSERT(v[j] == 1); for (++j; j < v.size(); ++j) { FCV_ASSERT(v[j] == 0); } } } { // push back move only { vector<moint, 6> c; c.push_back(moint(0)); FCV_ASSERT(c.size() == 1); for (std::size_t j = 0; j < c.size(); ++j) { FCV_ASSERT(c[j] == moint(j)); } c.push_back(moint(1)); FCV_ASSERT(c.size() == 2); for (std::size_t j = 0; j < c.size(); ++j) { FCV_ASSERT(c[j] == moint(j)); } c.push_back(moint(2)); FCV_ASSERT(c.size() == 3); for (std::size_t j = 0; j < c.size(); ++j) { FCV_ASSERT(c[j] == moint(j)); } c.push_back(moint(3)); FCV_ASSERT(c.size() == 4); for (std::size_t j = 0; j < c.size(); ++j) { FCV_ASSERT(c[j] == moint(j)); } c.push_back(moint(4)); FCV_ASSERT(c.size() == 5); for (std::size_t j = 0; j < c.size(); ++j) { FCV_ASSERT(c[j] == moint(j)); } } } std::cerr << "TESTS PASSED" << std::endl; return 0; }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
CE on Bluesky
About the author
Statistics
Changelog
Version tree