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
Swift
LLVM TableGen
Toit
TypeScript Native
V
Vala
Visual Basic
WASM
Zig
Javascript
GIMPLE
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)
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.3
x86 nvc++ 24.5
x86 nvc++ 24.7
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 (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 (latest)
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
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
/* * FakeIt - A Simplified C++ Mocking Framework * Copyright (c) Eran Pe'er 2013 * Generated: 2022-05-01 15:11:38.572491 * Distributed under the MIT License. Please refer to the LICENSE file at: * https://github.com/eranpeer/FakeIt */ #include <functional> #include <memory> #include <set> #include <vector> #include <stdexcept> #if defined (__GNUG__) || _MSC_VER >= 1900 #define THROWS noexcept(false) #define NO_THROWS noexcept(true) #elif defined (_MSC_VER) #define THROWS throw(...) #define NO_THROWS #endif #include <typeinfo> #include <unordered_set> #include <tuple> #include <string> #include <iosfwd> #include <atomic> #include <tuple> namespace fakeit { template<class C> struct naked_type { typedef typename std::remove_cv<typename std::remove_reference<C>::type>::type type; }; template< class T > struct tuple_arg { typedef T type; }; template< class T > struct tuple_arg < T& > { typedef T& type; }; template< class T > struct tuple_arg < T&& > { typedef T&& type; }; template<typename... arglist> using ArgumentsTuple = std::tuple < arglist... > ; template< class T > struct test_arg { typedef T& type; }; template< class T > struct test_arg< T& > { typedef T& type; }; template< class T > struct test_arg< T&& > { typedef T& type; }; template< class T > struct production_arg { typedef T& type; }; template< class T > struct production_arg< T& > { typedef T& type; }; template< class T > struct production_arg< T&& > { typedef T&& type; }; template <typename T> class is_ostreamable { struct no {}; #if defined(_MSC_VER) && _MSC_VER < 1900 template <typename T1> static decltype(operator<<(std::declval<std::ostream&>(), std::declval<const T1>())) test(std::ostream &s, const T1 &t); #else template <typename T1> static auto test(std::ostream &s, const T1 &t) -> decltype(s << t); #endif static no test(...); public: static const bool value = std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_same<decltype(test(*(std::ostream *)nullptr, std::declval<T>())), std::ostream &>::value; }; template <> class is_ostreamable<std::ios_base& (*)(std::ios_base&)> { public: static const bool value = true; }; template <typename CharT, typename Traits> class is_ostreamable<std::basic_ios<CharT,Traits>& (*)(std::basic_ios<CharT,Traits>&)> { public: static const bool value = true; }; template <typename CharT, typename Traits> class is_ostreamable<std::basic_ostream<CharT,Traits>& (*)(std::basic_ostream<CharT,Traits>&)> { public: static const bool value = true; }; template<typename R, typename... arglist> struct VTableMethodType { #if defined (__GNUG__) typedef R(*type)(void *, arglist...); #elif defined (_MSC_VER) typedef R(__thiscall *type)(void *, arglist...); #endif }; } #include <typeinfo> #include <tuple> #include <string> #include <iosfwd> #include <sstream> #include <string> namespace fakeit { struct FakeitContext; template<typename C> struct MockObject { virtual ~MockObject() THROWS { }; virtual C &get() = 0; virtual FakeitContext &getFakeIt() = 0; }; struct MethodInfo { static unsigned int nextMethodOrdinal() { static std::atomic_uint ordinal{0}; return ++ordinal; } MethodInfo(unsigned int anId, std::string aName) : _id(anId), _name(aName) { } unsigned int id() const { return _id; } std::string name() const { return _name; } void setName(const std::string &value) { _name = value; } private: unsigned int _id; std::string _name; }; struct UnknownMethod { static MethodInfo &instance() { static MethodInfo instance(MethodInfo::nextMethodOrdinal(), "unknown"); return instance; } }; } namespace fakeit { class Destructible { public: virtual ~Destructible() {} }; } namespace fakeit { struct Invocation : Destructible { static unsigned int nextInvocationOrdinal() { static std::atomic_uint invocationOrdinal{0}; return ++invocationOrdinal; } struct Matcher { virtual ~Matcher() THROWS { } virtual bool matches(Invocation &invocation) = 0; virtual std::string format() const = 0; }; Invocation(unsigned int ordinal, MethodInfo &method) : _ordinal(ordinal), _method(method), _isVerified(false) { } virtual ~Invocation() override = default; unsigned int getOrdinal() const { return _ordinal; } MethodInfo &getMethod() const { return _method; } void markAsVerified() { _isVerified = true; } bool isVerified() const { return _isVerified; } virtual std::string format() const = 0; private: const unsigned int _ordinal; MethodInfo &_method; bool _isVerified; }; } #include <iosfwd> #include <tuple> #include <string> #include <sstream> #include <ostream> namespace fakeit { template<typename T, class Enable = void> struct Formatter; template <> struct Formatter<bool> { static std::string format(bool const &val) { return val ? "true" : "false"; } }; template <> struct Formatter<char> { static std::string format(char const &val) { std::string s; s += "'"; s += val; s += "'"; return s; } }; template <> struct Formatter<char const*> { static std::string format(char const* const &val) { std::string s; if(val != nullptr) { s += '"'; s += val; s += '"'; } else { s = "[nullptr]"; } return s; } }; template <> struct Formatter<char*> { static std::string format(char* const &val) { return Formatter<char const*>::format( val ); } }; template<class C> struct Formatter<C, typename std::enable_if<!is_ostreamable<C>::value>::type> { static std::string format(C const &) { return "?"; } }; template<class C> struct Formatter<C, typename std::enable_if<is_ostreamable<C>::value>::type> { static std::string format(C const &val) { std::ostringstream os; os << val; return os.str(); } }; template <typename T> using TypeFormatter = Formatter<typename fakeit::naked_type<T>::type>; } namespace fakeit { template<class Tuple, std::size_t N> struct TuplePrinter { static void print(std::ostream &strm, const Tuple &t) { TuplePrinter<Tuple, N - 1>::print(strm, t); strm << ", " << fakeit::TypeFormatter<decltype(std::get<N - 1>(t))>::format(std::get<N - 1>(t)); } }; template<class Tuple> struct TuplePrinter<Tuple, 1> { static void print(std::ostream &strm, const Tuple &t) { strm << fakeit::TypeFormatter<decltype(std::get<0>(t))>::format(std::get<0>(t)); } }; template<class Tuple> struct TuplePrinter<Tuple, 0> { static void print(std::ostream &, const Tuple &) { } }; template<class ... Args> void print(std::ostream &strm, const std::tuple<Args...> &t) { strm << "("; TuplePrinter<decltype(t), sizeof...(Args)>::print(strm, t); strm << ")"; } template<class ... Args> std::ostream &operator<<(std::ostream &strm, const std::tuple<Args...> &t) { print(strm, t); return strm; } } namespace fakeit { template<typename ... arglist> struct ActualInvocation : public Invocation { struct Matcher : public virtual Destructible { virtual bool matches(ActualInvocation<arglist...> &actualInvocation) = 0; virtual std::string format() const = 0; }; ActualInvocation(unsigned int ordinal, MethodInfo &method, const typename fakeit::production_arg<arglist>::type... args) : Invocation(ordinal, method), _matcher{ nullptr } , actualArguments{ std::forward<arglist>(args)... } { } ArgumentsTuple<arglist...> & getActualArguments() { return actualArguments; } void setActualMatcher(Matcher *matcher) { this->_matcher = matcher; } Matcher *getActualMatcher() { return _matcher; } virtual std::string format() const override { std::ostringstream out; out << getMethod().name(); print(out, actualArguments); return out.str(); } private: Matcher *_matcher; ArgumentsTuple<arglist...> actualArguments; }; template<typename ... arglist> std::ostream &operator<<(std::ostream &strm, const ActualInvocation<arglist...> &ai) { strm << ai.format(); return strm; } } #include <unordered_set> namespace fakeit { struct ActualInvocationsContainer { virtual void clear() = 0; virtual ~ActualInvocationsContainer() NO_THROWS { } }; struct ActualInvocationsSource { virtual void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const = 0; virtual ~ActualInvocationsSource() NO_THROWS { } }; struct InvocationsSourceProxy : public ActualInvocationsSource { InvocationsSourceProxy(ActualInvocationsSource *inner) : _inner(inner) { } void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const override { _inner->getActualInvocations(into); } private: std::shared_ptr<ActualInvocationsSource> _inner; }; struct UnverifiedInvocationsSource : public ActualInvocationsSource { UnverifiedInvocationsSource(InvocationsSourceProxy decorated) : _decorated(decorated) { } void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const override { std::unordered_set<fakeit::Invocation *> all; _decorated.getActualInvocations(all); for (fakeit::Invocation *i : all) { if (!i->isVerified()) { into.insert(i); } } } private: InvocationsSourceProxy _decorated; }; struct AggregateInvocationsSource : public ActualInvocationsSource { AggregateInvocationsSource(std::vector<ActualInvocationsSource *> &sources) : _sources(sources) { } void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const override { std::unordered_set<fakeit::Invocation *> tmp; for (ActualInvocationsSource *source : _sources) { source->getActualInvocations(tmp); } filter(tmp, into); } protected: bool shouldInclude(fakeit::Invocation *) const { return true; } private: std::vector<ActualInvocationsSource *> _sources; void filter(std::unordered_set<Invocation *> &source, std::unordered_set<Invocation *> &target) const { for (Invocation *i:source) { if (shouldInclude(i)) { target.insert(i); } } } }; } namespace fakeit { class Sequence { private: protected: Sequence() { } virtual ~Sequence() THROWS { } public: virtual void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const = 0; virtual void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const = 0; virtual unsigned int size() const = 0; friend class VerifyFunctor; }; class ConcatenatedSequence : public virtual Sequence { private: const Sequence &s1; const Sequence &s2; protected: ConcatenatedSequence(const Sequence &seq1, const Sequence &seq2) : s1(seq1), s2(seq2) { } public: virtual ~ConcatenatedSequence() { } unsigned int size() const override { return s1.size() + s2.size(); } const Sequence &getLeft() const { return s1; } const Sequence &getRight() const { return s2; } void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const override { s1.getExpectedSequence(into); s2.getExpectedSequence(into); } virtual void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const override { s1.getInvolvedMocks(into); s2.getInvolvedMocks(into); } friend inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2); }; class RepeatedSequence : public virtual Sequence { private: const Sequence &_s; const int times; protected: RepeatedSequence(const Sequence &s, const int t) : _s(s), times(t) { } public: ~RepeatedSequence() { } unsigned int size() const override { return _s.size() * times; } friend inline RepeatedSequence operator*(const Sequence &s, int times); friend inline RepeatedSequence operator*(int times, const Sequence &s); void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const override { _s.getInvolvedMocks(into); } void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const override { for (int i = 0; i < times; i++) _s.getExpectedSequence(into); } int getTimes() const { return times; } const Sequence &getSequence() const { return _s; } }; inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2) { return ConcatenatedSequence(s1, s2); } inline RepeatedSequence operator*(const Sequence &s, int times) { if (times <= 0) throw std::invalid_argument("times"); return RepeatedSequence(s, times); } inline RepeatedSequence operator*(int times, const Sequence &s) { if (times <= 0) throw std::invalid_argument("times"); return RepeatedSequence(s, times); } } namespace fakeit { enum class VerificationType { Exact, AtLeast, NoMoreInvocations }; enum class UnexpectedType { Unmocked, Unmatched }; struct VerificationEvent { VerificationEvent(VerificationType aVerificationType) : _verificationType(aVerificationType), _line(0) { } virtual ~VerificationEvent() = default; VerificationType verificationType() const { return _verificationType; } void setFileInfo(const char * aFile, int aLine, const char * aCallingMethod) { _file = aFile; _callingMethod = aCallingMethod; _line = aLine; } const char * file() const { return _file; } int line() const { return _line; } const char * callingMethod() const { return _callingMethod; } private: VerificationType _verificationType; const char * _file; int _line; const char * _callingMethod; }; struct NoMoreInvocationsVerificationEvent : public VerificationEvent { ~NoMoreInvocationsVerificationEvent() = default; NoMoreInvocationsVerificationEvent( std::vector<Invocation *> &allTheIvocations, std::vector<Invocation *> &anUnverifedIvocations) : VerificationEvent(VerificationType::NoMoreInvocations), _allIvocations(allTheIvocations), _unverifedIvocations(anUnverifedIvocations) { } const std::vector<Invocation *> &allIvocations() const { return _allIvocations; } const std::vector<Invocation *> &unverifedIvocations() const { return _unverifedIvocations; } private: const std::vector<Invocation *> _allIvocations; const std::vector<Invocation *> _unverifedIvocations; }; struct SequenceVerificationEvent : public VerificationEvent { ~SequenceVerificationEvent() = default; SequenceVerificationEvent(VerificationType aVerificationType, std::vector<Sequence *> &anExpectedPattern, std::vector<Invocation *> &anActualSequence, int anExpectedCount, int anActualCount) : VerificationEvent(aVerificationType), _expectedPattern(anExpectedPattern), _actualSequence(anActualSequence), _expectedCount(anExpectedCount), _actualCount(anActualCount) { } const std::vector<Sequence *> &expectedPattern() const { return _expectedPattern; } const std::vector<Invocation *> &actualSequence() const { return _actualSequence; } int expectedCount() const { return _expectedCount; } int actualCount() const { return _actualCount; } private: const std::vector<Sequence *> _expectedPattern; const std::vector<Invocation *> _actualSequence; const int _expectedCount; const int _actualCount; }; struct UnexpectedMethodCallEvent { UnexpectedMethodCallEvent(UnexpectedType unexpectedType, const Invocation &invocation) : _unexpectedType(unexpectedType), _invocation(invocation) { } const Invocation &getInvocation() const { return _invocation; } UnexpectedType getUnexpectedType() const { return _unexpectedType; } const UnexpectedType _unexpectedType; const Invocation &_invocation; }; } namespace fakeit { struct VerificationEventHandler { virtual void handle(const SequenceVerificationEvent &e) = 0; virtual void handle(const NoMoreInvocationsVerificationEvent &e) = 0; }; struct EventHandler : public VerificationEventHandler { using VerificationEventHandler::handle; virtual void handle(const UnexpectedMethodCallEvent &e) = 0; }; } #include <vector> #include <string> namespace fakeit { struct UnexpectedMethodCallEvent; struct SequenceVerificationEvent; struct NoMoreInvocationsVerificationEvent; struct EventFormatter { virtual std::string format(const fakeit::UnexpectedMethodCallEvent &e) = 0; virtual std::string format(const fakeit::SequenceVerificationEvent &e) = 0; virtual std::string format(const fakeit::NoMoreInvocationsVerificationEvent &e) = 0; }; } #ifdef FAKEIT_ASSERT_ON_UNEXPECTED_METHOD_INVOCATION #include <cassert> #endif namespace fakeit { struct FakeitContext : public EventHandler, protected EventFormatter { virtual ~FakeitContext() = default; void handle(const UnexpectedMethodCallEvent &e) override { fireEvent(e); auto &eh = getTestingFrameworkAdapter(); #ifdef FAKEIT_ASSERT_ON_UNEXPECTED_METHOD_INVOCATION assert(!"Unexpected method invocation"); #endif eh.handle(e); } void handle(const SequenceVerificationEvent &e) override { fireEvent(e); auto &eh = getTestingFrameworkAdapter(); return eh.handle(e); } void handle(const NoMoreInvocationsVerificationEvent &e) override { fireEvent(e); auto &eh = getTestingFrameworkAdapter(); return eh.handle(e); } std::string format(const UnexpectedMethodCallEvent &e) override { auto &eventFormatter = getEventFormatter(); return eventFormatter.format(e); } std::string format(const SequenceVerificationEvent &e) override { auto &eventFormatter = getEventFormatter(); return eventFormatter.format(e); } std::string format(const NoMoreInvocationsVerificationEvent &e) override { auto &eventFormatter = getEventFormatter(); return eventFormatter.format(e); } void addEventHandler(EventHandler &eventListener) { _eventListeners.push_back(&eventListener); } void clearEventHandlers() { _eventListeners.clear(); } protected: virtual EventHandler &getTestingFrameworkAdapter() = 0; virtual EventFormatter &getEventFormatter() = 0; private: std::vector<EventHandler *> _eventListeners; void fireEvent(const NoMoreInvocationsVerificationEvent &evt) { for (auto listener : _eventListeners) listener->handle(evt); } void fireEvent(const UnexpectedMethodCallEvent &evt) { for (auto listener : _eventListeners) listener->handle(evt); } void fireEvent(const SequenceVerificationEvent &evt) { for (auto listener : _eventListeners) listener->handle(evt); } }; } #include <iostream> #include <iosfwd> namespace fakeit { struct DefaultEventFormatter : public EventFormatter { virtual std::string format(const UnexpectedMethodCallEvent &e) override { std::ostringstream out; out << "Unexpected method invocation: "; out << e.getInvocation().format() << std::endl; if (UnexpectedType::Unmatched == e.getUnexpectedType()) { out << " Could not find any recorded behavior to support this method call."; } else { out << " An unmocked method was invoked. All used virtual methods must be stubbed!"; } return out.str(); } virtual std::string format(const SequenceVerificationEvent &e) override { std::ostringstream out; out << "Verification error" << std::endl; out << "Expected pattern: "; const std::vector<fakeit::Sequence *> expectedPattern = e.expectedPattern(); out << formatExpectedPattern(expectedPattern) << std::endl; out << "Expected matches: "; formatExpectedCount(out, e.verificationType(), e.expectedCount()); out << std::endl; out << "Actual matches : " << e.actualCount() << std::endl; auto actualSequence = e.actualSequence(); out << "Actual sequence : total of " << actualSequence.size() << " actual invocations"; if (actualSequence.size() == 0) { out << "."; } else { out << ":" << std::endl; } formatInvocationList(out, actualSequence); return out.str(); } virtual std::string format(const NoMoreInvocationsVerificationEvent &e) override { std::ostringstream out; out << "Verification error" << std::endl; out << "Expected no more invocations!! but the following unverified invocations were found:" << std::endl; formatInvocationList(out, e.unverifedIvocations()); return out.str(); } static std::string formatExpectedPattern(const std::vector<fakeit::Sequence *> &expectedPattern) { std::string expectedPatternStr; for (unsigned int i = 0; i < expectedPattern.size(); i++) { Sequence *s = expectedPattern[i]; expectedPatternStr += formatSequence(*s); if (i < expectedPattern.size() - 1) expectedPatternStr += " ... "; } return expectedPatternStr; } private: static std::string formatSequence(const Sequence &val) { const ConcatenatedSequence *cs = dynamic_cast<const ConcatenatedSequence *>(&val); if (cs) { return format(*cs); } const RepeatedSequence *rs = dynamic_cast<const RepeatedSequence *>(&val); if (rs) { return format(*rs); } std::vector<Invocation::Matcher *> vec; val.getExpectedSequence(vec); return vec[0]->format(); } static void formatExpectedCount(std::ostream &out, fakeit::VerificationType verificationType, int expectedCount) { if (verificationType == fakeit::VerificationType::Exact) out << "exactly "; if (verificationType == fakeit::VerificationType::AtLeast) out << "at least "; out << expectedCount; } static void formatInvocationList(std::ostream &out, const std::vector<fakeit::Invocation *> &actualSequence) { size_t max_size = actualSequence.size(); if (max_size > 50) max_size = 50; for (unsigned int i = 0; i < max_size; i++) { out << " "; auto invocation = actualSequence[i]; out << invocation->format(); if (i < max_size - 1) out << std::endl; } if (actualSequence.size() > max_size) out << std::endl << " ..."; } static std::string format(const ConcatenatedSequence &val) { std::ostringstream out; out << formatSequence(val.getLeft()) << " + " << formatSequence(val.getRight()); return out.str(); } static std::string format(const RepeatedSequence &val) { std::ostringstream out; const ConcatenatedSequence *cs = dynamic_cast<const ConcatenatedSequence *>(&val.getSequence()); const RepeatedSequence *rs = dynamic_cast<const RepeatedSequence *>(&val.getSequence()); if (rs || cs) out << '('; out << formatSequence(val.getSequence()); if (rs || cs) out << ')'; out << " * " << val.getTimes(); return out.str(); } }; } #include <exception> namespace fakeit { #if __cplusplus >= 201703L || defined(__cpp_lib_uncaught_exceptions) inline bool UncaughtException () { return std::uncaught_exceptions() >= 1; } #else inline bool UncaughtException () { return std::uncaught_exception(); } #endif struct FakeitException { std::exception err; virtual ~FakeitException() = default; virtual std::string what() const = 0; friend std::ostream &operator<<(std::ostream &os, const FakeitException &val) { os << val.what(); return os; } }; struct UnexpectedMethodCallException : public FakeitException { UnexpectedMethodCallException(std::string format) : _format(format) { } virtual std::string what() const override { return _format; } private: std::string _format; }; } namespace fakeit { struct DefaultEventLogger : public fakeit::EventHandler { DefaultEventLogger(EventFormatter &formatter) : _formatter(formatter), _out(std::cout) { } virtual void handle(const UnexpectedMethodCallEvent &e) override { _out << _formatter.format(e) << std::endl; } virtual void handle(const SequenceVerificationEvent &e) override { _out << _formatter.format(e) << std::endl; } virtual void handle(const NoMoreInvocationsVerificationEvent &e) override { _out << _formatter.format(e) << std::endl; } private: EventFormatter &_formatter; std::ostream &_out; }; } namespace fakeit { class AbstractFakeit : public FakeitContext { public: virtual ~AbstractFakeit() = default; protected: virtual fakeit::EventHandler &accessTestingFrameworkAdapter() = 0; virtual EventFormatter &accessEventFormatter() = 0; }; class DefaultFakeit : public AbstractFakeit { DefaultEventFormatter _formatter; fakeit::EventFormatter *_customFormatter; fakeit::EventHandler *_testingFrameworkAdapter; public: DefaultFakeit() : _formatter(), _customFormatter(nullptr), _testingFrameworkAdapter(nullptr) { } virtual ~DefaultFakeit() = default; void setCustomEventFormatter(fakeit::EventFormatter &customEventFormatter) { _customFormatter = &customEventFormatter; } void resetCustomEventFormatter() { _customFormatter = nullptr; } void setTestingFrameworkAdapter(fakeit::EventHandler &testingFrameforkAdapter) { _testingFrameworkAdapter = &testingFrameforkAdapter; } void resetTestingFrameworkAdapter() { _testingFrameworkAdapter = nullptr; } protected: fakeit::EventHandler &getTestingFrameworkAdapter() override { if (_testingFrameworkAdapter) return *_testingFrameworkAdapter; return accessTestingFrameworkAdapter(); } EventFormatter &getEventFormatter() override { if (_customFormatter) return *_customFormatter; return accessEventFormatter(); } EventFormatter &accessEventFormatter() override { return _formatter; } }; } #include <string> #include <sstream> #include <iomanip> namespace fakeit { template<typename T> static std::string to_string(const T &n) { std::ostringstream stm; stm << n; return stm.str(); } } namespace fakeit { struct VerificationException : public std::exception { virtual ~VerificationException() NO_THROWS{}; VerificationException(std::string format) : _format(format) { } friend std::ostream &operator<<(std::ostream &os, const VerificationException &val) { os << val.what(); return os; } void setFileInfo(std::string aFile, int aLine, std::string aCallingMethod) { _file = aFile; _callingMethod = aCallingMethod; _line = aLine; } const std::string& file() const { return _file; } int line() const { return _line; } const std::string& callingMethod() const { return _callingMethod; } const char* what() const NO_THROWS override{ return _format.c_str(); } private: std::string _file; int _line; std::string _callingMethod; std::string _format; }; struct NoMoreInvocationsVerificationException : public VerificationException { NoMoreInvocationsVerificationException(std::string format) : VerificationException(format) { } }; struct SequenceVerificationException : public VerificationException { SequenceVerificationException(std::string format) : VerificationException(format) { } }; struct StandaloneAdapter : public EventHandler { std::string formatLineNumner(std::string file, int num){ #ifndef __GNUG__ return file + std::string("(") + fakeit::to_string(num) + std::string(")"); #else return file + std::string(":") + fakeit::to_string(num); #endif } virtual ~StandaloneAdapter() = default; StandaloneAdapter(EventFormatter &formatter) : _formatter(formatter) { } virtual void handle(const UnexpectedMethodCallEvent &evt) override { std::string format = _formatter.format(evt); UnexpectedMethodCallException ex(format); throw ex; } virtual void handle(const SequenceVerificationEvent &evt) override { std::string format(formatLineNumner(evt.file(), evt.line()) + ": " + _formatter.format(evt)); SequenceVerificationException e(format); e.setFileInfo(evt.file(), evt.line(), evt.callingMethod()); throw e; } virtual void handle(const NoMoreInvocationsVerificationEvent &evt) override { std::string format(formatLineNumner(evt.file(), evt.line()) + ": " + _formatter.format(evt)); NoMoreInvocationsVerificationException e(format); e.setFileInfo(evt.file(), evt.line(), evt.callingMethod()); throw e; } private: EventFormatter &_formatter; }; class StandaloneFakeit : public DefaultFakeit { public: virtual ~StandaloneFakeit() = default; StandaloneFakeit() : _standaloneAdapter(*this) { } static StandaloneFakeit &getInstance() { static StandaloneFakeit instance; return instance; } protected: fakeit::EventHandler &accessTestingFrameworkAdapter() override { return _standaloneAdapter; } private: StandaloneAdapter _standaloneAdapter; }; } static fakeit::DefaultFakeit& Fakeit = fakeit::StandaloneFakeit::getInstance(); #include <type_traits> #include <unordered_set> #include <memory> #undef max #include <functional> #include <type_traits> #include <vector> #include <array> #include <new> #include <limits> #include <functional> #include <type_traits> namespace fakeit { struct VirtualOffsetSelector { unsigned int offset; virtual unsigned int offset0(int) { return offset = 0; } virtual unsigned int offset1(int) { return offset = 1; } virtual unsigned int offset2(int) { return offset = 2; } virtual unsigned int offset3(int) { return offset = 3; } virtual unsigned int offset4(int) { return offset = 4; } virtual unsigned int offset5(int) { return offset = 5; } virtual unsigned int offset6(int) { return offset = 6; } virtual unsigned int offset7(int) { return offset = 7; } virtual unsigned int offset8(int) { return offset = 8; } virtual unsigned int offset9(int) { return offset = 9; } virtual unsigned int offset10(int) { return offset = 10; } virtual unsigned int offset11(int) { return offset = 11; } virtual unsigned int offset12(int) { return offset = 12; } virtual unsigned int offset13(int) { return offset = 13; } virtual unsigned int offset14(int) { return offset = 14; } virtual unsigned int offset15(int) { return offset = 15; } virtual unsigned int offset16(int) { return offset = 16; } virtual unsigned int offset17(int) { return offset = 17; } virtual unsigned int offset18(int) { return offset = 18; } virtual unsigned int offset19(int) { return offset = 19; } virtual unsigned int offset20(int) { return offset = 20; } virtual unsigned int offset21(int) { return offset = 21; } virtual unsigned int offset22(int) { return offset = 22; } virtual unsigned int offset23(int) { return offset = 23; } virtual unsigned int offset24(int) { return offset = 24; } virtual unsigned int offset25(int) { return offset = 25; } virtual unsigned int offset26(int) { return offset = 26; } virtual unsigned int offset27(int) { return offset = 27; } virtual unsigned int offset28(int) { return offset = 28; } virtual unsigned int offset29(int) { return offset = 29; } virtual unsigned int offset30(int) { return offset = 30; } virtual unsigned int offset31(int) { return offset = 31; } virtual unsigned int offset32(int) { return offset = 32; } virtual unsigned int offset33(int) { return offset = 33; } virtual unsigned int offset34(int) { return offset = 34; } virtual unsigned int offset35(int) { return offset = 35; } virtual unsigned int offset36(int) { return offset = 36; } virtual unsigned int offset37(int) { return offset = 37; } virtual unsigned int offset38(int) { return offset = 38; } virtual unsigned int offset39(int) { return offset = 39; } virtual unsigned int offset40(int) { return offset = 40; } virtual unsigned int offset41(int) { return offset = 41; } virtual unsigned int offset42(int) { return offset = 42; } virtual unsigned int offset43(int) { return offset = 43; } virtual unsigned int offset44(int) { return offset = 44; } virtual unsigned int offset45(int) { return offset = 45; } virtual unsigned int offset46(int) { return offset = 46; } virtual unsigned int offset47(int) { return offset = 47; } virtual unsigned int offset48(int) { return offset = 48; } virtual unsigned int offset49(int) { return offset = 49; } virtual unsigned int offset50(int) { return offset = 50; } virtual unsigned int offset51(int) { return offset = 51; } virtual unsigned int offset52(int) { return offset = 52; } virtual unsigned int offset53(int) { return offset = 53; } virtual unsigned int offset54(int) { return offset = 54; } virtual unsigned int offset55(int) { return offset = 55; } virtual unsigned int offset56(int) { return offset = 56; } virtual unsigned int offset57(int) { return offset = 57; } virtual unsigned int offset58(int) { return offset = 58; } virtual unsigned int offset59(int) { return offset = 59; } virtual unsigned int offset60(int) { return offset = 60; } virtual unsigned int offset61(int) { return offset = 61; } virtual unsigned int offset62(int) { return offset = 62; } virtual unsigned int offset63(int) { return offset = 63; } virtual unsigned int offset64(int) { return offset = 64; } virtual unsigned int offset65(int) { return offset = 65; } virtual unsigned int offset66(int) { return offset = 66; } virtual unsigned int offset67(int) { return offset = 67; } virtual unsigned int offset68(int) { return offset = 68; } virtual unsigned int offset69(int) { return offset = 69; } virtual unsigned int offset70(int) { return offset = 70; } virtual unsigned int offset71(int) { return offset = 71; } virtual unsigned int offset72(int) { return offset = 72; } virtual unsigned int offset73(int) { return offset = 73; } virtual unsigned int offset74(int) { return offset = 74; } virtual unsigned int offset75(int) { return offset = 75; } virtual unsigned int offset76(int) { return offset = 76; } virtual unsigned int offset77(int) { return offset = 77; } virtual unsigned int offset78(int) { return offset = 78; } virtual unsigned int offset79(int) { return offset = 79; } virtual unsigned int offset80(int) { return offset = 80; } virtual unsigned int offset81(int) { return offset = 81; } virtual unsigned int offset82(int) { return offset = 82; } virtual unsigned int offset83(int) { return offset = 83; } virtual unsigned int offset84(int) { return offset = 84; } virtual unsigned int offset85(int) { return offset = 85; } virtual unsigned int offset86(int) { return offset = 86; } virtual unsigned int offset87(int) { return offset = 87; } virtual unsigned int offset88(int) { return offset = 88; } virtual unsigned int offset89(int) { return offset = 89; } virtual unsigned int offset90(int) { return offset = 90; } virtual unsigned int offset91(int) { return offset = 91; } virtual unsigned int offset92(int) { return offset = 92; } virtual unsigned int offset93(int) { return offset = 93; } virtual unsigned int offset94(int) { return offset = 94; } virtual unsigned int offset95(int) { return offset = 95; } virtual unsigned int offset96(int) { return offset = 96; } virtual unsigned int offset97(int) { return offset = 97; } virtual unsigned int offset98(int) { return offset = 98; } virtual unsigned int offset99(int) { return offset = 99; } virtual unsigned int offset100(int) { return offset = 100; } virtual unsigned int offset101(int) { return offset = 101; } virtual unsigned int offset102(int) { return offset = 102; } virtual unsigned int offset103(int) { return offset = 103; } virtual unsigned int offset104(int) { return offset = 104; } virtual unsigned int offset105(int) { return offset = 105; } virtual unsigned int offset106(int) { return offset = 106; } virtual unsigned int offset107(int) { return offset = 107; } virtual unsigned int offset108(int) { return offset = 108; } virtual unsigned int offset109(int) { return offset = 109; } virtual unsigned int offset110(int) { return offset = 110; } virtual unsigned int offset111(int) { return offset = 111; } virtual unsigned int offset112(int) { return offset = 112; } virtual unsigned int offset113(int) { return offset = 113; } virtual unsigned int offset114(int) { return offset = 114; } virtual unsigned int offset115(int) { return offset = 115; } virtual unsigned int offset116(int) { return offset = 116; } virtual unsigned int offset117(int) { return offset = 117; } virtual unsigned int offset118(int) { return offset = 118; } virtual unsigned int offset119(int) { return offset = 119; } virtual unsigned int offset120(int) { return offset = 120; } virtual unsigned int offset121(int) { return offset = 121; } virtual unsigned int offset122(int) { return offset = 122; } virtual unsigned int offset123(int) { return offset = 123; } virtual unsigned int offset124(int) { return offset = 124; } virtual unsigned int offset125(int) { return offset = 125; } virtual unsigned int offset126(int) { return offset = 126; } virtual unsigned int offset127(int) { return offset = 127; } virtual unsigned int offset128(int) { return offset = 128; } virtual unsigned int offset129(int) { return offset = 129; } virtual unsigned int offset130(int) { return offset = 130; } virtual unsigned int offset131(int) { return offset = 131; } virtual unsigned int offset132(int) { return offset = 132; } virtual unsigned int offset133(int) { return offset = 133; } virtual unsigned int offset134(int) { return offset = 134; } virtual unsigned int offset135(int) { return offset = 135; } virtual unsigned int offset136(int) { return offset = 136; } virtual unsigned int offset137(int) { return offset = 137; } virtual unsigned int offset138(int) { return offset = 138; } virtual unsigned int offset139(int) { return offset = 139; } virtual unsigned int offset140(int) { return offset = 140; } virtual unsigned int offset141(int) { return offset = 141; } virtual unsigned int offset142(int) { return offset = 142; } virtual unsigned int offset143(int) { return offset = 143; } virtual unsigned int offset144(int) { return offset = 144; } virtual unsigned int offset145(int) { return offset = 145; } virtual unsigned int offset146(int) { return offset = 146; } virtual unsigned int offset147(int) { return offset = 147; } virtual unsigned int offset148(int) { return offset = 148; } virtual unsigned int offset149(int) { return offset = 149; } virtual unsigned int offset150(int) { return offset = 150; } virtual unsigned int offset151(int) { return offset = 151; } virtual unsigned int offset152(int) { return offset = 152; } virtual unsigned int offset153(int) { return offset = 153; } virtual unsigned int offset154(int) { return offset = 154; } virtual unsigned int offset155(int) { return offset = 155; } virtual unsigned int offset156(int) { return offset = 156; } virtual unsigned int offset157(int) { return offset = 157; } virtual unsigned int offset158(int) { return offset = 158; } virtual unsigned int offset159(int) { return offset = 159; } virtual unsigned int offset160(int) { return offset = 160; } virtual unsigned int offset161(int) { return offset = 161; } virtual unsigned int offset162(int) { return offset = 162; } virtual unsigned int offset163(int) { return offset = 163; } virtual unsigned int offset164(int) { return offset = 164; } virtual unsigned int offset165(int) { return offset = 165; } virtual unsigned int offset166(int) { return offset = 166; } virtual unsigned int offset167(int) { return offset = 167; } virtual unsigned int offset168(int) { return offset = 168; } virtual unsigned int offset169(int) { return offset = 169; } virtual unsigned int offset170(int) { return offset = 170; } virtual unsigned int offset171(int) { return offset = 171; } virtual unsigned int offset172(int) { return offset = 172; } virtual unsigned int offset173(int) { return offset = 173; } virtual unsigned int offset174(int) { return offset = 174; } virtual unsigned int offset175(int) { return offset = 175; } virtual unsigned int offset176(int) { return offset = 176; } virtual unsigned int offset177(int) { return offset = 177; } virtual unsigned int offset178(int) { return offset = 178; } virtual unsigned int offset179(int) { return offset = 179; } virtual unsigned int offset180(int) { return offset = 180; } virtual unsigned int offset181(int) { return offset = 181; } virtual unsigned int offset182(int) { return offset = 182; } virtual unsigned int offset183(int) { return offset = 183; } virtual unsigned int offset184(int) { return offset = 184; } virtual unsigned int offset185(int) { return offset = 185; } virtual unsigned int offset186(int) { return offset = 186; } virtual unsigned int offset187(int) { return offset = 187; } virtual unsigned int offset188(int) { return offset = 188; } virtual unsigned int offset189(int) { return offset = 189; } virtual unsigned int offset190(int) { return offset = 190; } virtual unsigned int offset191(int) { return offset = 191; } virtual unsigned int offset192(int) { return offset = 192; } virtual unsigned int offset193(int) { return offset = 193; } virtual unsigned int offset194(int) { return offset = 194; } virtual unsigned int offset195(int) { return offset = 195; } virtual unsigned int offset196(int) { return offset = 196; } virtual unsigned int offset197(int) { return offset = 197; } virtual unsigned int offset198(int) { return offset = 198; } virtual unsigned int offset199(int) { return offset = 199; } virtual unsigned int offset200(int) { return offset = 200; } virtual unsigned int offset201(int) { return offset = 201; } virtual unsigned int offset202(int) { return offset = 202; } virtual unsigned int offset203(int) { return offset = 203; } virtual unsigned int offset204(int) { return offset = 204; } virtual unsigned int offset205(int) { return offset = 205; } virtual unsigned int offset206(int) { return offset = 206; } virtual unsigned int offset207(int) { return offset = 207; } virtual unsigned int offset208(int) { return offset = 208; } virtual unsigned int offset209(int) { return offset = 209; } virtual unsigned int offset210(int) { return offset = 210; } virtual unsigned int offset211(int) { return offset = 211; } virtual unsigned int offset212(int) { return offset = 212; } virtual unsigned int offset213(int) { return offset = 213; } virtual unsigned int offset214(int) { return offset = 214; } virtual unsigned int offset215(int) { return offset = 215; } virtual unsigned int offset216(int) { return offset = 216; } virtual unsigned int offset217(int) { return offset = 217; } virtual unsigned int offset218(int) { return offset = 218; } virtual unsigned int offset219(int) { return offset = 219; } virtual unsigned int offset220(int) { return offset = 220; } virtual unsigned int offset221(int) { return offset = 221; } virtual unsigned int offset222(int) { return offset = 222; } virtual unsigned int offset223(int) { return offset = 223; } virtual unsigned int offset224(int) { return offset = 224; } virtual unsigned int offset225(int) { return offset = 225; } virtual unsigned int offset226(int) { return offset = 226; } virtual unsigned int offset227(int) { return offset = 227; } virtual unsigned int offset228(int) { return offset = 228; } virtual unsigned int offset229(int) { return offset = 229; } virtual unsigned int offset230(int) { return offset = 230; } virtual unsigned int offset231(int) { return offset = 231; } virtual unsigned int offset232(int) { return offset = 232; } virtual unsigned int offset233(int) { return offset = 233; } virtual unsigned int offset234(int) { return offset = 234; } virtual unsigned int offset235(int) { return offset = 235; } virtual unsigned int offset236(int) { return offset = 236; } virtual unsigned int offset237(int) { return offset = 237; } virtual unsigned int offset238(int) { return offset = 238; } virtual unsigned int offset239(int) { return offset = 239; } virtual unsigned int offset240(int) { return offset = 240; } virtual unsigned int offset241(int) { return offset = 241; } virtual unsigned int offset242(int) { return offset = 242; } virtual unsigned int offset243(int) { return offset = 243; } virtual unsigned int offset244(int) { return offset = 244; } virtual unsigned int offset245(int) { return offset = 245; } virtual unsigned int offset246(int) { return offset = 246; } virtual unsigned int offset247(int) { return offset = 247; } virtual unsigned int offset248(int) { return offset = 248; } virtual unsigned int offset249(int) { return offset = 249; } virtual unsigned int offset250(int) { return offset = 250; } virtual unsigned int offset251(int) { return offset = 251; } virtual unsigned int offset252(int) { return offset = 252; } virtual unsigned int offset253(int) { return offset = 253; } virtual unsigned int offset254(int) { return offset = 254; } virtual unsigned int offset255(int) { return offset = 255; } virtual unsigned int offset256(int) { return offset = 256; } virtual unsigned int offset257(int) { return offset = 257; } virtual unsigned int offset258(int) { return offset = 258; } virtual unsigned int offset259(int) { return offset = 259; } virtual unsigned int offset260(int) { return offset = 260; } virtual unsigned int offset261(int) { return offset = 261; } virtual unsigned int offset262(int) { return offset = 262; } virtual unsigned int offset263(int) { return offset = 263; } virtual unsigned int offset264(int) { return offset = 264; } virtual unsigned int offset265(int) { return offset = 265; } virtual unsigned int offset266(int) { return offset = 266; } virtual unsigned int offset267(int) { return offset = 267; } virtual unsigned int offset268(int) { return offset = 268; } virtual unsigned int offset269(int) { return offset = 269; } virtual unsigned int offset270(int) { return offset = 270; } virtual unsigned int offset271(int) { return offset = 271; } virtual unsigned int offset272(int) { return offset = 272; } virtual unsigned int offset273(int) { return offset = 273; } virtual unsigned int offset274(int) { return offset = 274; } virtual unsigned int offset275(int) { return offset = 275; } virtual unsigned int offset276(int) { return offset = 276; } virtual unsigned int offset277(int) { return offset = 277; } virtual unsigned int offset278(int) { return offset = 278; } virtual unsigned int offset279(int) { return offset = 279; } virtual unsigned int offset280(int) { return offset = 280; } virtual unsigned int offset281(int) { return offset = 281; } virtual unsigned int offset282(int) { return offset = 282; } virtual unsigned int offset283(int) { return offset = 283; } virtual unsigned int offset284(int) { return offset = 284; } virtual unsigned int offset285(int) { return offset = 285; } virtual unsigned int offset286(int) { return offset = 286; } virtual unsigned int offset287(int) { return offset = 287; } virtual unsigned int offset288(int) { return offset = 288; } virtual unsigned int offset289(int) { return offset = 289; } virtual unsigned int offset290(int) { return offset = 290; } virtual unsigned int offset291(int) { return offset = 291; } virtual unsigned int offset292(int) { return offset = 292; } virtual unsigned int offset293(int) { return offset = 293; } virtual unsigned int offset294(int) { return offset = 294; } virtual unsigned int offset295(int) { return offset = 295; } virtual unsigned int offset296(int) { return offset = 296; } virtual unsigned int offset297(int) { return offset = 297; } virtual unsigned int offset298(int) { return offset = 298; } virtual unsigned int offset299(int) { return offset = 299; } virtual unsigned int offset300(int) { return offset = 300; } virtual unsigned int offset301(int) { return offset = 301; } virtual unsigned int offset302(int) { return offset = 302; } virtual unsigned int offset303(int) { return offset = 303; } virtual unsigned int offset304(int) { return offset = 304; } virtual unsigned int offset305(int) { return offset = 305; } virtual unsigned int offset306(int) { return offset = 306; } virtual unsigned int offset307(int) { return offset = 307; } virtual unsigned int offset308(int) { return offset = 308; } virtual unsigned int offset309(int) { return offset = 309; } virtual unsigned int offset310(int) { return offset = 310; } virtual unsigned int offset311(int) { return offset = 311; } virtual unsigned int offset312(int) { return offset = 312; } virtual unsigned int offset313(int) { return offset = 313; } virtual unsigned int offset314(int) { return offset = 314; } virtual unsigned int offset315(int) { return offset = 315; } virtual unsigned int offset316(int) { return offset = 316; } virtual unsigned int offset317(int) { return offset = 317; } virtual unsigned int offset318(int) { return offset = 318; } virtual unsigned int offset319(int) { return offset = 319; } virtual unsigned int offset320(int) { return offset = 320; } virtual unsigned int offset321(int) { return offset = 321; } virtual unsigned int offset322(int) { return offset = 322; } virtual unsigned int offset323(int) { return offset = 323; } virtual unsigned int offset324(int) { return offset = 324; } virtual unsigned int offset325(int) { return offset = 325; } virtual unsigned int offset326(int) { return offset = 326; } virtual unsigned int offset327(int) { return offset = 327; } virtual unsigned int offset328(int) { return offset = 328; } virtual unsigned int offset329(int) { return offset = 329; } virtual unsigned int offset330(int) { return offset = 330; } virtual unsigned int offset331(int) { return offset = 331; } virtual unsigned int offset332(int) { return offset = 332; } virtual unsigned int offset333(int) { return offset = 333; } virtual unsigned int offset334(int) { return offset = 334; } virtual unsigned int offset335(int) { return offset = 335; } virtual unsigned int offset336(int) { return offset = 336; } virtual unsigned int offset337(int) { return offset = 337; } virtual unsigned int offset338(int) { return offset = 338; } virtual unsigned int offset339(int) { return offset = 339; } virtual unsigned int offset340(int) { return offset = 340; } virtual unsigned int offset341(int) { return offset = 341; } virtual unsigned int offset342(int) { return offset = 342; } virtual unsigned int offset343(int) { return offset = 343; } virtual unsigned int offset344(int) { return offset = 344; } virtual unsigned int offset345(int) { return offset = 345; } virtual unsigned int offset346(int) { return offset = 346; } virtual unsigned int offset347(int) { return offset = 347; } virtual unsigned int offset348(int) { return offset = 348; } virtual unsigned int offset349(int) { return offset = 349; } virtual unsigned int offset350(int) { return offset = 350; } virtual unsigned int offset351(int) { return offset = 351; } virtual unsigned int offset352(int) { return offset = 352; } virtual unsigned int offset353(int) { return offset = 353; } virtual unsigned int offset354(int) { return offset = 354; } virtual unsigned int offset355(int) { return offset = 355; } virtual unsigned int offset356(int) { return offset = 356; } virtual unsigned int offset357(int) { return offset = 357; } virtual unsigned int offset358(int) { return offset = 358; } virtual unsigned int offset359(int) { return offset = 359; } virtual unsigned int offset360(int) { return offset = 360; } virtual unsigned int offset361(int) { return offset = 361; } virtual unsigned int offset362(int) { return offset = 362; } virtual unsigned int offset363(int) { return offset = 363; } virtual unsigned int offset364(int) { return offset = 364; } virtual unsigned int offset365(int) { return offset = 365; } virtual unsigned int offset366(int) { return offset = 366; } virtual unsigned int offset367(int) { return offset = 367; } virtual unsigned int offset368(int) { return offset = 368; } virtual unsigned int offset369(int) { return offset = 369; } virtual unsigned int offset370(int) { return offset = 370; } virtual unsigned int offset371(int) { return offset = 371; } virtual unsigned int offset372(int) { return offset = 372; } virtual unsigned int offset373(int) { return offset = 373; } virtual unsigned int offset374(int) { return offset = 374; } virtual unsigned int offset375(int) { return offset = 375; } virtual unsigned int offset376(int) { return offset = 376; } virtual unsigned int offset377(int) { return offset = 377; } virtual unsigned int offset378(int) { return offset = 378; } virtual unsigned int offset379(int) { return offset = 379; } virtual unsigned int offset380(int) { return offset = 380; } virtual unsigned int offset381(int) { return offset = 381; } virtual unsigned int offset382(int) { return offset = 382; } virtual unsigned int offset383(int) { return offset = 383; } virtual unsigned int offset384(int) { return offset = 384; } virtual unsigned int offset385(int) { return offset = 385; } virtual unsigned int offset386(int) { return offset = 386; } virtual unsigned int offset387(int) { return offset = 387; } virtual unsigned int offset388(int) { return offset = 388; } virtual unsigned int offset389(int) { return offset = 389; } virtual unsigned int offset390(int) { return offset = 390; } virtual unsigned int offset391(int) { return offset = 391; } virtual unsigned int offset392(int) { return offset = 392; } virtual unsigned int offset393(int) { return offset = 393; } virtual unsigned int offset394(int) { return offset = 394; } virtual unsigned int offset395(int) { return offset = 395; } virtual unsigned int offset396(int) { return offset = 396; } virtual unsigned int offset397(int) { return offset = 397; } virtual unsigned int offset398(int) { return offset = 398; } virtual unsigned int offset399(int) { return offset = 399; } virtual unsigned int offset400(int) { return offset = 400; } virtual unsigned int offset401(int) { return offset = 401; } virtual unsigned int offset402(int) { return offset = 402; } virtual unsigned int offset403(int) { return offset = 403; } virtual unsigned int offset404(int) { return offset = 404; } virtual unsigned int offset405(int) { return offset = 405; } virtual unsigned int offset406(int) { return offset = 406; } virtual unsigned int offset407(int) { return offset = 407; } virtual unsigned int offset408(int) { return offset = 408; } virtual unsigned int offset409(int) { return offset = 409; } virtual unsigned int offset410(int) { return offset = 410; } virtual unsigned int offset411(int) { return offset = 411; } virtual unsigned int offset412(int) { return offset = 412; } virtual unsigned int offset413(int) { return offset = 413; } virtual unsigned int offset414(int) { return offset = 414; } virtual unsigned int offset415(int) { return offset = 415; } virtual unsigned int offset416(int) { return offset = 416; } virtual unsigned int offset417(int) { return offset = 417; } virtual unsigned int offset418(int) { return offset = 418; } virtual unsigned int offset419(int) { return offset = 419; } virtual unsigned int offset420(int) { return offset = 420; } virtual unsigned int offset421(int) { return offset = 421; } virtual unsigned int offset422(int) { return offset = 422; } virtual unsigned int offset423(int) { return offset = 423; } virtual unsigned int offset424(int) { return offset = 424; } virtual unsigned int offset425(int) { return offset = 425; } virtual unsigned int offset426(int) { return offset = 426; } virtual unsigned int offset427(int) { return offset = 427; } virtual unsigned int offset428(int) { return offset = 428; } virtual unsigned int offset429(int) { return offset = 429; } virtual unsigned int offset430(int) { return offset = 430; } virtual unsigned int offset431(int) { return offset = 431; } virtual unsigned int offset432(int) { return offset = 432; } virtual unsigned int offset433(int) { return offset = 433; } virtual unsigned int offset434(int) { return offset = 434; } virtual unsigned int offset435(int) { return offset = 435; } virtual unsigned int offset436(int) { return offset = 436; } virtual unsigned int offset437(int) { return offset = 437; } virtual unsigned int offset438(int) { return offset = 438; } virtual unsigned int offset439(int) { return offset = 439; } virtual unsigned int offset440(int) { return offset = 440; } virtual unsigned int offset441(int) { return offset = 441; } virtual unsigned int offset442(int) { return offset = 442; } virtual unsigned int offset443(int) { return offset = 443; } virtual unsigned int offset444(int) { return offset = 444; } virtual unsigned int offset445(int) { return offset = 445; } virtual unsigned int offset446(int) { return offset = 446; } virtual unsigned int offset447(int) { return offset = 447; } virtual unsigned int offset448(int) { return offset = 448; } virtual unsigned int offset449(int) { return offset = 449; } virtual unsigned int offset450(int) { return offset = 450; } virtual unsigned int offset451(int) { return offset = 451; } virtual unsigned int offset452(int) { return offset = 452; } virtual unsigned int offset453(int) { return offset = 453; } virtual unsigned int offset454(int) { return offset = 454; } virtual unsigned int offset455(int) { return offset = 455; } virtual unsigned int offset456(int) { return offset = 456; } virtual unsigned int offset457(int) { return offset = 457; } virtual unsigned int offset458(int) { return offset = 458; } virtual unsigned int offset459(int) { return offset = 459; } virtual unsigned int offset460(int) { return offset = 460; } virtual unsigned int offset461(int) { return offset = 461; } virtual unsigned int offset462(int) { return offset = 462; } virtual unsigned int offset463(int) { return offset = 463; } virtual unsigned int offset464(int) { return offset = 464; } virtual unsigned int offset465(int) { return offset = 465; } virtual unsigned int offset466(int) { return offset = 466; } virtual unsigned int offset467(int) { return offset = 467; } virtual unsigned int offset468(int) { return offset = 468; } virtual unsigned int offset469(int) { return offset = 469; } virtual unsigned int offset470(int) { return offset = 470; } virtual unsigned int offset471(int) { return offset = 471; } virtual unsigned int offset472(int) { return offset = 472; } virtual unsigned int offset473(int) { return offset = 473; } virtual unsigned int offset474(int) { return offset = 474; } virtual unsigned int offset475(int) { return offset = 475; } virtual unsigned int offset476(int) { return offset = 476; } virtual unsigned int offset477(int) { return offset = 477; } virtual unsigned int offset478(int) { return offset = 478; } virtual unsigned int offset479(int) { return offset = 479; } virtual unsigned int offset480(int) { return offset = 480; } virtual unsigned int offset481(int) { return offset = 481; } virtual unsigned int offset482(int) { return offset = 482; } virtual unsigned int offset483(int) { return offset = 483; } virtual unsigned int offset484(int) { return offset = 484; } virtual unsigned int offset485(int) { return offset = 485; } virtual unsigned int offset486(int) { return offset = 486; } virtual unsigned int offset487(int) { return offset = 487; } virtual unsigned int offset488(int) { return offset = 488; } virtual unsigned int offset489(int) { return offset = 489; } virtual unsigned int offset490(int) { return offset = 490; } virtual unsigned int offset491(int) { return offset = 491; } virtual unsigned int offset492(int) { return offset = 492; } virtual unsigned int offset493(int) { return offset = 493; } virtual unsigned int offset494(int) { return offset = 494; } virtual unsigned int offset495(int) { return offset = 495; } virtual unsigned int offset496(int) { return offset = 496; } virtual unsigned int offset497(int) { return offset = 497; } virtual unsigned int offset498(int) { return offset = 498; } virtual unsigned int offset499(int) { return offset = 499; } virtual unsigned int offset500(int) { return offset = 500; } virtual unsigned int offset501(int) { return offset = 501; } virtual unsigned int offset502(int) { return offset = 502; } virtual unsigned int offset503(int) { return offset = 503; } virtual unsigned int offset504(int) { return offset = 504; } virtual unsigned int offset505(int) { return offset = 505; } virtual unsigned int offset506(int) { return offset = 506; } virtual unsigned int offset507(int) { return offset = 507; } virtual unsigned int offset508(int) { return offset = 508; } virtual unsigned int offset509(int) { return offset = 509; } virtual unsigned int offset510(int) { return offset = 510; } virtual unsigned int offset511(int) { return offset = 511; } virtual unsigned int offset512(int) { return offset = 512; } virtual unsigned int offset513(int) { return offset = 513; } virtual unsigned int offset514(int) { return offset = 514; } virtual unsigned int offset515(int) { return offset = 515; } virtual unsigned int offset516(int) { return offset = 516; } virtual unsigned int offset517(int) { return offset = 517; } virtual unsigned int offset518(int) { return offset = 518; } virtual unsigned int offset519(int) { return offset = 519; } virtual unsigned int offset520(int) { return offset = 520; } virtual unsigned int offset521(int) { return offset = 521; } virtual unsigned int offset522(int) { return offset = 522; } virtual unsigned int offset523(int) { return offset = 523; } virtual unsigned int offset524(int) { return offset = 524; } virtual unsigned int offset525(int) { return offset = 525; } virtual unsigned int offset526(int) { return offset = 526; } virtual unsigned int offset527(int) { return offset = 527; } virtual unsigned int offset528(int) { return offset = 528; } virtual unsigned int offset529(int) { return offset = 529; } virtual unsigned int offset530(int) { return offset = 530; } virtual unsigned int offset531(int) { return offset = 531; } virtual unsigned int offset532(int) { return offset = 532; } virtual unsigned int offset533(int) { return offset = 533; } virtual unsigned int offset534(int) { return offset = 534; } virtual unsigned int offset535(int) { return offset = 535; } virtual unsigned int offset536(int) { return offset = 536; } virtual unsigned int offset537(int) { return offset = 537; } virtual unsigned int offset538(int) { return offset = 538; } virtual unsigned int offset539(int) { return offset = 539; } virtual unsigned int offset540(int) { return offset = 540; } virtual unsigned int offset541(int) { return offset = 541; } virtual unsigned int offset542(int) { return offset = 542; } virtual unsigned int offset543(int) { return offset = 543; } virtual unsigned int offset544(int) { return offset = 544; } virtual unsigned int offset545(int) { return offset = 545; } virtual unsigned int offset546(int) { return offset = 546; } virtual unsigned int offset547(int) { return offset = 547; } virtual unsigned int offset548(int) { return offset = 548; } virtual unsigned int offset549(int) { return offset = 549; } virtual unsigned int offset550(int) { return offset = 550; } virtual unsigned int offset551(int) { return offset = 551; } virtual unsigned int offset552(int) { return offset = 552; } virtual unsigned int offset553(int) { return offset = 553; } virtual unsigned int offset554(int) { return offset = 554; } virtual unsigned int offset555(int) { return offset = 555; } virtual unsigned int offset556(int) { return offset = 556; } virtual unsigned int offset557(int) { return offset = 557; } virtual unsigned int offset558(int) { return offset = 558; } virtual unsigned int offset559(int) { return offset = 559; } virtual unsigned int offset560(int) { return offset = 560; } virtual unsigned int offset561(int) { return offset = 561; } virtual unsigned int offset562(int) { return offset = 562; } virtual unsigned int offset563(int) { return offset = 563; } virtual unsigned int offset564(int) { return offset = 564; } virtual unsigned int offset565(int) { return offset = 565; } virtual unsigned int offset566(int) { return offset = 566; } virtual unsigned int offset567(int) { return offset = 567; } virtual unsigned int offset568(int) { return offset = 568; } virtual unsigned int offset569(int) { return offset = 569; } virtual unsigned int offset570(int) { return offset = 570; } virtual unsigned int offset571(int) { return offset = 571; } virtual unsigned int offset572(int) { return offset = 572; } virtual unsigned int offset573(int) { return offset = 573; } virtual unsigned int offset574(int) { return offset = 574; } virtual unsigned int offset575(int) { return offset = 575; } virtual unsigned int offset576(int) { return offset = 576; } virtual unsigned int offset577(int) { return offset = 577; } virtual unsigned int offset578(int) { return offset = 578; } virtual unsigned int offset579(int) { return offset = 579; } virtual unsigned int offset580(int) { return offset = 580; } virtual unsigned int offset581(int) { return offset = 581; } virtual unsigned int offset582(int) { return offset = 582; } virtual unsigned int offset583(int) { return offset = 583; } virtual unsigned int offset584(int) { return offset = 584; } virtual unsigned int offset585(int) { return offset = 585; } virtual unsigned int offset586(int) { return offset = 586; } virtual unsigned int offset587(int) { return offset = 587; } virtual unsigned int offset588(int) { return offset = 588; } virtual unsigned int offset589(int) { return offset = 589; } virtual unsigned int offset590(int) { return offset = 590; } virtual unsigned int offset591(int) { return offset = 591; } virtual unsigned int offset592(int) { return offset = 592; } virtual unsigned int offset593(int) { return offset = 593; } virtual unsigned int offset594(int) { return offset = 594; } virtual unsigned int offset595(int) { return offset = 595; } virtual unsigned int offset596(int) { return offset = 596; } virtual unsigned int offset597(int) { return offset = 597; } virtual unsigned int offset598(int) { return offset = 598; } virtual unsigned int offset599(int) { return offset = 599; } virtual unsigned int offset600(int) { return offset = 600; } virtual unsigned int offset601(int) { return offset = 601; } virtual unsigned int offset602(int) { return offset = 602; } virtual unsigned int offset603(int) { return offset = 603; } virtual unsigned int offset604(int) { return offset = 604; } virtual unsigned int offset605(int) { return offset = 605; } virtual unsigned int offset606(int) { return offset = 606; } virtual unsigned int offset607(int) { return offset = 607; } virtual unsigned int offset608(int) { return offset = 608; } virtual unsigned int offset609(int) { return offset = 609; } virtual unsigned int offset610(int) { return offset = 610; } virtual unsigned int offset611(int) { return offset = 611; } virtual unsigned int offset612(int) { return offset = 612; } virtual unsigned int offset613(int) { return offset = 613; } virtual unsigned int offset614(int) { return offset = 614; } virtual unsigned int offset615(int) { return offset = 615; } virtual unsigned int offset616(int) { return offset = 616; } virtual unsigned int offset617(int) { return offset = 617; } virtual unsigned int offset618(int) { return offset = 618; } virtual unsigned int offset619(int) { return offset = 619; } virtual unsigned int offset620(int) { return offset = 620; } virtual unsigned int offset621(int) { return offset = 621; } virtual unsigned int offset622(int) { return offset = 622; } virtual unsigned int offset623(int) { return offset = 623; } virtual unsigned int offset624(int) { return offset = 624; } virtual unsigned int offset625(int) { return offset = 625; } virtual unsigned int offset626(int) { return offset = 626; } virtual unsigned int offset627(int) { return offset = 627; } virtual unsigned int offset628(int) { return offset = 628; } virtual unsigned int offset629(int) { return offset = 629; } virtual unsigned int offset630(int) { return offset = 630; } virtual unsigned int offset631(int) { return offset = 631; } virtual unsigned int offset632(int) { return offset = 632; } virtual unsigned int offset633(int) { return offset = 633; } virtual unsigned int offset634(int) { return offset = 634; } virtual unsigned int offset635(int) { return offset = 635; } virtual unsigned int offset636(int) { return offset = 636; } virtual unsigned int offset637(int) { return offset = 637; } virtual unsigned int offset638(int) { return offset = 638; } virtual unsigned int offset639(int) { return offset = 639; } virtual unsigned int offset640(int) { return offset = 640; } virtual unsigned int offset641(int) { return offset = 641; } virtual unsigned int offset642(int) { return offset = 642; } virtual unsigned int offset643(int) { return offset = 643; } virtual unsigned int offset644(int) { return offset = 644; } virtual unsigned int offset645(int) { return offset = 645; } virtual unsigned int offset646(int) { return offset = 646; } virtual unsigned int offset647(int) { return offset = 647; } virtual unsigned int offset648(int) { return offset = 648; } virtual unsigned int offset649(int) { return offset = 649; } virtual unsigned int offset650(int) { return offset = 650; } virtual unsigned int offset651(int) { return offset = 651; } virtual unsigned int offset652(int) { return offset = 652; } virtual unsigned int offset653(int) { return offset = 653; } virtual unsigned int offset654(int) { return offset = 654; } virtual unsigned int offset655(int) { return offset = 655; } virtual unsigned int offset656(int) { return offset = 656; } virtual unsigned int offset657(int) { return offset = 657; } virtual unsigned int offset658(int) { return offset = 658; } virtual unsigned int offset659(int) { return offset = 659; } virtual unsigned int offset660(int) { return offset = 660; } virtual unsigned int offset661(int) { return offset = 661; } virtual unsigned int offset662(int) { return offset = 662; } virtual unsigned int offset663(int) { return offset = 663; } virtual unsigned int offset664(int) { return offset = 664; } virtual unsigned int offset665(int) { return offset = 665; } virtual unsigned int offset666(int) { return offset = 666; } virtual unsigned int offset667(int) { return offset = 667; } virtual unsigned int offset668(int) { return offset = 668; } virtual unsigned int offset669(int) { return offset = 669; } virtual unsigned int offset670(int) { return offset = 670; } virtual unsigned int offset671(int) { return offset = 671; } virtual unsigned int offset672(int) { return offset = 672; } virtual unsigned int offset673(int) { return offset = 673; } virtual unsigned int offset674(int) { return offset = 674; } virtual unsigned int offset675(int) { return offset = 675; } virtual unsigned int offset676(int) { return offset = 676; } virtual unsigned int offset677(int) { return offset = 677; } virtual unsigned int offset678(int) { return offset = 678; } virtual unsigned int offset679(int) { return offset = 679; } virtual unsigned int offset680(int) { return offset = 680; } virtual unsigned int offset681(int) { return offset = 681; } virtual unsigned int offset682(int) { return offset = 682; } virtual unsigned int offset683(int) { return offset = 683; } virtual unsigned int offset684(int) { return offset = 684; } virtual unsigned int offset685(int) { return offset = 685; } virtual unsigned int offset686(int) { return offset = 686; } virtual unsigned int offset687(int) { return offset = 687; } virtual unsigned int offset688(int) { return offset = 688; } virtual unsigned int offset689(int) { return offset = 689; } virtual unsigned int offset690(int) { return offset = 690; } virtual unsigned int offset691(int) { return offset = 691; } virtual unsigned int offset692(int) { return offset = 692; } virtual unsigned int offset693(int) { return offset = 693; } virtual unsigned int offset694(int) { return offset = 694; } virtual unsigned int offset695(int) { return offset = 695; } virtual unsigned int offset696(int) { return offset = 696; } virtual unsigned int offset697(int) { return offset = 697; } virtual unsigned int offset698(int) { return offset = 698; } virtual unsigned int offset699(int) { return offset = 699; } virtual unsigned int offset700(int) { return offset = 700; } virtual unsigned int offset701(int) { return offset = 701; } virtual unsigned int offset702(int) { return offset = 702; } virtual unsigned int offset703(int) { return offset = 703; } virtual unsigned int offset704(int) { return offset = 704; } virtual unsigned int offset705(int) { return offset = 705; } virtual unsigned int offset706(int) { return offset = 706; } virtual unsigned int offset707(int) { return offset = 707; } virtual unsigned int offset708(int) { return offset = 708; } virtual unsigned int offset709(int) { return offset = 709; } virtual unsigned int offset710(int) { return offset = 710; } virtual unsigned int offset711(int) { return offset = 711; } virtual unsigned int offset712(int) { return offset = 712; } virtual unsigned int offset713(int) { return offset = 713; } virtual unsigned int offset714(int) { return offset = 714; } virtual unsigned int offset715(int) { return offset = 715; } virtual unsigned int offset716(int) { return offset = 716; } virtual unsigned int offset717(int) { return offset = 717; } virtual unsigned int offset718(int) { return offset = 718; } virtual unsigned int offset719(int) { return offset = 719; } virtual unsigned int offset720(int) { return offset = 720; } virtual unsigned int offset721(int) { return offset = 721; } virtual unsigned int offset722(int) { return offset = 722; } virtual unsigned int offset723(int) { return offset = 723; } virtual unsigned int offset724(int) { return offset = 724; } virtual unsigned int offset725(int) { return offset = 725; } virtual unsigned int offset726(int) { return offset = 726; } virtual unsigned int offset727(int) { return offset = 727; } virtual unsigned int offset728(int) { return offset = 728; } virtual unsigned int offset729(int) { return offset = 729; } virtual unsigned int offset730(int) { return offset = 730; } virtual unsigned int offset731(int) { return offset = 731; } virtual unsigned int offset732(int) { return offset = 732; } virtual unsigned int offset733(int) { return offset = 733; } virtual unsigned int offset734(int) { return offset = 734; } virtual unsigned int offset735(int) { return offset = 735; } virtual unsigned int offset736(int) { return offset = 736; } virtual unsigned int offset737(int) { return offset = 737; } virtual unsigned int offset738(int) { return offset = 738; } virtual unsigned int offset739(int) { return offset = 739; } virtual unsigned int offset740(int) { return offset = 740; } virtual unsigned int offset741(int) { return offset = 741; } virtual unsigned int offset742(int) { return offset = 742; } virtual unsigned int offset743(int) { return offset = 743; } virtual unsigned int offset744(int) { return offset = 744; } virtual unsigned int offset745(int) { return offset = 745; } virtual unsigned int offset746(int) { return offset = 746; } virtual unsigned int offset747(int) { return offset = 747; } virtual unsigned int offset748(int) { return offset = 748; } virtual unsigned int offset749(int) { return offset = 749; } virtual unsigned int offset750(int) { return offset = 750; } virtual unsigned int offset751(int) { return offset = 751; } virtual unsigned int offset752(int) { return offset = 752; } virtual unsigned int offset753(int) { return offset = 753; } virtual unsigned int offset754(int) { return offset = 754; } virtual unsigned int offset755(int) { return offset = 755; } virtual unsigned int offset756(int) { return offset = 756; } virtual unsigned int offset757(int) { return offset = 757; } virtual unsigned int offset758(int) { return offset = 758; } virtual unsigned int offset759(int) { return offset = 759; } virtual unsigned int offset760(int) { return offset = 760; } virtual unsigned int offset761(int) { return offset = 761; } virtual unsigned int offset762(int) { return offset = 762; } virtual unsigned int offset763(int) { return offset = 763; } virtual unsigned int offset764(int) { return offset = 764; } virtual unsigned int offset765(int) { return offset = 765; } virtual unsigned int offset766(int) { return offset = 766; } virtual unsigned int offset767(int) { return offset = 767; } virtual unsigned int offset768(int) { return offset = 768; } virtual unsigned int offset769(int) { return offset = 769; } virtual unsigned int offset770(int) { return offset = 770; } virtual unsigned int offset771(int) { return offset = 771; } virtual unsigned int offset772(int) { return offset = 772; } virtual unsigned int offset773(int) { return offset = 773; } virtual unsigned int offset774(int) { return offset = 774; } virtual unsigned int offset775(int) { return offset = 775; } virtual unsigned int offset776(int) { return offset = 776; } virtual unsigned int offset777(int) { return offset = 777; } virtual unsigned int offset778(int) { return offset = 778; } virtual unsigned int offset779(int) { return offset = 779; } virtual unsigned int offset780(int) { return offset = 780; } virtual unsigned int offset781(int) { return offset = 781; } virtual unsigned int offset782(int) { return offset = 782; } virtual unsigned int offset783(int) { return offset = 783; } virtual unsigned int offset784(int) { return offset = 784; } virtual unsigned int offset785(int) { return offset = 785; } virtual unsigned int offset786(int) { return offset = 786; } virtual unsigned int offset787(int) { return offset = 787; } virtual unsigned int offset788(int) { return offset = 788; } virtual unsigned int offset789(int) { return offset = 789; } virtual unsigned int offset790(int) { return offset = 790; } virtual unsigned int offset791(int) { return offset = 791; } virtual unsigned int offset792(int) { return offset = 792; } virtual unsigned int offset793(int) { return offset = 793; } virtual unsigned int offset794(int) { return offset = 794; } virtual unsigned int offset795(int) { return offset = 795; } virtual unsigned int offset796(int) { return offset = 796; } virtual unsigned int offset797(int) { return offset = 797; } virtual unsigned int offset798(int) { return offset = 798; } virtual unsigned int offset799(int) { return offset = 799; } virtual unsigned int offset800(int) { return offset = 800; } virtual unsigned int offset801(int) { return offset = 801; } virtual unsigned int offset802(int) { return offset = 802; } virtual unsigned int offset803(int) { return offset = 803; } virtual unsigned int offset804(int) { return offset = 804; } virtual unsigned int offset805(int) { return offset = 805; } virtual unsigned int offset806(int) { return offset = 806; } virtual unsigned int offset807(int) { return offset = 807; } virtual unsigned int offset808(int) { return offset = 808; } virtual unsigned int offset809(int) { return offset = 809; } virtual unsigned int offset810(int) { return offset = 810; } virtual unsigned int offset811(int) { return offset = 811; } virtual unsigned int offset812(int) { return offset = 812; } virtual unsigned int offset813(int) { return offset = 813; } virtual unsigned int offset814(int) { return offset = 814; } virtual unsigned int offset815(int) { return offset = 815; } virtual unsigned int offset816(int) { return offset = 816; } virtual unsigned int offset817(int) { return offset = 817; } virtual unsigned int offset818(int) { return offset = 818; } virtual unsigned int offset819(int) { return offset = 819; } virtual unsigned int offset820(int) { return offset = 820; } virtual unsigned int offset821(int) { return offset = 821; } virtual unsigned int offset822(int) { return offset = 822; } virtual unsigned int offset823(int) { return offset = 823; } virtual unsigned int offset824(int) { return offset = 824; } virtual unsigned int offset825(int) { return offset = 825; } virtual unsigned int offset826(int) { return offset = 826; } virtual unsigned int offset827(int) { return offset = 827; } virtual unsigned int offset828(int) { return offset = 828; } virtual unsigned int offset829(int) { return offset = 829; } virtual unsigned int offset830(int) { return offset = 830; } virtual unsigned int offset831(int) { return offset = 831; } virtual unsigned int offset832(int) { return offset = 832; } virtual unsigned int offset833(int) { return offset = 833; } virtual unsigned int offset834(int) { return offset = 834; } virtual unsigned int offset835(int) { return offset = 835; } virtual unsigned int offset836(int) { return offset = 836; } virtual unsigned int offset837(int) { return offset = 837; } virtual unsigned int offset838(int) { return offset = 838; } virtual unsigned int offset839(int) { return offset = 839; } virtual unsigned int offset840(int) { return offset = 840; } virtual unsigned int offset841(int) { return offset = 841; } virtual unsigned int offset842(int) { return offset = 842; } virtual unsigned int offset843(int) { return offset = 843; } virtual unsigned int offset844(int) { return offset = 844; } virtual unsigned int offset845(int) { return offset = 845; } virtual unsigned int offset846(int) { return offset = 846; } virtual unsigned int offset847(int) { return offset = 847; } virtual unsigned int offset848(int) { return offset = 848; } virtual unsigned int offset849(int) { return offset = 849; } virtual unsigned int offset850(int) { return offset = 850; } virtual unsigned int offset851(int) { return offset = 851; } virtual unsigned int offset852(int) { return offset = 852; } virtual unsigned int offset853(int) { return offset = 853; } virtual unsigned int offset854(int) { return offset = 854; } virtual unsigned int offset855(int) { return offset = 855; } virtual unsigned int offset856(int) { return offset = 856; } virtual unsigned int offset857(int) { return offset = 857; } virtual unsigned int offset858(int) { return offset = 858; } virtual unsigned int offset859(int) { return offset = 859; } virtual unsigned int offset860(int) { return offset = 860; } virtual unsigned int offset861(int) { return offset = 861; } virtual unsigned int offset862(int) { return offset = 862; } virtual unsigned int offset863(int) { return offset = 863; } virtual unsigned int offset864(int) { return offset = 864; } virtual unsigned int offset865(int) { return offset = 865; } virtual unsigned int offset866(int) { return offset = 866; } virtual unsigned int offset867(int) { return offset = 867; } virtual unsigned int offset868(int) { return offset = 868; } virtual unsigned int offset869(int) { return offset = 869; } virtual unsigned int offset870(int) { return offset = 870; } virtual unsigned int offset871(int) { return offset = 871; } virtual unsigned int offset872(int) { return offset = 872; } virtual unsigned int offset873(int) { return offset = 873; } virtual unsigned int offset874(int) { return offset = 874; } virtual unsigned int offset875(int) { return offset = 875; } virtual unsigned int offset876(int) { return offset = 876; } virtual unsigned int offset877(int) { return offset = 877; } virtual unsigned int offset878(int) { return offset = 878; } virtual unsigned int offset879(int) { return offset = 879; } virtual unsigned int offset880(int) { return offset = 880; } virtual unsigned int offset881(int) { return offset = 881; } virtual unsigned int offset882(int) { return offset = 882; } virtual unsigned int offset883(int) { return offset = 883; } virtual unsigned int offset884(int) { return offset = 884; } virtual unsigned int offset885(int) { return offset = 885; } virtual unsigned int offset886(int) { return offset = 886; } virtual unsigned int offset887(int) { return offset = 887; } virtual unsigned int offset888(int) { return offset = 888; } virtual unsigned int offset889(int) { return offset = 889; } virtual unsigned int offset890(int) { return offset = 890; } virtual unsigned int offset891(int) { return offset = 891; } virtual unsigned int offset892(int) { return offset = 892; } virtual unsigned int offset893(int) { return offset = 893; } virtual unsigned int offset894(int) { return offset = 894; } virtual unsigned int offset895(int) { return offset = 895; } virtual unsigned int offset896(int) { return offset = 896; } virtual unsigned int offset897(int) { return offset = 897; } virtual unsigned int offset898(int) { return offset = 898; } virtual unsigned int offset899(int) { return offset = 899; } virtual unsigned int offset900(int) { return offset = 900; } virtual unsigned int offset901(int) { return offset = 901; } virtual unsigned int offset902(int) { return offset = 902; } virtual unsigned int offset903(int) { return offset = 903; } virtual unsigned int offset904(int) { return offset = 904; } virtual unsigned int offset905(int) { return offset = 905; } virtual unsigned int offset906(int) { return offset = 906; } virtual unsigned int offset907(int) { return offset = 907; } virtual unsigned int offset908(int) { return offset = 908; } virtual unsigned int offset909(int) { return offset = 909; } virtual unsigned int offset910(int) { return offset = 910; } virtual unsigned int offset911(int) { return offset = 911; } virtual unsigned int offset912(int) { return offset = 912; } virtual unsigned int offset913(int) { return offset = 913; } virtual unsigned int offset914(int) { return offset = 914; } virtual unsigned int offset915(int) { return offset = 915; } virtual unsigned int offset916(int) { return offset = 916; } virtual unsigned int offset917(int) { return offset = 917; } virtual unsigned int offset918(int) { return offset = 918; } virtual unsigned int offset919(int) { return offset = 919; } virtual unsigned int offset920(int) { return offset = 920; } virtual unsigned int offset921(int) { return offset = 921; } virtual unsigned int offset922(int) { return offset = 922; } virtual unsigned int offset923(int) { return offset = 923; } virtual unsigned int offset924(int) { return offset = 924; } virtual unsigned int offset925(int) { return offset = 925; } virtual unsigned int offset926(int) { return offset = 926; } virtual unsigned int offset927(int) { return offset = 927; } virtual unsigned int offset928(int) { return offset = 928; } virtual unsigned int offset929(int) { return offset = 929; } virtual unsigned int offset930(int) { return offset = 930; } virtual unsigned int offset931(int) { return offset = 931; } virtual unsigned int offset932(int) { return offset = 932; } virtual unsigned int offset933(int) { return offset = 933; } virtual unsigned int offset934(int) { return offset = 934; } virtual unsigned int offset935(int) { return offset = 935; } virtual unsigned int offset936(int) { return offset = 936; } virtual unsigned int offset937(int) { return offset = 937; } virtual unsigned int offset938(int) { return offset = 938; } virtual unsigned int offset939(int) { return offset = 939; } virtual unsigned int offset940(int) { return offset = 940; } virtual unsigned int offset941(int) { return offset = 941; } virtual unsigned int offset942(int) { return offset = 942; } virtual unsigned int offset943(int) { return offset = 943; } virtual unsigned int offset944(int) { return offset = 944; } virtual unsigned int offset945(int) { return offset = 945; } virtual unsigned int offset946(int) { return offset = 946; } virtual unsigned int offset947(int) { return offset = 947; } virtual unsigned int offset948(int) { return offset = 948; } virtual unsigned int offset949(int) { return offset = 949; } virtual unsigned int offset950(int) { return offset = 950; } virtual unsigned int offset951(int) { return offset = 951; } virtual unsigned int offset952(int) { return offset = 952; } virtual unsigned int offset953(int) { return offset = 953; } virtual unsigned int offset954(int) { return offset = 954; } virtual unsigned int offset955(int) { return offset = 955; } virtual unsigned int offset956(int) { return offset = 956; } virtual unsigned int offset957(int) { return offset = 957; } virtual unsigned int offset958(int) { return offset = 958; } virtual unsigned int offset959(int) { return offset = 959; } virtual unsigned int offset960(int) { return offset = 960; } virtual unsigned int offset961(int) { return offset = 961; } virtual unsigned int offset962(int) { return offset = 962; } virtual unsigned int offset963(int) { return offset = 963; } virtual unsigned int offset964(int) { return offset = 964; } virtual unsigned int offset965(int) { return offset = 965; } virtual unsigned int offset966(int) { return offset = 966; } virtual unsigned int offset967(int) { return offset = 967; } virtual unsigned int offset968(int) { return offset = 968; } virtual unsigned int offset969(int) { return offset = 969; } virtual unsigned int offset970(int) { return offset = 970; } virtual unsigned int offset971(int) { return offset = 971; } virtual unsigned int offset972(int) { return offset = 972; } virtual unsigned int offset973(int) { return offset = 973; } virtual unsigned int offset974(int) { return offset = 974; } virtual unsigned int offset975(int) { return offset = 975; } virtual unsigned int offset976(int) { return offset = 976; } virtual unsigned int offset977(int) { return offset = 977; } virtual unsigned int offset978(int) { return offset = 978; } virtual unsigned int offset979(int) { return offset = 979; } virtual unsigned int offset980(int) { return offset = 980; } virtual unsigned int offset981(int) { return offset = 981; } virtual unsigned int offset982(int) { return offset = 982; } virtual unsigned int offset983(int) { return offset = 983; } virtual unsigned int offset984(int) { return offset = 984; } virtual unsigned int offset985(int) { return offset = 985; } virtual unsigned int offset986(int) { return offset = 986; } virtual unsigned int offset987(int) { return offset = 987; } virtual unsigned int offset988(int) { return offset = 988; } virtual unsigned int offset989(int) { return offset = 989; } virtual unsigned int offset990(int) { return offset = 990; } virtual unsigned int offset991(int) { return offset = 991; } virtual unsigned int offset992(int) { return offset = 992; } virtual unsigned int offset993(int) { return offset = 993; } virtual unsigned int offset994(int) { return offset = 994; } virtual unsigned int offset995(int) { return offset = 995; } virtual unsigned int offset996(int) { return offset = 996; } virtual unsigned int offset997(int) { return offset = 997; } virtual unsigned int offset998(int) { return offset = 998; } virtual unsigned int offset999(int) { return offset = 999; } virtual unsigned int offset1000(int) { return offset = 1000; } }; } #if defined(__GNUG__) && !defined(__clang__) #define FAKEIT_NO_DEVIRTUALIZE_ATTR [[gnu::optimize("no-devirtualize")]] #else #define FAKEIT_NO_DEVIRTUALIZE_ATTR #endif namespace fakeit { template<typename TARGET, typename SOURCE> FAKEIT_NO_DEVIRTUALIZE_ATTR TARGET union_cast(SOURCE source) { union { SOURCE source; TARGET target; } u; u.source = source; return u.target; } } namespace fakeit { class NoVirtualDtor : public std::runtime_error { public: NoVirtualDtor() :std::runtime_error("Can't mock the destructor. No virtual destructor was found") {} }; class VTUtils { public: #if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 8 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" #endif template<typename C, typename R, typename ... arglist> static unsigned int getOffset(R (C::*vMethod)(arglist...)) { auto sMethod = reinterpret_cast<unsigned int (VirtualOffsetSelector::*)(int)>(vMethod); VirtualOffsetSelector offsetSelctor; return (offsetSelctor.*sMethod)(0); } #if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 8 #pragma GCC diagnostic pop #endif template<typename C> static typename std::enable_if<std::has_virtual_destructor<C>::value, unsigned int>::type getDestructorOffset() { VirtualOffsetSelector offsetSelctor; union_cast<C *>(&offsetSelctor)->~C(); return offsetSelctor.offset; } template<typename C> static typename std::enable_if<!std::has_virtual_destructor<C>::value, unsigned int>::type getDestructorOffset() { throw NoVirtualDtor(); } template<typename C> static typename std::enable_if<std::has_virtual_destructor<C>::value, bool>::type hasVirtualDestructor() { return true; } template<typename C> static typename std::enable_if<!std::has_virtual_destructor<C>::value, bool>::type hasVirtualDestructor() { return false; } template<typename C> static unsigned int getVTSize() { struct Derrived : public C { virtual void endOfVt() { } }; unsigned int vtSize = getOffset(&Derrived::endOfVt); return vtSize; } }; } #ifdef _MSC_VER namespace fakeit { typedef unsigned long dword_; struct TypeDescriptor { TypeDescriptor() : ptrToVTable(0), spare(0) { int **tiVFTPtr = (int **) (&typeid(void)); int *i = (int *) tiVFTPtr[0]; char *type_info_vft_ptr = (char *) i; ptrToVTable = type_info_vft_ptr; } char *ptrToVTable; dword_ spare; char name[8]; }; struct PMD { int mdisp; int pdisp; int vdisp; PMD() : mdisp(0), pdisp(-1), vdisp(0) { } }; struct RTTIBaseClassDescriptor { RTTIBaseClassDescriptor() : pTypeDescriptor(nullptr), numContainedBases(0), attributes(0) { } const std::type_info *pTypeDescriptor; dword_ numContainedBases; struct PMD where; dword_ attributes; }; template<typename C, typename... baseclasses> struct RTTIClassHierarchyDescriptor { RTTIClassHierarchyDescriptor() : signature(0), attributes(0), numBaseClasses(0), pBaseClassArray(nullptr) { pBaseClassArray = new RTTIBaseClassDescriptor *[1 + sizeof...(baseclasses)]; addBaseClass < C, baseclasses...>(); } ~RTTIClassHierarchyDescriptor() { for (int i = 0; i < 1 + sizeof...(baseclasses); i++) { RTTIBaseClassDescriptor *desc = pBaseClassArray[i]; delete desc; } delete[] pBaseClassArray; } dword_ signature; dword_ attributes; dword_ numBaseClasses; RTTIBaseClassDescriptor **pBaseClassArray; template<typename BaseType> void addBaseClass() { static_assert(std::is_base_of<BaseType, C>::value, "C must be a derived class of BaseType"); RTTIBaseClassDescriptor *desc = new RTTIBaseClassDescriptor(); desc->pTypeDescriptor = &typeid(BaseType); pBaseClassArray[numBaseClasses] = desc; for (unsigned int i = 0; i < numBaseClasses; i++) { pBaseClassArray[i]->numContainedBases++; } numBaseClasses++; } template<typename head, typename B1, typename... tail> void addBaseClass() { static_assert(std::is_base_of<B1, head>::value, "invalid inheritance list"); addBaseClass<head>(); addBaseClass<B1, tail...>(); } }; template<typename C, typename... baseclasses> struct RTTICompleteObjectLocator { #ifdef _WIN64 RTTICompleteObjectLocator(const std::type_info &unused) : signature(0), offset(0), cdOffset(0), typeDescriptorOffset(0), classDescriptorOffset(0) { (void)unused; } dword_ signature; dword_ offset; dword_ cdOffset; dword_ typeDescriptorOffset; dword_ classDescriptorOffset; #else RTTICompleteObjectLocator(const std::type_info &info) : signature(0), offset(0), cdOffset(0), pTypeDescriptor(&info), pClassDescriptor(new RTTIClassHierarchyDescriptor<C, baseclasses...>()) { } ~RTTICompleteObjectLocator() { delete pClassDescriptor; } dword_ signature; dword_ offset; dword_ cdOffset; const std::type_info *pTypeDescriptor; struct RTTIClassHierarchyDescriptor<C, baseclasses...> *pClassDescriptor; #endif }; struct VirtualTableBase { static VirtualTableBase &getVTable(void *instance) { fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance); return *vt; } VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { } void *getCookie(int index) { return _firstMethod[-2 - index]; } void setCookie(int index, void *value) { _firstMethod[-2 - index] = value; } void *getMethod(unsigned int index) const { return _firstMethod[index]; } void setMethod(unsigned int index, void *method) { _firstMethod[index] = method; } protected: void **_firstMethod; }; template<class C, class... baseclasses> struct VirtualTable : public VirtualTableBase { class Handle { friend struct VirtualTable<C, baseclasses...>; void **firstMethod; Handle(void **method) : firstMethod(method) { } public: VirtualTable<C, baseclasses...> &restore() { VirtualTable<C, baseclasses...> *vt = (VirtualTable<C, baseclasses...> *) this; return *vt; } }; static VirtualTable<C, baseclasses...> &getVTable(C &instance) { fakeit::VirtualTable<C, baseclasses...> *vt = (fakeit::VirtualTable<C, baseclasses...> *) (&instance); return *vt; } void copyFrom(VirtualTable<C, baseclasses...> &from) { unsigned int size = VTUtils::getVTSize<C>(); for (unsigned int i = 0; i < size; i++) { _firstMethod[i] = from.getMethod(i); } } VirtualTable() : VirtualTable(buildVTArray()) { } ~VirtualTable() { } void dispose() { _firstMethod--; RTTICompleteObjectLocator<C, baseclasses...> *locator = (RTTICompleteObjectLocator<C, baseclasses...> *) _firstMethod[0]; delete locator; _firstMethod -= numOfCookies; delete[] _firstMethod; } unsigned int dtor(int) { C *c = (C *) this; C &cRef = *c; auto vt = VirtualTable<C, baseclasses...>::getVTable(cRef); void *dtorPtr = vt.getCookie(numOfCookies - 1); void(*method)(C *) = reinterpret_cast<void (*)(C *)>(dtorPtr); method(c); return 0; } void setDtor(void *method) { void *dtorPtr = union_cast<void *>(&VirtualTable<C, baseclasses...>::dtor); unsigned int index = VTUtils::getDestructorOffset<C>(); _firstMethod[index] = dtorPtr; setCookie(numOfCookies - 1, method); } unsigned int getSize() { return VTUtils::getVTSize<C>(); } void initAll(void *value) { auto size = getSize(); for (unsigned int i = 0; i < size; i++) { setMethod(i, value); } } Handle createHandle() { Handle h(_firstMethod); return h; } private: class SimpleType { }; static_assert(sizeof(unsigned int (SimpleType::*)()) == sizeof(unsigned int (C::*)()), "Can't mock a type with multiple inheritance or with non-polymorphic base class"); static const unsigned int numOfCookies = 3; static void **buildVTArray() { int vtSize = VTUtils::getVTSize<C>(); auto array = new void *[vtSize + numOfCookies + 1]{}; RTTICompleteObjectLocator<C, baseclasses...> *objectLocator = new RTTICompleteObjectLocator<C, baseclasses...>( typeid(C)); array += numOfCookies; array[0] = objectLocator; array++; return array; } VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) { } }; } #else #ifndef __clang__ #include <type_traits> #include <tr2/type_traits> namespace fakeit { template<typename ... T1> class has_one_base { }; template<typename T1, typename T2, typename ... types> class has_one_base<std::tr2::__reflection_typelist<T1, T2, types...>> : public std::false_type { }; template<typename T1> class has_one_base<std::tr2::__reflection_typelist<T1>> : public has_one_base<typename std::tr2::direct_bases<T1>::type> { }; template<> class has_one_base<std::tr2::__reflection_typelist<>> : public std::true_type { }; template<typename T> class is_simple_inheritance_layout : public has_one_base<typename std::tr2::direct_bases<T>::type> { }; } #endif namespace fakeit { struct VirtualTableBase { static VirtualTableBase &getVTable(void *instance) { fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance); return *vt; } VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { } void *getCookie(int index) { return _firstMethod[-3 - index]; } void setCookie(int index, void *value) { _firstMethod[-3 - index] = value; } void *getMethod(unsigned int index) const { return _firstMethod[index]; } void setMethod(unsigned int index, void *method) { _firstMethod[index] = method; } protected: void **_firstMethod; }; template<class C, class ... baseclasses> struct VirtualTable : public VirtualTableBase { #ifndef __clang__ static_assert(is_simple_inheritance_layout<C>::value, "Can't mock a type with multiple inheritance"); #endif class Handle { friend struct VirtualTable<C, baseclasses...>; void **firstMethod; Handle(void **method) : firstMethod(method) { } public: VirtualTable<C, baseclasses...> &restore() { VirtualTable<C, baseclasses...> *vt = (VirtualTable<C, baseclasses...> *) this; return *vt; } }; static VirtualTable<C, baseclasses...> &getVTable(C &instance) { fakeit::VirtualTable<C, baseclasses...> *vt = (fakeit::VirtualTable<C, baseclasses...> *) (&instance); return *vt; } void copyFrom(VirtualTable<C, baseclasses...> &from) { unsigned int size = VTUtils::getVTSize<C>(); for (size_t i = 0; i < size; ++i) { _firstMethod[i] = from.getMethod(i); } } VirtualTable() : VirtualTable(buildVTArray()) { } void dispose() { _firstMethod--; _firstMethod--; _firstMethod -= numOfCookies; delete[] _firstMethod; } unsigned int dtor(int) { C *c = (C *) this; C &cRef = *c; auto vt = VirtualTable<C, baseclasses...>::getVTable(cRef); unsigned int index = VTUtils::getDestructorOffset<C>(); void *dtorPtr = vt.getMethod(index); void(*method)(C *) = union_cast<void (*)(C *)>(dtorPtr); method(c); return 0; } void setDtor(void *method) { unsigned int index = VTUtils::getDestructorOffset<C>(); void *dtorPtr = union_cast<void *>(&VirtualTable<C, baseclasses...>::dtor); _firstMethod[index] = method; _firstMethod[index + 1] = dtorPtr; } unsigned int getSize() { return VTUtils::getVTSize<C>(); } void initAll(void *value) { unsigned int size = getSize(); for (unsigned int i = 0; i < size; i++) { setMethod(i, value); } } const std::type_info *getTypeId() { return (const std::type_info *) (_firstMethod[-1]); } Handle createHandle() { Handle h(_firstMethod); return h; } private: static const unsigned int numOfCookies = 2; static void **buildVTArray() { int size = VTUtils::getVTSize<C>(); auto array = new void *[size + 2 + numOfCookies]{}; array += numOfCookies; array++; array[0] = const_cast<std::type_info *>(&typeid(C)); array++; return array; } VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) { } }; } #endif namespace fakeit { struct NoMoreRecordedActionException { }; template<typename R, typename ... arglist> struct MethodInvocationHandler : Destructible { virtual R handleMethodInvocation(const typename fakeit::production_arg<arglist>::type... args) = 0; }; } #include <new> namespace fakeit { namespace details { template <int instanceAreaSize, typename C, typename... BaseClasses> class FakeObjectImpl { public: void initializeDataMembersArea() { for (size_t i = 0; i < instanceAreaSize; ++i) { instanceArea[i] = (char) 0; } } protected: VirtualTable<C, BaseClasses...> vtable; char instanceArea[instanceAreaSize]; }; template <typename C, typename... BaseClasses> class FakeObjectImpl<0, C, BaseClasses...> { public: void initializeDataMembersArea() {} protected: VirtualTable<C, BaseClasses...> vtable; }; } template <typename C, typename... BaseClasses> class FakeObject : public details::FakeObjectImpl<sizeof(C) - sizeof(VirtualTable<C, BaseClasses...>), C, BaseClasses...> { FakeObject(FakeObject const&) = delete; FakeObject& operator=(FakeObject const&) = delete; public: FakeObject() { this->initializeDataMembersArea(); } ~FakeObject() { this->vtable.dispose(); } void setMethod(unsigned int index, void* method) { this->vtable.setMethod(index, method); } VirtualTable<C, BaseClasses...>& getVirtualTable() { return this->vtable; } void setVirtualTable(VirtualTable<C, BaseClasses...>& t) { this->vtable = t; } void setDtor(void* dtor) { this->vtable.setDtor(dtor); } }; } namespace fakeit { struct MethodProxy { MethodProxy(unsigned int id, unsigned int offset, void *vMethod) : _id(id), _offset(offset), _vMethod(vMethod) { } unsigned int getOffset() const { return _offset; } unsigned int getId() const { return _id; } void *getProxy() const { return union_cast<void *>(_vMethod); } private: unsigned int _id; unsigned int _offset; void *_vMethod; }; } #include <utility> namespace fakeit { struct InvocationHandlerCollection { static const unsigned int VT_COOKIE_INDEX = 0; virtual Destructible *getInvocatoinHandlerPtrById(unsigned int index) = 0; static InvocationHandlerCollection *getInvocationHandlerCollection(void *instance) { VirtualTableBase &vt = VirtualTableBase::getVTable(instance); InvocationHandlerCollection *invocationHandlerCollection = (InvocationHandlerCollection *) vt.getCookie( InvocationHandlerCollection::VT_COOKIE_INDEX); return invocationHandlerCollection; } }; template<typename R, typename ... arglist> class MethodProxyCreator { public: template<unsigned int id> MethodProxy createMethodProxy(unsigned int offset) { return MethodProxy(id, offset, union_cast<void *>(&MethodProxyCreator::methodProxyX < id > )); } protected: R methodProxy(unsigned int id, const typename fakeit::production_arg<arglist>::type... args) { InvocationHandlerCollection *invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection( this); MethodInvocationHandler<R, arglist...> *invocationHandler = (MethodInvocationHandler<R, arglist...> *) invocationHandlerCollection->getInvocatoinHandlerPtrById( id); return invocationHandler->handleMethodInvocation(std::forward<const typename fakeit::production_arg<arglist>::type>(args)...); } template<int id> R methodProxyX(arglist ... args) { return methodProxy(id, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...); } }; } namespace fakeit { class InvocationHandlers : public InvocationHandlerCollection { std::vector<std::shared_ptr<Destructible>> &_methodMocks; std::vector<unsigned int> &_offsets; unsigned int getOffset(unsigned int id) const { unsigned int offset = 0; for (; offset < _offsets.size(); offset++) { if (_offsets[offset] == id) { break; } } return offset; } public: InvocationHandlers( std::vector<std::shared_ptr<Destructible>> &methodMocks, std::vector<unsigned int> &offsets) : _methodMocks(methodMocks), _offsets(offsets) { for (std::vector<unsigned int>::iterator it = _offsets.begin(); it != _offsets.end(); ++it) { *it = std::numeric_limits<int>::max(); } } Destructible *getInvocatoinHandlerPtrById(unsigned int id) override { unsigned int offset = getOffset(id); std::shared_ptr<Destructible> ptr = _methodMocks[offset]; return ptr.get(); } }; template<typename C, typename ... baseclasses> struct DynamicProxy { static_assert(std::is_polymorphic<C>::value, "DynamicProxy requires a polymorphic type"); DynamicProxy(C &inst) : instance(inst), originalVtHandle(VirtualTable<C, baseclasses...>::getVTable(instance).createHandle()), _methodMocks(VTUtils::getVTSize<C>()), _offsets(VTUtils::getVTSize<C>()), _invocationHandlers(_methodMocks, _offsets) { _cloneVt.copyFrom(originalVtHandle.restore()); _cloneVt.setCookie(InvocationHandlerCollection::VT_COOKIE_INDEX, &_invocationHandlers); getFake().setVirtualTable(_cloneVt); } void detach() { getFake().setVirtualTable(originalVtHandle.restore()); } ~DynamicProxy() { _cloneVt.dispose(); } C &get() { return instance; } void Reset() { _methodMocks = {}; _methodMocks.resize(VTUtils::getVTSize<C>()); _members = {}; _offsets = {}; _offsets.resize(VTUtils::getVTSize<C>()); _cloneVt.copyFrom(originalVtHandle.restore()); } void Clear() { } template<int id, typename R, typename ... arglist> void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler<R, arglist...> *methodInvocationHandler) { auto offset = VTUtils::getOffset(vMethod); MethodProxyCreator<R, arglist...> creator; bind(creator.template createMethodProxy<id + 1>(offset), methodInvocationHandler); } void stubDtor(MethodInvocationHandler<void> *methodInvocationHandler) { auto offset = VTUtils::getDestructorOffset<C>(); MethodProxyCreator<void> creator; bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler); } template<typename R, typename ... arglist> bool isMethodStubbed(R(C::*vMethod)(arglist...)) { unsigned int offset = VTUtils::getOffset(vMethod); return isBinded(offset); } bool isDtorStubbed() { unsigned int offset = VTUtils::getDestructorOffset<C>(); return isBinded(offset); } template<typename R, typename ... arglist> Destructible *getMethodMock(R(C::*vMethod)(arglist...)) { auto offset = VTUtils::getOffset(vMethod); std::shared_ptr<Destructible> ptr = _methodMocks[offset]; return ptr.get(); } Destructible *getDtorMock() { auto offset = VTUtils::getDestructorOffset<C>(); std::shared_ptr<Destructible> ptr = _methodMocks[offset]; return ptr.get(); } template<typename DATA_TYPE, typename ... arglist> void stubDataMember(DATA_TYPE C::*member, const arglist &... initargs) { DATA_TYPE C::*theMember = (DATA_TYPE C::*) member; C &mock = get(); DATA_TYPE *memberPtr = &(mock.*theMember); _members.push_back( std::shared_ptr<DataMemeberWrapper < DATA_TYPE, arglist...> > {new DataMemeberWrapper < DATA_TYPE, arglist...>(memberPtr, initargs...)}); } template<typename DATA_TYPE> void getMethodMocks(std::vector<DATA_TYPE> &into) const { for (std::shared_ptr<Destructible> ptr : _methodMocks) { DATA_TYPE p = dynamic_cast<DATA_TYPE>(ptr.get()); if (p) { into.push_back(p); } } } VirtualTable<C, baseclasses...> &getOriginalVT() { VirtualTable<C, baseclasses...> &vt = originalVtHandle.restore(); return vt; } private: template<typename DATA_TYPE, typename ... arglist> class DataMemeberWrapper : public Destructible { private: DATA_TYPE *dataMember; public: DataMemeberWrapper(DATA_TYPE *dataMem, const arglist &... initargs) : dataMember(dataMem) { new(dataMember) DATA_TYPE{initargs ...}; } ~DataMemeberWrapper() override { dataMember->~DATA_TYPE(); } }; static_assert(sizeof(C) == sizeof(FakeObject<C, baseclasses...>), "This is a problem"); C &instance; typename VirtualTable<C, baseclasses...>::Handle originalVtHandle; VirtualTable<C, baseclasses...> _cloneVt; std::vector<std::shared_ptr<Destructible>> _methodMocks; std::vector<std::shared_ptr<Destructible>> _members; std::vector<unsigned int> _offsets; InvocationHandlers _invocationHandlers; FakeObject<C, baseclasses...> &getFake() { return reinterpret_cast<FakeObject<C, baseclasses...> &>(instance); } void bind(const MethodProxy &methodProxy, Destructible *invocationHandler) { getFake().setMethod(methodProxy.getOffset(), methodProxy.getProxy()); _methodMocks[methodProxy.getOffset()].reset(invocationHandler); _offsets[methodProxy.getOffset()] = methodProxy.getId(); } void bindDtor(const MethodProxy &methodProxy, Destructible *invocationHandler) { getFake().setDtor(methodProxy.getProxy()); _methodMocks[methodProxy.getOffset()].reset(invocationHandler); _offsets[methodProxy.getOffset()] = methodProxy.getId(); } template<typename DATA_TYPE> DATA_TYPE getMethodMock(unsigned int offset) { std::shared_ptr<Destructible> ptr = _methodMocks[offset]; return dynamic_cast<DATA_TYPE>(ptr.get()); } template<typename BaseClass> void checkMultipleInheritance() { C *ptr = (C *) (unsigned int) 1; BaseClass *basePtr = ptr; int delta = (unsigned long) basePtr - (unsigned long) ptr; if (delta > 0) { throw std::invalid_argument(std::string("multiple inheritance is not supported")); } } bool isBinded(unsigned int offset) { std::shared_ptr<Destructible> ptr = _methodMocks[offset]; return ptr.get() != nullptr; } }; } #include <functional> #include <type_traits> #include <memory> #include <iosfwd> #include <vector> #include <functional> #include <tuple> #include <tuple> namespace fakeit { template<int N> struct apply_func { template<typename R, typename ... ArgsF, typename ... ArgsT, typename ... Args, typename FunctionType> static R applyTuple(FunctionType&& f, std::tuple<ArgsT...> &t, Args &... args) { return apply_func<N - 1>::template applyTuple<R>(std::forward<FunctionType>(f), t, std::get<N - 1>(t), args...); } }; template<> struct apply_func < 0 > { template<typename R, typename ... ArgsF, typename ... ArgsT, typename ... Args, typename FunctionType> static R applyTuple(FunctionType&& f, std::tuple<ArgsT...> & , Args &... args) { return std::forward<FunctionType>(f)(args...); } }; struct TupleDispatcher { template<typename R, typename ... ArgsF, typename ... ArgsT, typename FunctionType> static R applyTuple(FunctionType&& f, std::tuple<ArgsT...> &t) { return apply_func<sizeof...(ArgsT)>::template applyTuple<R>(std::forward<FunctionType>(f), t); } template<typename R, typename ...arglist, typename FunctionType> static R invoke(FunctionType&& func, const std::tuple<arglist...> &arguments) { std::tuple<arglist...> &args = const_cast<std::tuple<arglist...> &>(arguments); return applyTuple<R>(std::forward<FunctionType>(func), args); } template<typename TupleType, typename FunctionType> static void for_each(TupleType &&, FunctionType &, std::integral_constant<size_t, std::tuple_size<typename std::remove_reference<TupleType>::type>::value>) { } template<std::size_t I, typename TupleType, typename FunctionType, typename = typename std::enable_if< I != std::tuple_size<typename std::remove_reference<TupleType>::type>::value>::type> static void for_each(TupleType &&t, FunctionType &f, std::integral_constant<size_t, I>) { f(I, std::get < I >(t)); for_each(std::forward < TupleType >(t), f, std::integral_constant<size_t, I + 1>()); } template<typename TupleType, typename FunctionType> static void for_each(TupleType &&t, FunctionType &f) { for_each(std::forward < TupleType >(t), f, std::integral_constant<size_t, 0>()); } template<typename TupleType1, typename TupleType2, typename FunctionType> static void for_each(TupleType1 &&, TupleType2 &&, FunctionType &, std::integral_constant<size_t, std::tuple_size<typename std::remove_reference<TupleType1>::type>::value>) { } template<std::size_t I, typename TupleType1, typename TupleType2, typename FunctionType, typename = typename std::enable_if< I != std::tuple_size<typename std::remove_reference<TupleType1>::type>::value>::type> static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f, std::integral_constant<size_t, I>) { f(I, std::get < I >(t), std::get < I >(t2)); for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant<size_t, I + 1>()); } template<typename TupleType1, typename TupleType2, typename FunctionType> static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f) { for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant<size_t, 0>()); } }; } namespace fakeit { template<typename R, typename ... arglist> struct ActualInvocationHandler : Destructible { virtual R handleMethodInvocation(ArgumentsTuple<arglist...> & args) = 0; }; } #include <functional> #include <tuple> #include <string> #include <iosfwd> #include <type_traits> #include <typeinfo> namespace fakeit { struct DefaultValueInstatiationException { virtual ~DefaultValueInstatiationException() = default; virtual std::string what() const = 0; }; template<class C> struct is_constructible_type { static const bool value = std::is_default_constructible<typename naked_type<C>::type>::value && !std::is_abstract<typename naked_type<C>::type>::value; }; template<class C, class Enable = void> struct DefaultValue; template<class C> struct DefaultValue<C, typename std::enable_if<!is_constructible_type<C>::value>::type> { static C &value() { if (std::is_reference<C>::value) { typename naked_type<C>::type *ptr = nullptr; return *ptr; } class Exception : public DefaultValueInstatiationException { virtual std::string what() const override { return (std::string("Type ") + std::string(typeid(C).name()) + std::string( " is not default constructible. Could not instantiate a default return value")).c_str(); } }; throw Exception(); } }; template<class C> struct DefaultValue<C, typename std::enable_if<is_constructible_type<C>::value>::type> { static C &value() { static typename naked_type<C>::type val{}; return val; } }; template<> struct DefaultValue<void> { static void value() { return; } }; template<> struct DefaultValue<bool> { static bool &value() { static bool value{false}; return value; } }; template<> struct DefaultValue<char> { static char &value() { static char value{0}; return value; } }; template<> struct DefaultValue<char16_t> { static char16_t &value() { static char16_t value{0}; return value; } }; template<> struct DefaultValue<char32_t> { static char32_t &value() { static char32_t value{0}; return value; } }; template<> struct DefaultValue<wchar_t> { static wchar_t &value() { static wchar_t value{0}; return value; } }; template<> struct DefaultValue<short> { static short &value() { static short value{0}; return value; } }; template<> struct DefaultValue<int> { static int &value() { static int value{0}; return value; } }; template<> struct DefaultValue<long> { static long &value() { static long value{0}; return value; } }; template<> struct DefaultValue<long long> { static long long &value() { static long long value{0}; return value; } }; template<> struct DefaultValue<std::string> { static std::string &value() { static std::string value{}; return value; } }; } #include <cstring> namespace fakeit { struct IMatcher : Destructible { ~IMatcher() = default; virtual std::string format() const = 0; }; template<typename T> struct TypedMatcher : IMatcher { virtual bool matches(const T &actual) const = 0; }; template<typename T> struct TypedMatcherCreator { virtual ~TypedMatcherCreator() = default; virtual TypedMatcher<T> *createMatcher() const = 0; }; template<typename T> struct ComparisonMatcherCreator : public TypedMatcherCreator<T> { virtual ~ComparisonMatcherCreator() = default; ComparisonMatcherCreator(const T &arg) : _expected(arg) { } struct Matcher : public TypedMatcher<T> { Matcher(const T &expected) : _expected(expected) { } const T _expected; }; const T &_expected; }; namespace internal { template<typename T> struct TypedAnyMatcher : public TypedMatcherCreator<T> { virtual ~TypedAnyMatcher() = default; TypedAnyMatcher() { } struct Matcher : public TypedMatcher<T> { virtual bool matches(const T &) const override { return true; } virtual std::string format() const override { return "Any"; } }; virtual TypedMatcher<T> *createMatcher() const override { return new Matcher(); } }; template<typename T> struct EqMatcherCreator : public ComparisonMatcherCreator<T> { virtual ~EqMatcherCreator() = default; EqMatcherCreator(const T &expected) : ComparisonMatcherCreator<T>(expected) { } struct Matcher : public ComparisonMatcherCreator<T>::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator<T>::Matcher(expected) { } virtual std::string format() const override { return TypeFormatter<T>::format(this->_expected); } virtual bool matches(const T &actual) const override { return actual == this->_expected; } }; virtual TypedMatcher<T> *createMatcher() const { return new Matcher(this->_expected); } }; template<typename T> struct GtMatcherCreator : public ComparisonMatcherCreator<T> { virtual ~GtMatcherCreator() = default; GtMatcherCreator(const T &expected) : ComparisonMatcherCreator<T>(expected) { } struct Matcher : public ComparisonMatcherCreator<T>::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator<T>::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual > this->_expected; } virtual std::string format() const override { return std::string(">") + TypeFormatter<T>::format(this->_expected); } }; virtual TypedMatcher<T> *createMatcher() const override { return new Matcher(this->_expected); } }; template<typename T> struct GeMatcherCreator : public ComparisonMatcherCreator<T> { virtual ~GeMatcherCreator() = default; GeMatcherCreator(const T &expected) : ComparisonMatcherCreator<T>(expected) { } struct Matcher : public ComparisonMatcherCreator<T>::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator<T>::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual >= this->_expected; } virtual std::string format() const override { return std::string(">=") + TypeFormatter<T>::format(this->_expected); } }; virtual TypedMatcher<T> *createMatcher() const override { return new Matcher(this->_expected); } }; template<typename T> struct LtMatcherCreator : public ComparisonMatcherCreator<T> { virtual ~LtMatcherCreator() = default; LtMatcherCreator(const T &expected) : ComparisonMatcherCreator<T>(expected) { } struct Matcher : public ComparisonMatcherCreator<T>::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator<T>::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual < this->_expected; } virtual std::string format() const override { return std::string("<") + TypeFormatter<T>::format(this->_expected); } }; virtual TypedMatcher<T> *createMatcher() const override { return new Matcher(this->_expected); } }; template<typename T> struct LeMatcherCreator : public ComparisonMatcherCreator<T> { virtual ~LeMatcherCreator() = default; LeMatcherCreator(const T &expected) : ComparisonMatcherCreator<T>(expected) { } struct Matcher : public ComparisonMatcherCreator<T>::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator<T>::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual <= this->_expected; } virtual std::string format() const override { return std::string("<=") + TypeFormatter<T>::format(this->_expected); } }; virtual TypedMatcher<T> *createMatcher() const override { return new Matcher(this->_expected); } }; template<typename T> struct NeMatcherCreator : public ComparisonMatcherCreator<T> { virtual ~NeMatcherCreator() = default; NeMatcherCreator(const T &expected) : ComparisonMatcherCreator<T>(expected) { } struct Matcher : public ComparisonMatcherCreator<T>::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator<T>::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual != this->_expected; } virtual std::string format() const override { return std::string("!=") + TypeFormatter<T>::format(this->_expected); } }; virtual TypedMatcher<T> *createMatcher() const override { return new Matcher(this->_expected); } }; struct StrEqMatcherCreator : public ComparisonMatcherCreator<const char*> { virtual ~StrEqMatcherCreator() = default; StrEqMatcherCreator(const char* const &expected) : ComparisonMatcherCreator<const char*>(expected) { } struct Matcher : public ComparisonMatcherCreator<const char*>::Matcher { Matcher(const char* const &expected) : ComparisonMatcherCreator<const char*>::Matcher(expected) { } virtual std::string format() const override { return TypeFormatter<const char*>::format(this->_expected); } virtual bool matches(const char* const &actual) const override { return std::strcmp(actual, this->_expected) == 0; } }; virtual TypedMatcher<const char*> *createMatcher() const { return new Matcher(this->_expected); } }; struct StrGtMatcherCreator : public ComparisonMatcherCreator<const char*> { virtual ~StrGtMatcherCreator() = default; StrGtMatcherCreator(const char* const &expected) : ComparisonMatcherCreator<const char*>(expected) { } struct Matcher : public ComparisonMatcherCreator<const char*>::Matcher { Matcher(const char* const &expected) : ComparisonMatcherCreator<const char*>::Matcher(expected) { } virtual std::string format() const override { return std::string(">") + TypeFormatter<const char*>::format(this->_expected); } virtual bool matches(const char* const &actual) const override { return std::strcmp(actual, this->_expected) > 0; } }; virtual TypedMatcher<const char*> *createMatcher() const { return new Matcher(this->_expected); } }; struct StrGeMatcherCreator : public ComparisonMatcherCreator<const char*> { virtual ~StrGeMatcherCreator() = default; StrGeMatcherCreator(const char* const &expected) : ComparisonMatcherCreator<const char*>(expected) { } struct Matcher : public ComparisonMatcherCreator<const char*>::Matcher { Matcher(const char* const &expected) : ComparisonMatcherCreator<const char*>::Matcher(expected) { } virtual std::string format() const override { return std::string(">=") + TypeFormatter<const char*>::format(this->_expected); } virtual bool matches(const char* const &actual) const override { return std::strcmp(actual, this->_expected) >= 0; } }; virtual TypedMatcher<const char*> *createMatcher() const { return new Matcher(this->_expected); } }; struct StrLtMatcherCreator : public ComparisonMatcherCreator<const char*> { virtual ~StrLtMatcherCreator() = default; StrLtMatcherCreator(const char* const &expected) : ComparisonMatcherCreator<const char*>(expected) { } struct Matcher : public ComparisonMatcherCreator<const char*>::Matcher { Matcher(const char* const &expected) : ComparisonMatcherCreator<const char*>::Matcher(expected) { } virtual std::string format() const override { return std::string("<") + TypeFormatter<const char*>::format(this->_expected); } virtual bool matches(const char* const &actual) const override { return std::strcmp(actual, this->_expected) < 0; } }; virtual TypedMatcher<const char*> *createMatcher() const { return new Matcher(this->_expected); } }; struct StrLeMatcherCreator : public ComparisonMatcherCreator<const char*> { virtual ~StrLeMatcherCreator() = default; StrLeMatcherCreator(const char* const &expected) : ComparisonMatcherCreator<const char*>(expected) { } struct Matcher : public ComparisonMatcherCreator<const char*>::Matcher { Matcher(const char* const &expected) : ComparisonMatcherCreator<const char*>::Matcher(expected) { } virtual std::string format() const override { return std::string("<=") + TypeFormatter<const char*>::format(this->_expected); } virtual bool matches(const char* const &actual) const override { return std::strcmp(actual, this->_expected) <= 0; } }; virtual TypedMatcher<const char*> *createMatcher() const { return new Matcher(this->_expected); } }; struct StrNeMatcherCreator : public ComparisonMatcherCreator<const char*> { virtual ~StrNeMatcherCreator() = default; StrNeMatcherCreator(const char* const &expected) : ComparisonMatcherCreator<const char*>(expected) { } struct Matcher : public ComparisonMatcherCreator<const char*>::Matcher { Matcher(const char* const &expected) : ComparisonMatcherCreator<const char*>::Matcher(expected) { } virtual std::string format() const override { return std::string("!=") + TypeFormatter<const char*>::format(this->_expected); } virtual bool matches(const char* const &actual) const override { return std::strcmp(actual, this->_expected) != 0; } }; virtual TypedMatcher<const char*> *createMatcher() const { return new Matcher(this->_expected); } }; } struct AnyMatcher { } static _; template<typename T> internal::TypedAnyMatcher<T> Any() { internal::TypedAnyMatcher<T> rv; return rv; } template<typename T> internal::EqMatcherCreator<T> Eq(const T &arg) { internal::EqMatcherCreator<T> rv(arg); return rv; } template<typename T> internal::GtMatcherCreator<T> Gt(const T &arg) { internal::GtMatcherCreator<T> rv(arg); return rv; } template<typename T> internal::GeMatcherCreator<T> Ge(const T &arg) { internal::GeMatcherCreator<T> rv(arg); return rv; } template<typename T> internal::LtMatcherCreator<T> Lt(const T &arg) { internal::LtMatcherCreator<T> rv(arg); return rv; } template<typename T> internal::LeMatcherCreator<T> Le(const T &arg) { internal::LeMatcherCreator<T> rv(arg); return rv; } template<typename T> internal::NeMatcherCreator<T> Ne(const T &arg) { internal::NeMatcherCreator<T> rv(arg); return rv; } inline internal::StrEqMatcherCreator StrEq(const char* const &arg) { internal::StrEqMatcherCreator rv(arg); return rv; } inline internal::StrGtMatcherCreator StrGt(const char* const &arg) { internal::StrGtMatcherCreator rv(arg); return rv; } inline internal::StrGeMatcherCreator StrGe(const char* const &arg) { internal::StrGeMatcherCreator rv(arg); return rv; } inline internal::StrLtMatcherCreator StrLt(const char* const &arg) { internal::StrLtMatcherCreator rv(arg); return rv; } inline internal::StrLeMatcherCreator StrLe(const char* const &arg) { internal::StrLeMatcherCreator rv(arg); return rv; } inline internal::StrNeMatcherCreator StrNe(const char* const &arg) { internal::StrNeMatcherCreator rv(arg); return rv; } } namespace fakeit { template<typename ... arglist> struct ArgumentsMatcherInvocationMatcher : public ActualInvocation<arglist...>::Matcher { virtual ~ArgumentsMatcherInvocationMatcher() { for (unsigned int i = 0; i < _matchers.size(); i++) delete _matchers[i]; } ArgumentsMatcherInvocationMatcher(const std::vector<Destructible *> &args) : _matchers(args) { } virtual bool matches(ActualInvocation<arglist...> &invocation) override { if (invocation.getActualMatcher() == this) return true; return matches(invocation.getActualArguments()); } virtual std::string format() const override { std::ostringstream out; out << "("; for (unsigned int i = 0; i < _matchers.size(); i++) { if (i > 0) out << ", "; IMatcher *m = dynamic_cast<IMatcher *>(_matchers[i]); out << m->format(); } out << ")"; return out.str(); } private: struct MatchingLambda { MatchingLambda(const std::vector<Destructible *> &matchers) : _matchers(matchers) { } template<typename A> void operator()(int index, A &actualArg) { TypedMatcher<typename naked_type<A>::type> *matcher = dynamic_cast<TypedMatcher<typename naked_type<A>::type> *>(_matchers[index]); if (_matching) _matching = matcher->matches(actualArg); } bool isMatching() { return _matching; } private: bool _matching = true; const std::vector<Destructible *> &_matchers; }; virtual bool matches(ArgumentsTuple<arglist...>& actualArguments) { MatchingLambda l(_matchers); fakeit::TupleDispatcher::for_each(actualArguments, l); return l.isMatching(); } const std::vector<Destructible *> _matchers; }; template<typename ... arglist> struct UserDefinedInvocationMatcher : ActualInvocation<arglist...>::Matcher { virtual ~UserDefinedInvocationMatcher() = default; UserDefinedInvocationMatcher(std::function<bool(arglist &...)> match) : matcher{match} { } virtual bool matches(ActualInvocation<arglist...> &invocation) override { if (invocation.getActualMatcher() == this) return true; return matches(invocation.getActualArguments()); } virtual std::string format() const override { return {"( user defined matcher )"}; } private: virtual bool matches(ArgumentsTuple<arglist...>& actualArguments) { return TupleDispatcher::invoke<bool, typename tuple_arg<arglist>::type...>(matcher, actualArguments); } const std::function<bool(arglist &...)> matcher; }; template<typename ... arglist> struct DefaultInvocationMatcher : public ActualInvocation<arglist...>::Matcher { virtual ~DefaultInvocationMatcher() = default; DefaultInvocationMatcher() { } virtual bool matches(ActualInvocation<arglist...> &invocation) override { return matches(invocation.getActualArguments()); } virtual std::string format() const override { return {"( Any arguments )"}; } private: virtual bool matches(const ArgumentsTuple<arglist...>&) { return true; } }; } namespace fakeit { template<typename R, typename ... arglist> class RecordedMethodBody : public MethodInvocationHandler<R, arglist...>, public ActualInvocationsSource, public ActualInvocationsContainer { struct MatchedInvocationHandler : ActualInvocationHandler<R, arglist...> { virtual ~MatchedInvocationHandler() = default; MatchedInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher, ActualInvocationHandler<R, arglist...> *invocationHandler) : _matcher{matcher}, _invocationHandler{invocationHandler} { } virtual R handleMethodInvocation(ArgumentsTuple<arglist...> & args) override { Destructible &destructable = *_invocationHandler; ActualInvocationHandler<R, arglist...> &invocationHandler = dynamic_cast<ActualInvocationHandler<R, arglist...> &>(destructable); return invocationHandler.handleMethodInvocation(args); } typename ActualInvocation<arglist...>::Matcher &getMatcher() const { Destructible &destructable = *_matcher; typename ActualInvocation<arglist...>::Matcher &matcher = dynamic_cast<typename ActualInvocation<arglist...>::Matcher &>(destructable); return matcher; } private: std::shared_ptr<Destructible> _matcher; std::shared_ptr<Destructible> _invocationHandler; }; FakeitContext &_fakeit; MethodInfo _method; std::vector<std::shared_ptr<Destructible>> _invocationHandlers; std::vector<std::shared_ptr<Destructible>> _actualInvocations; MatchedInvocationHandler *buildMatchedInvocationHandler( typename ActualInvocation<arglist...>::Matcher *invocationMatcher, ActualInvocationHandler<R, arglist...> *invocationHandler) { return new MatchedInvocationHandler(invocationMatcher, invocationHandler); } MatchedInvocationHandler *getInvocationHandlerForActualArgs(ActualInvocation<arglist...> &invocation) { for (auto i = _invocationHandlers.rbegin(); i != _invocationHandlers.rend(); ++i) { std::shared_ptr<Destructible> curr = *i; Destructible &destructable = *curr; MatchedInvocationHandler &im = asMatchedInvocationHandler(destructable); if (im.getMatcher().matches(invocation)) { return &im; } } return nullptr; } MatchedInvocationHandler &asMatchedInvocationHandler(Destructible &destructable) { MatchedInvocationHandler &im = dynamic_cast<MatchedInvocationHandler &>(destructable); return im; } ActualInvocation<arglist...> &asActualInvocation(Destructible &destructable) const { ActualInvocation<arglist...> &invocation = dynamic_cast<ActualInvocation<arglist...> &>(destructable); return invocation; } public: RecordedMethodBody(FakeitContext &fakeit, std::string name) : _fakeit(fakeit), _method{MethodInfo::nextMethodOrdinal(), name} { } virtual ~RecordedMethodBody() NO_THROWS { } MethodInfo &getMethod() { return _method; } bool isOfMethod(MethodInfo &method) { return method.id() == _method.id(); } void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher, ActualInvocationHandler<R, arglist...> *invocationHandler) { ActualInvocationHandler<R, arglist...> *mock = buildMatchedInvocationHandler(matcher, invocationHandler); std::shared_ptr<Destructible> destructable{mock}; _invocationHandlers.push_back(destructable); } void reset() { _invocationHandlers.clear(); _actualInvocations.clear(); } void clear() override { _actualInvocations.clear(); } R handleMethodInvocation(const typename fakeit::production_arg<arglist>::type... args) override { unsigned int ordinal = Invocation::nextInvocationOrdinal(); MethodInfo &method = this->getMethod(); auto actualInvocation = new ActualInvocation<arglist...>(ordinal, method, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...); std::shared_ptr<Destructible> actualInvocationDtor{actualInvocation}; auto invocationHandler = getInvocationHandlerForActualArgs(*actualInvocation); if (invocationHandler) { auto &matcher = invocationHandler->getMatcher(); actualInvocation->setActualMatcher(&matcher); _actualInvocations.push_back(actualInvocationDtor); try { return invocationHandler->handleMethodInvocation(actualInvocation->getActualArguments()); } catch (NoMoreRecordedActionException &) { } } UnexpectedMethodCallEvent event(UnexpectedType::Unmatched, *actualInvocation); _fakeit.handle(event); std::string format{_fakeit.format(event)}; UnexpectedMethodCallException e(format); throw e; } void scanActualInvocations(const std::function<void(ActualInvocation<arglist...> &)> &scanner) { for (auto destructablePtr : _actualInvocations) { ActualInvocation<arglist...> &invocation = asActualInvocation(*destructablePtr); scanner(invocation); } } void getActualInvocations(std::unordered_set<Invocation *> &into) const override { for (auto destructablePtr : _actualInvocations) { Invocation &invocation = asActualInvocation(*destructablePtr); into.insert(&invocation); } } void setMethodDetails(const std::string &mockName, const std::string &methodName) { const std::string fullName{mockName + "." + methodName}; _method.setName(fullName); } }; } #include <functional> #include <type_traits> #include <stdexcept> #include <utility> #include <functional> #include <type_traits> namespace fakeit { struct Quantity { Quantity(const int q) : quantity(q) { } const int quantity; } static Once(1); template<typename R> struct Quantifier : public Quantity { Quantifier(const int q, const R &val) : Quantity(q), value(val) { } const R &value; }; template<> struct Quantifier<void> : public Quantity { explicit Quantifier(const int q) : Quantity(q) { } }; struct QuantifierFunctor : public Quantifier<void> { QuantifierFunctor(const int q) : Quantifier<void>(q) { } template<typename R> Quantifier<R> operator()(const R &value) { return Quantifier<R>(quantity, value); } }; template<int q> struct Times : public Quantity { Times() : Quantity(q) { } template<typename R> static Quantifier<R> of(const R &value) { return Quantifier<R>(q, value); } static Quantifier<void> Void() { return Quantifier<void>(q); } }; #if defined (__GNUG__) || (_MSC_VER >= 1900) inline QuantifierFunctor operator "" _Times(unsigned long long n) { return QuantifierFunctor((int) n); } inline QuantifierFunctor operator "" _Time(unsigned long long n) { if (n != 1) throw std::invalid_argument("Only 1_Time is supported. Use X_Times (with s) if X is bigger than 1"); return QuantifierFunctor((int) n); } #endif } #include <functional> #include <atomic> #include <tuple> #include <type_traits> namespace fakeit { template<typename R, typename ... arglist> struct Action : Destructible { virtual R invoke(const ArgumentsTuple<arglist...> &) = 0; virtual bool isDone() = 0; }; template<typename R, typename ... arglist> struct Repeat : Action<R, arglist...> { virtual ~Repeat() = default; Repeat(std::function<R(typename fakeit::test_arg<arglist>::type...)> func) : f(func), times(1) { } Repeat(std::function<R(typename fakeit::test_arg<arglist>::type...)> func, long t) : f(func), times(t) { } virtual R invoke(const ArgumentsTuple<arglist...> & args) override { times--; return TupleDispatcher::invoke<R, arglist...>(f, args); } virtual bool isDone() override { return times == 0; } private: std::function<R(typename fakeit::test_arg<arglist>::type...)> f; long times; }; template<typename R, typename ... arglist> struct RepeatForever : public Action<R, arglist...> { virtual ~RepeatForever() = default; RepeatForever(std::function<R(typename fakeit::test_arg<arglist>::type...)> func) : f(func) { } virtual R invoke(const ArgumentsTuple<arglist...> & args) override { return TupleDispatcher::invoke<R, arglist...>(f, args); } virtual bool isDone() override { return false; } private: std::function<R(typename fakeit::test_arg<arglist>::type...)> f; }; template<typename R, typename ... arglist> struct ReturnDefaultValue : public Action<R, arglist...> { virtual ~ReturnDefaultValue() = default; virtual R invoke(const ArgumentsTuple<arglist...> &) override { return DefaultValue<R>::value(); } virtual bool isDone() override { return false; } }; template<typename R, typename ... arglist> struct ReturnDelegateValue : public Action<R, arglist...> { ReturnDelegateValue(std::function<R(const typename fakeit::test_arg<arglist>::type...)> delegate) : _delegate(delegate) { } virtual ~ReturnDelegateValue() = default; virtual R invoke(const ArgumentsTuple<arglist...> & args) override { return TupleDispatcher::invoke<R, arglist...>(_delegate, args); } virtual bool isDone() override { return false; } private: std::function<R(const typename fakeit::test_arg<arglist>::type...)> _delegate; }; } namespace fakeit { namespace helper { template <typename T, int N> struct ArgValue; template <int max_index, int tuple_index> struct ArgValidator; template<int arg_index, typename current_arg, typename ...T, int ...N, typename ... arglist> static void Assign(std::tuple<ArgValue<T, N>...> arg_vals, current_arg &&p, arglist &&... args); template<int N> struct ParamWalker; } template<typename R, typename ... arglist> struct MethodStubbingProgress { virtual ~MethodStubbingProgress() THROWS { } template<typename U = R> typename std::enable_if<!std::is_reference<U>::value, MethodStubbingProgress<R, arglist...> &>::type Return(const R &r) { return Do([r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; }); } template<typename U = R> typename std::enable_if<std::is_reference<U>::value, MethodStubbingProgress<R, arglist...> &>::type Return(const R &r) { return Do([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; }); } MethodStubbingProgress<R, arglist...> & Return(const Quantifier<R> &q) { const R &value = q.value; auto method = [value](const arglist &...) -> R { return value; }; return DoImpl(new Repeat<R, arglist...>(method, q.quantity)); } template<typename first, typename second, typename ... tail> MethodStubbingProgress<R, arglist...> & Return(const first &f, const second &s, const tail &... t) { Return(f); return Return(s, t...); } template<typename U = R> typename std::enable_if<!std::is_reference<U>::value, void>::type AlwaysReturn(const R &r) { return AlwaysDo([r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; }); } template<typename U = R> typename std::enable_if<std::is_reference<U>::value, void>::type AlwaysReturn(const R &r) { return AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; }); } MethodStubbingProgress<R, arglist...> & Return() { return Do([](const typename fakeit::test_arg<arglist>::type...) -> R { return DefaultValue<R>::value(); }); } void AlwaysReturn() { return AlwaysDo([](const typename fakeit::test_arg<arglist>::type...) -> R { return DefaultValue<R>::value(); }); } template<typename E> MethodStubbingProgress<R, arglist...> &Throw(const E &e) { return Do([e](const typename fakeit::test_arg<arglist>::type...) -> R { throw e; }); } template<typename E> MethodStubbingProgress<R, arglist...> & Throw(const Quantifier<E> &q) { const E &value = q.value; auto method = [value](const arglist &...) -> R { throw value; }; return DoImpl(new Repeat<R, arglist...>(method, q.quantity)); } template<typename first, typename second, typename ... tail> MethodStubbingProgress<R, arglist...> & Throw(const first &f, const second &s, const tail &... t) { Throw(f); return Throw(s, t...); } template<typename E> void AlwaysThrow(const E &e) { return AlwaysDo([e](const typename fakeit::test_arg<arglist>::type...) -> R { throw e; }); } template<typename ... valuelist> MethodStubbingProgress<R, arglist...> & ReturnAndSet(R &&r, valuelist &&... arg_vals) { return Do(GetAssigner(std::forward<R>(r), std::forward<valuelist>(arg_vals)...)); } template<typename ... valuelist> void AlwaysReturnAndSet(R &&r, valuelist &&... arg_vals) { AlwaysDo(GetAssigner(std::forward<R>(r), std::forward<valuelist>(arg_vals)...)); } virtual MethodStubbingProgress<R, arglist...> & Do(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) { return DoImpl(new Repeat<R, arglist...>(method)); } template<typename F> MethodStubbingProgress<R, arglist...> & Do(const Quantifier<F> &q) { return DoImpl(new Repeat<R, arglist...>(q.value, q.quantity)); } template<typename first, typename second, typename ... tail> MethodStubbingProgress<R, arglist...> & Do(const first &f, const second &s, const tail &... t) { Do(f); return Do(s, t...); } virtual void AlwaysDo(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) { DoImpl(new RepeatForever<R, arglist...>(method)); } protected: virtual MethodStubbingProgress<R, arglist...> &DoImpl(Action<R, arglist...> *action) = 0; private: MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; template<typename ... valuelist> #if __cplusplus >= 201402L auto #else std::function<R (typename fakeit::test_arg<arglist>::type...)> #endif GetAssigner(R &&r, valuelist &&... arg_vals) { class Lambda { public: Lambda(R &&r, valuelist &&... arg_vals) : vals_tuple{std::forward<R>(r), std::forward<valuelist>(arg_vals)...} {} R operator()(typename fakeit::test_arg<arglist>::type... args) { helper::ParamWalker<sizeof...(valuelist)>::Assign(vals_tuple, std::forward<arglist>(args)...); return std::get<0>(vals_tuple); } private: ArgumentsTuple<R, valuelist...> vals_tuple; }; return Lambda(std::forward<R>(r), std::forward<valuelist>(arg_vals)...); } template<typename ...T, int ...N> #if __cplusplus >= 201402L auto #else std::function<R (typename fakeit::test_arg<arglist>::type...)> #endif GetAssigner(R &&r, helper::ArgValue<T, N>... arg_vals) { class Lambda { public: Lambda(R &&r, helper::ArgValue<T, N>... arg_vals) : ret{std::forward<R>(r)} , vals_tuple{std::forward<helper::ArgValue<T, N>>(arg_vals)...} {} R operator()(typename fakeit::test_arg<arglist>::type... args) { helper::ArgValidator<sizeof...(arglist), sizeof...(T) - 1>::CheckPositions(vals_tuple); helper::Assign<1>(vals_tuple, std::forward<arglist>(args)...); return std::get<0>(ret); } private: std::tuple<R> ret; ArgumentsTuple<helper::ArgValue<T, N>...> vals_tuple; }; return Lambda(std::forward<R>(r), std::forward<helper::ArgValue<T, N>>(arg_vals)...); } }; template<typename ... arglist> struct MethodStubbingProgress<void, arglist...> { virtual ~MethodStubbingProgress() THROWS { } MethodStubbingProgress<void, arglist...> &Return() { auto lambda = [](const typename fakeit::test_arg<arglist>::type...) -> void { return DefaultValue<void>::value(); }; return Do(lambda); } virtual MethodStubbingProgress<void, arglist...> &Do( std::function<void(const typename fakeit::test_arg<arglist>::type...)> method) { return DoImpl(new Repeat<void, arglist...>(method)); } void AlwaysReturn() { return AlwaysDo([](const typename fakeit::test_arg<arglist>::type...) -> void { return DefaultValue<void>::value(); }); } MethodStubbingProgress<void, arglist...> & Return(const Quantifier<void> &q) { auto method = [](const arglist &...) -> void { return DefaultValue<void>::value(); }; return DoImpl(new Repeat<void, arglist...>(method, q.quantity)); } template<typename E> MethodStubbingProgress<void, arglist...> &Throw(const E &e) { return Do([e](const typename fakeit::test_arg<arglist>::type...) -> void { throw e; }); } template<typename E> MethodStubbingProgress<void, arglist...> & Throw(const Quantifier<E> &q) { const E &value = q.value; auto method = [value](const typename fakeit::test_arg<arglist>::type...) -> void { throw value; }; return DoImpl(new Repeat<void, arglist...>(method, q.quantity)); } template<typename first, typename second, typename ... tail> MethodStubbingProgress<void, arglist...> & Throw(const first &f, const second &s, const tail &... t) { Throw(f); return Throw(s, t...); } template<typename E> void AlwaysThrow(const E e) { return AlwaysDo([e](const typename fakeit::test_arg<arglist>::type...) -> void { throw e; }); } template<typename ... valuelist> MethodStubbingProgress<void, arglist...> & ReturnAndSet(valuelist &&... arg_vals) { return Do(GetAssigner(std::forward<valuelist>(arg_vals)...)); } template<typename ... valuelist> void AlwaysReturnAndSet(valuelist &&... arg_vals) { AlwaysDo(GetAssigner(std::forward<valuelist>(arg_vals)...)); } template<typename F> MethodStubbingProgress<void, arglist...> & Do(const Quantifier<F> &q) { return DoImpl(new Repeat<void, arglist...>(q.value, q.quantity)); } template<typename first, typename second, typename ... tail> MethodStubbingProgress<void, arglist...> & Do(const first &f, const second &s, const tail &... t) { Do(f); return Do(s, t...); } virtual void AlwaysDo(std::function<void(const typename fakeit::test_arg<arglist>::type...)> method) { DoImpl(new RepeatForever<void, arglist...>(method)); } protected: virtual MethodStubbingProgress<void, arglist...> &DoImpl(Action<void, arglist...> *action) = 0; private: MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; template<typename ... valuelist> #if __cplusplus >= 201402L auto #else std::function<void (typename fakeit::test_arg<arglist>::type...)> #endif GetAssigner(valuelist &&... arg_vals) { class Lambda { public: Lambda(valuelist &&... arg_vals) : vals_tuple{std::forward<valuelist>(arg_vals)...} {} void operator()(typename fakeit::test_arg<arglist>::type... args) { helper::ParamWalker<sizeof...(valuelist)>::Assign(vals_tuple, std::forward<arglist>(args)...); } private: ArgumentsTuple<valuelist...> vals_tuple; }; return Lambda(std::forward<valuelist>(arg_vals)...); } template<typename ...T, int ...N> #if __cplusplus >= 201402L auto #else std::function<void (typename fakeit::test_arg<arglist>::type...)> #endif GetAssigner(helper::ArgValue<T, N>... arg_vals) { class Lambda { public: Lambda(helper::ArgValue<T, N>... arg_vals) : vals_tuple{std::forward<helper::ArgValue<T, N>>(arg_vals)...} {} void operator()(typename fakeit::test_arg<arglist>::type... args) { helper::ArgValidator<sizeof...(arglist), sizeof...(T) - 1>::CheckPositions(vals_tuple); helper::Assign<1>(vals_tuple, std::forward<arglist>(args)...); } private: ArgumentsTuple<helper::ArgValue<T, N>...> vals_tuple; }; return Lambda(std::forward<helper::ArgValue<T, N>>(arg_vals)...); } }; namespace helper { template <typename T, int N> struct ArgValue { ArgValue(T &&v): value { std::forward<T>(v) } {} constexpr static int pos = N; T value; }; template <int max_index, int tuple_index> struct ArgValidator { template <typename ...T, int ...N> static void CheckPositions(const std::tuple<ArgValue<T, N>...> arg_vals) { #if __cplusplus >= 201402L static_assert(std::get<tuple_index>(arg_vals).pos <= max_index, "Argument index out of range"); ArgValidator<max_index, tuple_index - 1>::CheckPositions(arg_vals); #else (void)arg_vals; #endif } }; template <int max_index> struct ArgValidator<max_index, -1> { template <typename T> static void CheckPositions(T) {} }; template <typename current_arg> typename std::enable_if<std::is_pointer<current_arg>::value, typename std::remove_pointer<current_arg>::type &>::type GetArg(current_arg &&t) { return *t; } template <typename current_arg> typename std::enable_if<!std::is_pointer<current_arg>::value, current_arg>::type GetArg(current_arg &&t) { return std::forward<current_arg>(t); } template<int N> struct ParamWalker { template<typename current_arg, typename ... valuelist, typename ... arglist> static void Assign(ArgumentsTuple<valuelist...> arg_vals, current_arg &&p, arglist&&... args) { ParamWalker<N - 1>::template Assign(arg_vals, std::forward<arglist>(args)...); GetArg(std::forward<current_arg>(p)) = std::get<sizeof...(valuelist) - N>(arg_vals); } }; template<> struct ParamWalker<0> { template<typename ... valuelist, typename ... arglist> static void Assign(ArgumentsTuple<valuelist...>, arglist... ) {} }; template<int arg_index, int check_index> struct ArgLocator { template<typename current_arg, typename ...T, int ...N> static void AssignArg(current_arg &&p, std::tuple<ArgValue<T, N>...> arg_vals) { #if __cplusplus >= 201703L if constexpr (std::get<check_index>(arg_vals).pos == arg_index) GetArg(std::forward<current_arg>(p)) = std::get<check_index>(arg_vals).value; #else if (std::get<check_index>(arg_vals).pos == arg_index) Set(std::forward<current_arg>(p), std::get<check_index>(arg_vals).value); #endif else if (check_index > 0) ArgLocator<arg_index, check_index - 1>::AssignArg(std::forward<current_arg>(p), arg_vals); } #if __cplusplus < 201703L private: template<typename T, typename U> static typename std::enable_if<std::is_convertible<U, decltype(GetArg(std::declval<T>()))>::value, void>::type Set(T &&p, U &&v) { GetArg(std::forward<T>(p)) = v; } template<typename T, typename U> static typename std::enable_if<!std::is_convertible<U, decltype(GetArg(std::declval<T>()))>::value, void>::type Set(T &&, U &&) { throw std::logic_error("ReturnAndSet(): Invalid value type"); } #endif }; template<int arg_index> struct ArgLocator<arg_index, -1> { template<typename current_arg, typename T> static void AssignArg(current_arg, T) { } }; template<int arg_index, typename current_arg, typename ...T, int ...N, typename ... arglist> static void Assign(std::tuple<ArgValue<T, N>...> arg_vals, current_arg &&p, arglist &&... args) { ArgLocator<arg_index, sizeof...(N) - 1>::AssignArg(std::forward<current_arg>(p), arg_vals); Assign<arg_index + 1>(arg_vals, std::forward<arglist>(args)...); } template<int arg_index, typename ... valuelist> static void Assign(std::tuple<valuelist...>) {} } namespace placeholders { using namespace std::placeholders; template <typename PlaceHolder, typename ArgType, typename std::enable_if<static_cast<bool>(std::is_placeholder<PlaceHolder>::value), bool>::type = true> helper::ArgValue<ArgType, std::is_placeholder<PlaceHolder>::value> operator<=(PlaceHolder, ArgType &&arg) { return { std::forward<ArgType>(arg) }; } } using placeholders::operator <=; } #include <vector> #include <functional> namespace fakeit { class Finally { private: std::function<void()> _finallyClause; Finally(const Finally &); Finally &operator=(const Finally &); public: explicit Finally(std::function<void()> f) : _finallyClause(f) { } ~Finally() { _finallyClause(); } }; } namespace fakeit { template<typename R, typename ... arglist> struct ActionSequence : ActualInvocationHandler<R,arglist...> { ActionSequence() { clear(); } void AppendDo(Action<R, arglist...> *action) { append(action); } virtual R handleMethodInvocation(ArgumentsTuple<arglist...> & args) override { std::shared_ptr<Destructible> destructablePtr = _recordedActions.front(); Destructible &destructable = *destructablePtr; Action<R, arglist...> &action = dynamic_cast<Action<R, arglist...> &>(destructable); std::function<void()> finallyClause = [&]() -> void { if (action.isDone()) _recordedActions.erase(_recordedActions.begin()); }; Finally onExit(finallyClause); return action.invoke(args); } private: struct NoMoreRecordedAction : Action<R, arglist...> { virtual R invoke(const ArgumentsTuple<arglist...> &) override { throw NoMoreRecordedActionException(); } virtual bool isDone() override { return false; } }; void append(Action<R, arglist...> *action) { std::shared_ptr<Destructible> destructable{action}; _recordedActions.insert(_recordedActions.end() - 1, destructable); } void clear() { _recordedActions.clear(); auto actionPtr = std::shared_ptr<Destructible> {new NoMoreRecordedAction()}; _recordedActions.push_back(actionPtr); } std::vector<std::shared_ptr<Destructible>> _recordedActions; }; } namespace fakeit { template<typename C, typename DATA_TYPE> class DataMemberStubbingRoot { private: public: DataMemberStubbingRoot(const DataMemberStubbingRoot &) = default; DataMemberStubbingRoot() = default; void operator=(const DATA_TYPE&) { } }; } #include <functional> #include <utility> #include <type_traits> #include <tuple> #include <memory> #include <vector> #include <unordered_set> #include <set> #include <iosfwd> namespace fakeit { struct Xaction { virtual void commit() = 0; }; } namespace fakeit { template<typename R, typename ... arglist> struct SpyingContext : Xaction { virtual void appendAction(Action<R, arglist...> *action) = 0; virtual std::function<R(arglist&...)> getOriginalMethod() = 0; }; } namespace fakeit { template<typename R, typename ... arglist> struct StubbingContext : public Xaction { virtual void appendAction(Action<R, arglist...> *action) = 0; }; } #include <functional> #include <type_traits> #include <tuple> #include <memory> #include <vector> #include <unordered_set> namespace fakeit { template<unsigned int index, typename ... arglist> class MatchersCollector { std::vector<Destructible *> &_matchers; public: template<std::size_t N> using ArgType = typename std::tuple_element<N, std::tuple<arglist...>>::type; template<std::size_t N> using NakedArgType = typename naked_type<ArgType<index>>::type; template<std::size_t N> using ArgMatcherCreatorType = decltype(std::declval<TypedMatcherCreator<NakedArgType<N>>>()); MatchersCollector(std::vector<Destructible *> &matchers) : _matchers(matchers) { } void CollectMatchers() { } template<typename Head> typename std::enable_if< std::is_constructible<NakedArgType<index>, Head>::value, void> ::type CollectMatchers(const Head &value) { TypedMatcher<NakedArgType<index>> *d = Eq<NakedArgType<index>>(value).createMatcher(); _matchers.push_back(d); } template<typename Head, typename ...Tail> typename std::enable_if< std::is_constructible<NakedArgType<index>, Head>::value , void> ::type CollectMatchers(const Head &head, const Tail &... tail) { CollectMatchers(head); MatchersCollector<index + 1, arglist...> c(_matchers); c.CollectMatchers(tail...); } template<typename Head> typename std::enable_if< std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void> ::type CollectMatchers(const Head &creator) { TypedMatcher<NakedArgType<index>> *d = creator.createMatcher(); _matchers.push_back(d); } template<typename Head, typename ...Tail> typename std::enable_if< std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void> ::type CollectMatchers(const Head &head, const Tail &... tail) { CollectMatchers(head); MatchersCollector<index + 1, arglist...> c(_matchers); c.CollectMatchers(tail...); } template<typename Head> typename std::enable_if< std::is_same<AnyMatcher, Head>::value, void> ::type CollectMatchers(const Head &) { TypedMatcher<NakedArgType<index>> *d = Any<NakedArgType<index>>().createMatcher(); _matchers.push_back(d); } template<typename Head, typename ...Tail> typename std::enable_if< std::is_same<AnyMatcher, Head>::value, void> ::type CollectMatchers(const Head &head, const Tail &... tail) { CollectMatchers(head); MatchersCollector<index + 1, arglist...> c(_matchers); c.CollectMatchers(tail...); } }; } namespace fakeit { template<typename R, typename ... arglist> class MethodMockingContext : public Sequence, public ActualInvocationsSource, public virtual StubbingContext<R, arglist...>, public virtual SpyingContext<R, arglist...>, private Invocation::Matcher { public: struct Context : Destructible { virtual typename std::function<R(arglist&...)> getOriginalMethod() = 0; virtual std::string getMethodName() = 0; virtual void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher, ActualInvocationHandler<R, arglist...> *invocationHandler) = 0; virtual void scanActualInvocations(const std::function<void(ActualInvocation<arglist...> &)> &scanner) = 0; virtual void setMethodDetails(std::string mockName, std::string methodName) = 0; virtual bool isOfMethod(MethodInfo &method) = 0; virtual ActualInvocationsSource &getInvolvedMock() = 0; }; private: class Implementation { Context *_stubbingContext; ActionSequence<R, arglist...> *_recordedActionSequence; typename ActualInvocation<arglist...>::Matcher *_invocationMatcher; bool _commited; Context &getStubbingContext() const { return *_stubbingContext; } public: Implementation(Context *stubbingContext) : _stubbingContext(stubbingContext), _recordedActionSequence(new ActionSequence<R, arglist...>()), _invocationMatcher { new DefaultInvocationMatcher<arglist...>()}, _commited(false) { } ~Implementation() { delete _stubbingContext; if (!_commited) { delete _recordedActionSequence; delete _invocationMatcher; } } ActionSequence<R, arglist...> &getRecordedActionSequence() { return *_recordedActionSequence; } std::string format() const { std::string s = getStubbingContext().getMethodName(); s += _invocationMatcher->format(); return s; } void getActualInvocations(std::unordered_set<Invocation *> &into) const { auto scanner = [&](ActualInvocation<arglist...> &a) { if (_invocationMatcher->matches(a)) { into.insert(&a); } }; getStubbingContext().scanActualInvocations(scanner); } bool matches(Invocation &invocation) { MethodInfo &actualMethod = invocation.getMethod(); if (!getStubbingContext().isOfMethod(actualMethod)) { return false; } ActualInvocation<arglist...> &actualInvocation = dynamic_cast<ActualInvocation<arglist...> &>(invocation); return _invocationMatcher->matches(actualInvocation); } void commit() { getStubbingContext().addMethodInvocationHandler(_invocationMatcher, _recordedActionSequence); _commited = true; } void appendAction(Action<R, arglist...> *action) { getRecordedActionSequence().AppendDo(action); } void setMethodBodyByAssignment(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) { appendAction(new RepeatForever<R, arglist...>(method)); commit(); } void setMethodDetails(std::string mockName, std::string methodName) { getStubbingContext().setMethodDetails(mockName, methodName); } void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const { into.push_back(&getStubbingContext().getInvolvedMock()); } typename std::function<R(arglist &...)> getOriginalMethod() { return getStubbingContext().getOriginalMethod(); } void setInvocationMatcher(typename ActualInvocation<arglist...>::Matcher *matcher) { delete _invocationMatcher; _invocationMatcher = matcher; } }; protected: MethodMockingContext(Context *stubbingContext) : _impl{new Implementation(stubbingContext)} { } MethodMockingContext(MethodMockingContext &) = default; MethodMockingContext(MethodMockingContext &&other) : _impl(std::move(other._impl)) { } virtual ~MethodMockingContext() NO_THROWS { } std::string format() const override { return _impl->format(); } unsigned int size() const override { return 1; } void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const override { _impl->getInvolvedMocks(into); } void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const override { const Invocation::Matcher *b = this; Invocation::Matcher *c = const_cast<Invocation::Matcher *>(b); into.push_back(c); } void getActualInvocations(std::unordered_set<Invocation *> &into) const override { _impl->getActualInvocations(into); } bool matches(Invocation &invocation) override { return _impl->matches(invocation); } void commit() override { _impl->commit(); } void setMethodDetails(std::string mockName, std::string methodName) { _impl->setMethodDetails(mockName, methodName); } void setMatchingCriteria(std::function<bool(arglist &...)> predicate) { typename ActualInvocation<arglist...>::Matcher *matcher{ new UserDefinedInvocationMatcher<arglist...>(predicate)}; _impl->setInvocationMatcher(matcher); } void setMatchingCriteria(const std::vector<Destructible *> &matchers) { typename ActualInvocation<arglist...>::Matcher *matcher{ new ArgumentsMatcherInvocationMatcher<arglist...>(matchers)}; _impl->setInvocationMatcher(matcher); } void appendAction(Action<R, arglist...> *action) override { _impl->appendAction(action); } void setMethodBodyByAssignment(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) { _impl->setMethodBodyByAssignment(method); } template<class ...matcherCreators, class = typename std::enable_if< sizeof...(matcherCreators) == sizeof...(arglist)>::type> void setMatchingCriteria(const matcherCreators &... matcherCreator) { std::vector<Destructible *> matchers; MatchersCollector<0, arglist...> c(matchers); c.CollectMatchers(matcherCreator...); MethodMockingContext<R, arglist...>::setMatchingCriteria(matchers); } private: typename std::function<R(arglist&...)> getOriginalMethod() override { return _impl->getOriginalMethod(); } std::shared_ptr<Implementation> _impl; }; template<typename R, typename ... arglist> class MockingContext : public MethodMockingContext<R, arglist...> { MockingContext &operator=(const MockingContext &) = delete; public: MockingContext(typename MethodMockingContext<R, arglist...>::Context *stubbingContext) : MethodMockingContext<R, arglist...>(stubbingContext) { } MockingContext(MockingContext &) = default; MockingContext(MockingContext &&other) : MethodMockingContext<R, arglist...>(std::move(other)) { } MockingContext<R, arglist...> &setMethodDetails(std::string mockName, std::string methodName) { MethodMockingContext<R, arglist...>::setMethodDetails(mockName, methodName); return *this; } MockingContext<R, arglist...> &Using(const arglist &... args) { MethodMockingContext<R, arglist...>::setMatchingCriteria(args...); return *this; } template<class ...arg_matcher> MockingContext<R, arglist...> &Using(const arg_matcher &... arg_matchers) { MethodMockingContext<R, arglist...>::setMatchingCriteria(arg_matchers...); return *this; } MockingContext<R, arglist...> &Matching(std::function<bool(arglist &...)> matcher) { MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher); return *this; } MockingContext<R, arglist...> &operator()(const arglist &... args) { MethodMockingContext<R, arglist...>::setMatchingCriteria(args...); return *this; } MockingContext<R, arglist...> &operator()(std::function<bool(arglist &...)> matcher) { MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher); return *this; } void operator=(std::function<R(arglist &...)> method) { MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method); } template<typename U = R> typename std::enable_if<!std::is_reference<U>::value, void>::type operator=(const R &r) { auto method = [r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; }; MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method); } template<typename U = R> typename std::enable_if<std::is_reference<U>::value, void>::type operator=(const R &r) { auto method = [&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; }; MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method); } }; template<typename ... arglist> class MockingContext<void, arglist...> : public MethodMockingContext<void, arglist...> { MockingContext &operator=(const MockingContext &) = delete; public: MockingContext(typename MethodMockingContext<void, arglist...>::Context *stubbingContext) : MethodMockingContext<void, arglist...>(stubbingContext) { } MockingContext(MockingContext &) = default; MockingContext(MockingContext &&other) : MethodMockingContext<void, arglist...>(std::move(other)) { } MockingContext<void, arglist...> &setMethodDetails(std::string mockName, std::string methodName) { MethodMockingContext<void, arglist...>::setMethodDetails(mockName, methodName); return *this; } MockingContext<void, arglist...> &Using(const arglist &... args) { MethodMockingContext<void, arglist...>::setMatchingCriteria(args...); return *this; } template<class ...arg_matcher> MockingContext<void, arglist...> &Using(const arg_matcher &... arg_matchers) { MethodMockingContext<void, arglist...>::setMatchingCriteria(arg_matchers...); return *this; } MockingContext<void, arglist...> &Matching(std::function<bool(arglist &...)> matcher) { MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher); return *this; } MockingContext<void, arglist...> &operator()(const arglist &... args) { MethodMockingContext<void, arglist...>::setMatchingCriteria(args...); return *this; } MockingContext<void, arglist...> &operator()(std::function<bool(arglist &...)> matcher) { MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher); return *this; } void operator=(std::function<void(arglist &...)> method) { MethodMockingContext<void, arglist...>::setMethodBodyByAssignment(method); } }; class DtorMockingContext : public MethodMockingContext<void> { public: DtorMockingContext(MethodMockingContext<void>::Context *stubbingContext) : MethodMockingContext<void>(stubbingContext) { } DtorMockingContext(DtorMockingContext &other) : MethodMockingContext<void>(other) { } DtorMockingContext(DtorMockingContext &&other) : MethodMockingContext<void>(std::move(other)) { } void operator=(std::function<void()> method) { MethodMockingContext<void>::setMethodBodyByAssignment(method); } DtorMockingContext &setMethodDetails(std::string mockName, std::string methodName) { MethodMockingContext<void>::setMethodDetails(mockName, methodName); return *this; } }; } namespace fakeit { template<typename C, typename ... baseclasses> class MockImpl : private MockObject<C>, public virtual ActualInvocationsSource { public: MockImpl(FakeitContext &fakeit, C &obj) : MockImpl<C, baseclasses...>(fakeit, obj, true) { } MockImpl(FakeitContext &fakeit) : MockImpl<C, baseclasses...>(fakeit, *(createFakeInstance()), false){ FakeObject<C, baseclasses...> *fake = asFakeObject(_instanceOwner.get()); fake->getVirtualTable().setCookie(1, this); } virtual ~MockImpl() NO_THROWS { _proxy.detach(); } void getActualInvocations(std::unordered_set<Invocation *> &into) const override { std::vector<ActualInvocationsSource *> vec; _proxy.getMethodMocks(vec); for (ActualInvocationsSource *s : vec) { s->getActualInvocations(into); } } void initDataMembersIfOwner() { if (isOwner()) { FakeObject<C, baseclasses...> *fake = asFakeObject(_instanceOwner.get()); fake->initializeDataMembersArea(); } } void reset() { _proxy.Reset(); initDataMembersIfOwner(); } void clear() { std::vector<ActualInvocationsContainer *> vec; _proxy.getMethodMocks(vec); for (ActualInvocationsContainer *s : vec) { s->clear(); } initDataMembersIfOwner(); } virtual C &get() override { return _proxy.get(); } virtual FakeitContext &getFakeIt() override { return _fakeit; } template<class DATA_TYPE, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type> DataMemberStubbingRoot<C, DATA_TYPE> stubDataMember(DATA_TYPE T::*member, const arglist &... ctorargs) { _proxy.stubDataMember(member, ctorargs...); return DataMemberStubbingRoot<T, DATA_TYPE>(); } template<int id, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type> MockingContext<R, arglist...> stubMethod(R(T::*vMethod)(arglist...)) { return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl < id, R, arglist... > (*this, vMethod)); } DtorMockingContext stubDtor() { return DtorMockingContext(new DtorMockingContextImpl(*this)); } private: std::shared_ptr<FakeObject<C, baseclasses...>> _instanceOwner; DynamicProxy<C, baseclasses...> _proxy; FakeitContext &_fakeit; MockImpl(FakeitContext &fakeit, C &obj, bool isSpy) : _instanceOwner(isSpy ? nullptr : asFakeObject(&obj)) , _proxy{obj} , _fakeit(fakeit) {} static FakeObject<C, baseclasses...>* asFakeObject(void* instance){ return reinterpret_cast<FakeObject<C, baseclasses...> *>(instance); } template<typename R, typename ... arglist> class MethodMockingContextBase : public MethodMockingContext<R, arglist...>::Context { protected: MockImpl<C, baseclasses...> &_mock; virtual RecordedMethodBody<R, arglist...> &getRecordedMethodBody() = 0; public: MethodMockingContextBase(MockImpl<C, baseclasses...> &mock) : _mock(mock) { } virtual ~MethodMockingContextBase() = default; void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher, ActualInvocationHandler<R, arglist...> *invocationHandler) { getRecordedMethodBody().addMethodInvocationHandler(matcher, invocationHandler); } void scanActualInvocations(const std::function<void(ActualInvocation<arglist...> &)> &scanner) { getRecordedMethodBody().scanActualInvocations(scanner); } void setMethodDetails(std::string mockName, std::string methodName) { getRecordedMethodBody().setMethodDetails(mockName, methodName); } bool isOfMethod(MethodInfo &method) { return getRecordedMethodBody().isOfMethod(method); } ActualInvocationsSource &getInvolvedMock() { return _mock; } std::string getMethodName() { return getRecordedMethodBody().getMethod().name(); } }; template<typename R, typename ... arglist> class MethodMockingContextImpl : public MethodMockingContextBase<R, arglist...> { protected: R (C::*_vMethod)(arglist...); public: virtual ~MethodMockingContextImpl() = default; MethodMockingContextImpl(MockImpl<C, baseclasses...> &mock, R (C::*vMethod)(arglist...)) : MethodMockingContextBase<R, arglist...>(mock), _vMethod(vMethod) { } virtual std::function<R(arglist&...)> getOriginalMethod() override { void *mPtr = MethodMockingContextBase<R, arglist...>::_mock.getOriginalMethod(_vMethod); C * instance = &(MethodMockingContextBase<R, arglist...>::_mock.get()); return [=](arglist&... args) -> R { auto m = union_cast<typename VTableMethodType<R,arglist...>::type>(mPtr); return m(instance, std::forward<arglist>(args)...); }; } }; template<int id, typename R, typename ... arglist> class UniqueMethodMockingContextImpl : public MethodMockingContextImpl<R, arglist...> { protected: virtual RecordedMethodBody<R, arglist...> &getRecordedMethodBody() override { return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<id>( MethodMockingContextBase<R, arglist...>::_mock._proxy, MethodMockingContextImpl<R, arglist...>::_vMethod); } public: UniqueMethodMockingContextImpl(MockImpl<C, baseclasses...> &mock, R (C::*vMethod)(arglist...)) : MethodMockingContextImpl<R, arglist...>(mock, vMethod) { } }; class DtorMockingContextImpl : public MethodMockingContextBase<void> { protected: virtual RecordedMethodBody<void> &getRecordedMethodBody() override { return MethodMockingContextBase<void>::_mock.stubDtorIfNotStubbed( MethodMockingContextBase<void>::_mock._proxy); } public: virtual ~DtorMockingContextImpl() = default; DtorMockingContextImpl(MockImpl<C, baseclasses...> &mock) : MethodMockingContextBase<void>(mock) { } virtual std::function<void()> getOriginalMethod() override { return [=]() -> void { }; } }; static MockImpl<C, baseclasses...> *getMockImpl(void *instance) { FakeObject<C, baseclasses...> *fake = asFakeObject(instance); MockImpl<C, baseclasses...> *mock = reinterpret_cast<MockImpl<C, baseclasses...> *>(fake->getVirtualTable().getCookie( 1)); return mock; } bool isOwner(){ return _instanceOwner != nullptr;} void unmockedDtor() {} void unmocked() { ActualInvocation<> invocation(Invocation::nextInvocationOrdinal(), UnknownMethod::instance()); UnexpectedMethodCallEvent event(UnexpectedType::Unmocked, invocation); auto &fakeit = getMockImpl(this)->_fakeit; fakeit.handle(event); std::string format = fakeit.format(event); UnexpectedMethodCallException e(format); throw e; } static C *createFakeInstance() { FakeObject<C, baseclasses...> *fake = new FakeObject<C, baseclasses...>(); void *unmockedMethodStubPtr = union_cast<void *>(&MockImpl<C, baseclasses...>::unmocked); void *unmockedDtorStubPtr = union_cast<void *>(&MockImpl<C, baseclasses...>::unmockedDtor); fake->getVirtualTable().initAll(unmockedMethodStubPtr); if (VTUtils::hasVirtualDestructor<C>()) fake->setDtor(unmockedDtorStubPtr); return reinterpret_cast<C *>(fake); } template<typename R, typename ... arglist> void *getOriginalMethod(R (C::*vMethod)(arglist...)) { auto vt = _proxy.getOriginalVT(); auto offset = VTUtils::getOffset(vMethod); void *origMethodPtr = vt.getMethod(offset); return origMethodPtr; } void *getOriginalDtor() { auto vt = _proxy.getOriginalVT(); auto offset = VTUtils::getDestructorOffset<C>(); void *origMethodPtr = vt.getMethod(offset); return origMethodPtr; } template<unsigned int id, typename R, typename ... arglist> RecordedMethodBody<R, arglist...> &stubMethodIfNotStubbed(DynamicProxy<C, baseclasses...> &proxy, R (C::*vMethod)(arglist...)) { if (!proxy.isMethodStubbed(vMethod)) { proxy.template stubMethod<id>(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod)); } Destructible *d = proxy.getMethodMock(vMethod); RecordedMethodBody<R, arglist...> *methodMock = dynamic_cast<RecordedMethodBody<R, arglist...> *>(d); return *methodMock; } RecordedMethodBody<void> &stubDtorIfNotStubbed(DynamicProxy<C, baseclasses...> &proxy) { if (!proxy.isDtorStubbed()) { proxy.stubDtor(createRecordedDtorBody(*this)); } Destructible *d = proxy.getDtorMock(); RecordedMethodBody<void> *dtorMock = dynamic_cast<RecordedMethodBody<void> *>(d); return *dtorMock; } template<typename R, typename ... arglist> static RecordedMethodBody<R, arglist...> *createRecordedMethodBody(MockObject<C> &mock, R(C::*vMethod)(arglist...)) { return new RecordedMethodBody<R, arglist...>(mock.getFakeIt(), typeid(vMethod).name()); } static RecordedMethodBody<void> *createRecordedDtorBody(MockObject<C> &mock) { return new RecordedMethodBody<void>(mock.getFakeIt(), "dtor"); } }; } namespace fakeit { template<typename R, typename... Args> struct Prototype; template<typename R, typename... Args> struct Prototype<R(Args...)> { typedef R Type(Args...); typedef R ConstType(Args...) const; template<class C> struct MemberType { typedef Type(C::*type); typedef ConstType(C::*cosntType); static type get(type t) { return t; } static cosntType getconst(cosntType t) { return t; } }; }; template<int X, typename R, typename C, typename... arglist> struct UniqueMethod { R (C::*method)(arglist...); UniqueMethod(R (C::*vMethod)(arglist...)) : method(vMethod) { } int uniqueId() { return X; } }; } namespace fakeit { namespace internal { } using namespace fakeit::internal; template<typename C, typename ... baseclasses> class Mock : public ActualInvocationsSource { MockImpl<C, baseclasses...> impl; public: virtual ~Mock() = default; static_assert(std::is_polymorphic<C>::value, "Can only mock a polymorphic type"); Mock() : impl(Fakeit) { } explicit Mock(C &obj) : impl(Fakeit, obj) { } virtual C &get() { return impl.get(); } C &operator()() { return get(); } void Reset() { impl.reset(); } void ClearInvocationHistory() { impl.clear(); } template<class DATA_TYPE, typename ... arglist, class = typename std::enable_if<std::is_member_object_pointer<DATA_TYPE C::*>::value>::type> DataMemberStubbingRoot<C, DATA_TYPE> Stub(DATA_TYPE C::* member, const arglist &... ctorargs) { return impl.stubDataMember(member, ctorargs...); } template<int id, typename R, typename T, typename ... arglist, class = typename std::enable_if< !std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<R, arglist...> stub(R (T::*vMethod)(arglist...) const) { auto methodWithoutConstVolatile = reinterpret_cast<R (T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< !std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...) volatile) { auto methodWithoutConstVolatile = reinterpret_cast<R(T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< !std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) { auto methodWithoutConstVolatile = reinterpret_cast<R(T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< !std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...)) { return impl.template stubMethod<id>(vMethod); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) const) { auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) volatile) { auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) { auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if< std::is_void<R>::value && std::is_base_of<T, C>::value>::type> MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...)) { auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod); return impl.template stubMethod<id>(methodWithoutConstVolatile); } DtorMockingContext dtor() { return impl.stubDtor(); } void getActualInvocations(std::unordered_set<Invocation *> &into) const override { impl.getActualInvocations(into); } }; } #include <exception> namespace fakeit { class RefCount { private: int count; public: void AddRef() { count++; } int Release() { return --count; } }; template<typename T> class smart_ptr { private: T *pData; RefCount *reference; public: smart_ptr() : pData(0), reference(0) { reference = new RefCount(); reference->AddRef(); } smart_ptr(T *pValue) : pData(pValue), reference(0) { reference = new RefCount(); reference->AddRef(); } smart_ptr(const smart_ptr<T> &sp) : pData(sp.pData), reference(sp.reference) { reference->AddRef(); } ~smart_ptr() THROWS { if (reference->Release() == 0) { delete reference; delete pData; } } T &operator*() { return *pData; } T *operator->() { return pData; } smart_ptr<T> &operator=(const smart_ptr<T> &sp) { if (this != &sp) { if (reference->Release() == 0) { delete reference; delete pData; } pData = sp.pData; reference = sp.reference; reference->AddRef(); } return *this; } }; } namespace fakeit { class WhenFunctor { struct StubbingChange { friend class WhenFunctor; virtual ~StubbingChange() THROWS { if (UncaughtException()) { return; } _xaction.commit(); } StubbingChange(StubbingChange &other) : _xaction(other._xaction) { } private: StubbingChange(Xaction &xaction) : _xaction(xaction) { } Xaction &_xaction; }; public: template<typename R, typename ... arglist> struct MethodProgress : MethodStubbingProgress<R, arglist...> { friend class WhenFunctor; virtual ~MethodProgress() override = default; MethodProgress(MethodProgress &other) : _progress(other._progress), _context(other._context) { } MethodProgress(StubbingContext<R, arglist...> &xaction) : _progress(new StubbingChange(xaction)), _context(xaction) { } protected: virtual MethodStubbingProgress<R, arglist...> &DoImpl(Action<R, arglist...> *action) override { _context.appendAction(action); return *this; } private: smart_ptr<StubbingChange> _progress; StubbingContext<R, arglist...> &_context; }; WhenFunctor() { } template<typename R, typename ... arglist> MethodProgress<R, arglist...> operator()(const StubbingContext<R, arglist...> &stubbingContext) { StubbingContext<R, arglist...> &rootWithoutConst = const_cast<StubbingContext<R, arglist...> &>(stubbingContext); MethodProgress<R, arglist...> progress(rootWithoutConst); return progress; } }; } namespace fakeit { class FakeFunctor { private: template<typename R, typename ... arglist> void fake(const StubbingContext<R, arglist...> &root) { StubbingContext<R, arglist...> &rootWithoutConst = const_cast<StubbingContext<R, arglist...> &>(root); rootWithoutConst.appendAction(new ReturnDefaultValue<R, arglist...>()); rootWithoutConst.commit(); } void operator()() { } public: template<typename H, typename ... M> void operator()(const H &head, const M &... tail) { fake(head); this->operator()(tail...); } }; } #include <set> #include <set> namespace fakeit { struct InvocationUtils { static void sortByInvocationOrder(std::unordered_set<Invocation *> &ivocations, std::vector<Invocation *> &result) { auto comparator = [](Invocation *a, Invocation *b) -> bool { return a->getOrdinal() < b->getOrdinal(); }; std::set<Invocation *, bool (*)(Invocation *a, Invocation *b)> sortedIvocations(comparator); for (auto i : ivocations) sortedIvocations.insert(i); for (auto i : sortedIvocations) result.push_back(i); } static void collectActualInvocations(std::unordered_set<Invocation *> &actualInvocations, std::vector<ActualInvocationsSource *> &invocationSources) { for (auto source : invocationSources) { source->getActualInvocations(actualInvocations); } } static void selectNonVerifiedInvocations(std::unordered_set<Invocation *> &actualInvocations, std::unordered_set<Invocation *> &into) { for (auto invocation : actualInvocations) { if (!invocation->isVerified()) { into.insert(invocation); } } } static void collectInvocationSources(std::vector<ActualInvocationsSource *> &) { } template<typename ... list> static void collectInvocationSources(std::vector<ActualInvocationsSource *> &into, const ActualInvocationsSource &mock, const list &... tail) { into.push_back(const_cast<ActualInvocationsSource *>(&mock)); collectInvocationSources(into, tail...); } static void collectSequences(std::vector<Sequence *> &) { } template<typename ... list> static void collectSequences(std::vector<Sequence *> &vec, const Sequence &sequence, const list &... tail) { vec.push_back(&const_cast<Sequence &>(sequence)); collectSequences(vec, tail...); } static void collectInvolvedMocks(std::vector<Sequence *> &allSequences, std::vector<ActualInvocationsSource *> &involvedMocks) { for (auto sequence : allSequences) { sequence->getInvolvedMocks(involvedMocks); } } template<class T> static T &remove_const(const T &s) { return const_cast<T &>(s); } }; } #include <memory> #include <vector> #include <unordered_set> namespace fakeit { struct MatchAnalysis { std::vector<Invocation *> actualSequence; std::vector<Invocation *> matchedInvocations; int count; void run(InvocationsSourceProxy &involvedInvocationSources, std::vector<Sequence *> &expectedPattern) { getActualInvocationSequence(involvedInvocationSources, actualSequence); count = countMatches(expectedPattern, actualSequence, matchedInvocations); } private: static void getActualInvocationSequence(InvocationsSourceProxy &involvedMocks, std::vector<Invocation *> &actualSequence) { std::unordered_set<Invocation *> actualInvocations; collectActualInvocations(involvedMocks, actualInvocations); InvocationUtils::sortByInvocationOrder(actualInvocations, actualSequence); } static int countMatches(std::vector<Sequence *> &pattern, std::vector<Invocation *> &actualSequence, std::vector<Invocation *> &matchedInvocations) { int end = -1; int count = 0; int startSearchIndex = 0; while (findNextMatch(pattern, actualSequence, startSearchIndex, end, matchedInvocations)) { count++; startSearchIndex = end; } return count; } static void collectActualInvocations(InvocationsSourceProxy &involvedMocks, std::unordered_set<Invocation *> &actualInvocations) { involvedMocks.getActualInvocations(actualInvocations); } static bool findNextMatch(std::vector<Sequence *> &pattern, std::vector<Invocation *> &actualSequence, int startSearchIndex, int &end, std::vector<Invocation *> &matchedInvocations) { for (auto sequence : pattern) { int index = findNextMatch(sequence, actualSequence, startSearchIndex); if (index == -1) { return false; } collectMatchedInvocations(actualSequence, matchedInvocations, index, sequence->size()); startSearchIndex = index + sequence->size(); } end = startSearchIndex; return true; } static void collectMatchedInvocations(std::vector<Invocation *> &actualSequence, std::vector<Invocation *> &matchedInvocations, int start, int length) { int indexAfterMatchedPattern = start + length; for (; start < indexAfterMatchedPattern; start++) { matchedInvocations.push_back(actualSequence[start]); } } static bool isMatch(std::vector<Invocation *> &actualSequence, std::vector<Invocation::Matcher *> &expectedSequence, int start) { bool found = true; for (unsigned int j = 0; found && j < expectedSequence.size(); j++) { Invocation *actual = actualSequence[start + j]; Invocation::Matcher *expected = expectedSequence[j]; found = found && expected->matches(*actual); } return found; } static int findNextMatch(Sequence *&pattern, std::vector<Invocation *> &actualSequence, int startSearchIndex) { std::vector<Invocation::Matcher *> expectedSequence; pattern->getExpectedSequence(expectedSequence); for (int i = startSearchIndex; i < ((int) actualSequence.size() - (int) expectedSequence.size() + 1); i++) { if (isMatch(actualSequence, expectedSequence, i)) { return i; } } return -1; } }; } namespace fakeit { struct SequenceVerificationExpectation { friend class SequenceVerificationProgress; ~SequenceVerificationExpectation() THROWS { if (UncaughtException()) { return; } VerifyExpectation(_fakeit); } void setExpectedPattern(std::vector<Sequence *> expectedPattern) { _expectedPattern = expectedPattern; } void setExpectedCount(const int count) { _expectedCount = count; } void expectAnything() { _expectAnything = true; } void setFileInfo(const char * file, int line, const char * callingMethod) { _file = file; _line = line; _testMethod = callingMethod; } private: VerificationEventHandler &_fakeit; InvocationsSourceProxy _involvedInvocationSources; std::vector<Sequence *> _expectedPattern; int _expectedCount; bool _expectAnything; const char * _file; int _line; const char * _testMethod; bool _isVerified; SequenceVerificationExpectation( VerificationEventHandler &fakeit, InvocationsSourceProxy mocks, std::vector<Sequence *> &expectedPattern) : _fakeit(fakeit), _involvedInvocationSources(mocks), _expectedPattern(expectedPattern), _expectedCount(-1), _expectAnything(false), _line(0), _isVerified(false) { } void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) { if (_isVerified) return; _isVerified = true; MatchAnalysis ma; ma.run(_involvedInvocationSources, _expectedPattern); if (isNotAnythingVerification()) { if (isAtLeastVerification() && atLeastLimitNotReached(ma.count)) { return handleAtLeastVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count); } if (isExactVerification() && exactLimitNotMatched(ma.count)) { return handleExactVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count); } } markAsVerified(ma.matchedInvocations); } std::vector<Sequence *> &collectSequences(std::vector<Sequence *> &vec) { return vec; } template<typename ... list> std::vector<Sequence *> &collectSequences(std::vector<Sequence *> &vec, const Sequence &sequence, const list &... tail) { vec.push_back(&const_cast<Sequence &>(sequence)); return collectSequences(vec, tail...); } static void markAsVerified(std::vector<Invocation *> &matchedInvocations) { for (auto i : matchedInvocations) { i->markAsVerified(); } } bool isNotAnythingVerification() { return !_expectAnything; } bool isAtLeastVerification() { return _expectedCount < 0; } bool isExactVerification() { return !isAtLeastVerification(); } bool atLeastLimitNotReached(int actualCount) { return actualCount < -_expectedCount; } bool exactLimitNotMatched(int actualCount) { return actualCount != _expectedCount; } void handleExactVerificationEvent(VerificationEventHandler &verificationErrorHandler, std::vector<Invocation *> actualSequence, int count) { SequenceVerificationEvent evt(VerificationType::Exact, _expectedPattern, actualSequence, _expectedCount, count); evt.setFileInfo(_file, _line, _testMethod); return verificationErrorHandler.handle(evt); } void handleAtLeastVerificationEvent(VerificationEventHandler &verificationErrorHandler, std::vector<Invocation *> actualSequence, int count) { SequenceVerificationEvent evt(VerificationType::AtLeast, _expectedPattern, actualSequence, -_expectedCount, count); evt.setFileInfo(_file, _line, _testMethod); return verificationErrorHandler.handle(evt); } }; } namespace fakeit { class ThrowFalseEventHandler : public VerificationEventHandler { void handle(const SequenceVerificationEvent &) override { throw false; } void handle(const NoMoreInvocationsVerificationEvent &) override { throw false; } }; } namespace fakeit { struct FakeitContext; class SequenceVerificationProgress { friend class UsingFunctor; friend class VerifyFunctor; friend class UsingProgress; smart_ptr<SequenceVerificationExpectation> _expectationPtr; SequenceVerificationProgress(SequenceVerificationExpectation *ptr) : _expectationPtr(ptr) { } SequenceVerificationProgress( FakeitContext &fakeit, InvocationsSourceProxy sources, std::vector<Sequence *> &allSequences) : SequenceVerificationProgress(new SequenceVerificationExpectation(fakeit, sources, allSequences)) { } virtual void verifyInvocations(const int times) { _expectationPtr->setExpectedCount(times); } class Terminator { smart_ptr<SequenceVerificationExpectation> _expectationPtr; bool toBool() { try { ThrowFalseEventHandler eh; _expectationPtr->VerifyExpectation(eh); return true; } catch (bool e) { return e; } } public: Terminator(smart_ptr<SequenceVerificationExpectation> expectationPtr) : _expectationPtr(expectationPtr) { }; operator bool() { return toBool(); } bool operator!() const { return !const_cast<Terminator *>(this)->toBool(); } }; public: ~SequenceVerificationProgress() THROWS { }; operator bool() const { return Terminator(_expectationPtr); } bool operator!() const { return !Terminator(_expectationPtr); } Terminator Any() { _expectationPtr->expectAnything(); return Terminator(_expectationPtr); } Terminator Never() { Exactly(0); return Terminator(_expectationPtr); } Terminator Once() { Exactly(1); return Terminator(_expectationPtr); } Terminator Twice() { Exactly(2); return Terminator(_expectationPtr); } Terminator AtLeastOnce() { verifyInvocations(-1); return Terminator(_expectationPtr); } Terminator Exactly(const int times) { if (times < 0) { throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times))); } verifyInvocations(times); return Terminator(_expectationPtr); } Terminator Exactly(const Quantity &q) { Exactly(q.quantity); return Terminator(_expectationPtr); } Terminator AtLeast(const int times) { if (times < 0) { throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times))); } verifyInvocations(-times); return Terminator(_expectationPtr); } Terminator AtLeast(const Quantity &q) { AtLeast(q.quantity); return Terminator(_expectationPtr); } SequenceVerificationProgress setFileInfo(const char * file, int line, const char * callingMethod) { _expectationPtr->setFileInfo(file, line, callingMethod); return *this; } }; } namespace fakeit { class UsingProgress { fakeit::FakeitContext &_fakeit; InvocationsSourceProxy _sources; void collectSequences(std::vector<fakeit::Sequence *> &) { } template<typename ... list> void collectSequences(std::vector<fakeit::Sequence *> &vec, const fakeit::Sequence &sequence, const list &... tail) { vec.push_back(&const_cast<fakeit::Sequence &>(sequence)); collectSequences(vec, tail...); } public: UsingProgress(fakeit::FakeitContext &fakeit, InvocationsSourceProxy source) : _fakeit(fakeit), _sources(source) { } template<typename ... list> SequenceVerificationProgress Verify(const fakeit::Sequence &sequence, const list &... tail) { std::vector<fakeit::Sequence *> allSequences; collectSequences(allSequences, sequence, tail...); SequenceVerificationProgress progress(_fakeit, _sources, allSequences); return progress; } }; } namespace fakeit { class UsingFunctor { friend class VerifyFunctor; FakeitContext &_fakeit; public: UsingFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } template<typename ... list> UsingProgress operator()(const ActualInvocationsSource &head, const list &... tail) { std::vector<ActualInvocationsSource *> allMocks{&InvocationUtils::remove_const(head), &InvocationUtils::remove_const(tail)...}; InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)}; UsingProgress progress(_fakeit, aggregateInvocationsSource); return progress; } }; } #include <set> namespace fakeit { class VerifyFunctor { FakeitContext &_fakeit; public: VerifyFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } template<typename ... list> SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) { std::vector<Sequence *> allSequences{&InvocationUtils::remove_const(sequence), &InvocationUtils::remove_const(tail)...}; std::vector<ActualInvocationsSource *> involvedSources; InvocationUtils::collectInvolvedMocks(allSequences, involvedSources); InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)}; UsingProgress usingProgress(_fakeit, aggregateInvocationsSource); return usingProgress.Verify(sequence, tail...); } }; } #include <set> #include <memory> namespace fakeit { class VerifyNoOtherInvocationsVerificationProgress { friend class VerifyNoOtherInvocationsFunctor; struct VerifyNoOtherInvocationsExpectation { friend class VerifyNoOtherInvocationsVerificationProgress; ~VerifyNoOtherInvocationsExpectation() THROWS { if (UncaughtException()) { return; } VerifyExpectation(_fakeit); } void setFileInfo(const char * file, int line, const char * callingMethod) { _file = file; _line = line; _callingMethod = callingMethod; } private: VerificationEventHandler &_fakeit; std::vector<ActualInvocationsSource *> _mocks; const char * _file; int _line; const char * _callingMethod; bool _isVerified; VerifyNoOtherInvocationsExpectation(VerificationEventHandler &fakeit, std::vector<ActualInvocationsSource *> mocks) : _fakeit(fakeit), _mocks(mocks), _line(0), _isVerified(false) { } VerifyNoOtherInvocationsExpectation(VerifyNoOtherInvocationsExpectation &other) = default; void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) { if (_isVerified) return; _isVerified = true; std::unordered_set<Invocation *> actualInvocations; InvocationUtils::collectActualInvocations(actualInvocations, _mocks); std::unordered_set<Invocation *> nonVerifiedInvocations; InvocationUtils::selectNonVerifiedInvocations(actualInvocations, nonVerifiedInvocations); if (nonVerifiedInvocations.size() > 0) { std::vector<Invocation *> sortedNonVerifiedInvocations; InvocationUtils::sortByInvocationOrder(nonVerifiedInvocations, sortedNonVerifiedInvocations); std::vector<Invocation *> sortedActualInvocations; InvocationUtils::sortByInvocationOrder(actualInvocations, sortedActualInvocations); NoMoreInvocationsVerificationEvent evt(sortedActualInvocations, sortedNonVerifiedInvocations); evt.setFileInfo(_file, _line, _callingMethod); return verificationErrorHandler.handle(evt); } } }; fakeit::smart_ptr<VerifyNoOtherInvocationsExpectation> _ptr; VerifyNoOtherInvocationsVerificationProgress(VerifyNoOtherInvocationsExpectation *ptr) : _ptr(ptr) { } VerifyNoOtherInvocationsVerificationProgress(FakeitContext &fakeit, std::vector<ActualInvocationsSource *> &invocationSources) : VerifyNoOtherInvocationsVerificationProgress( new VerifyNoOtherInvocationsExpectation(fakeit, invocationSources) ) { } bool toBool() { try { ThrowFalseEventHandler ev; _ptr->VerifyExpectation(ev); return true; } catch (bool e) { return e; } } public: ~VerifyNoOtherInvocationsVerificationProgress() THROWS { }; VerifyNoOtherInvocationsVerificationProgress setFileInfo(const char * file, int line, const char * callingMethod) { _ptr->setFileInfo(file, line, callingMethod); return *this; } operator bool() const { return const_cast<VerifyNoOtherInvocationsVerificationProgress *>(this)->toBool(); } bool operator!() const { return !const_cast<VerifyNoOtherInvocationsVerificationProgress *>(this)->toBool(); } }; } namespace fakeit { class VerifyNoOtherInvocationsFunctor { FakeitContext &_fakeit; public: VerifyNoOtherInvocationsFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } void operator()() { } template<typename ... list> VerifyNoOtherInvocationsVerificationProgress operator()(const ActualInvocationsSource &head, const list &... tail) { std::vector<ActualInvocationsSource *> invocationSources{&InvocationUtils::remove_const(head), &InvocationUtils::remove_const(tail)...}; VerifyNoOtherInvocationsVerificationProgress progress{_fakeit, invocationSources}; return progress; } }; } namespace fakeit { class SpyFunctor { private: template<typename R, typename ... arglist> void spy(const SpyingContext<R, arglist...> &root) { SpyingContext<R, arglist...> &rootWithoutConst = const_cast<SpyingContext<R, arglist...> &>(root); auto methodFromOriginalVT = rootWithoutConst.getOriginalMethod(); rootWithoutConst.appendAction(new ReturnDelegateValue<R, arglist...>(methodFromOriginalVT)); rootWithoutConst.commit(); } void operator()() { } public: template<typename H, typename ... M> void operator()(const H &head, const M &... tail) { spy(head); this->operator()(tail...); } }; } #include <vector> #include <set> namespace fakeit { class VerifyUnverifiedFunctor { FakeitContext &_fakeit; public: VerifyUnverifiedFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } template<typename ... list> SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) { std::vector<Sequence *> allSequences{&InvocationUtils::remove_const(sequence), &InvocationUtils::remove_const(tail)...}; std::vector<ActualInvocationsSource *> involvedSources; InvocationUtils::collectInvolvedMocks(allSequences, involvedSources); InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)}; InvocationsSourceProxy unverifiedInvocationsSource{ new UnverifiedInvocationsSource(aggregateInvocationsSource)}; UsingProgress usingProgress(_fakeit, unverifiedInvocationsSource); return usingProgress.Verify(sequence, tail...); } }; class UnverifiedFunctor { public: UnverifiedFunctor(FakeitContext &fakeit) : Verify(fakeit) { } VerifyUnverifiedFunctor Verify; template<typename ... list> UnverifiedInvocationsSource operator()(const ActualInvocationsSource &head, const list &... tail) { std::vector<ActualInvocationsSource *> allMocks{&InvocationUtils::remove_const(head), &InvocationUtils::remove_const(tail)...}; InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)}; UnverifiedInvocationsSource unverifiedInvocationsSource{aggregateInvocationsSource}; return unverifiedInvocationsSource; } }; } namespace fakeit { static UsingFunctor Using(Fakeit); static VerifyFunctor Verify(Fakeit); static VerifyNoOtherInvocationsFunctor VerifyNoOtherInvocations(Fakeit); static UnverifiedFunctor Unverified(Fakeit); static SpyFunctor Spy; static FakeFunctor Fake; static WhenFunctor When; template<class T> class SilenceUnusedVariableWarnings { void use(void *) { } SilenceUnusedVariableWarnings() { use(&Fake); use(&When); use(&Spy); use(&Using); use(&Verify); use(&VerifyNoOtherInvocations); use(&_); } }; } #ifdef _MSC_VER #define __func__ __FUNCTION__ #endif #define MOCK_TYPE(mock) \ std::remove_reference<decltype((mock).get())>::type #define OVERLOADED_METHOD_PTR(mock, method, prototype) \ fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::get(&MOCK_TYPE(mock)::method) #define CONST_OVERLOADED_METHOD_PTR(mock, method, prototype) \ fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::getconst(&MOCK_TYPE(mock)::method) #define Dtor(mock) \ (mock).dtor().setMethodDetails(#mock,"destructor") #define Method(mock, method) \ (mock).template stub<__COUNTER__>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method) #define OverloadedMethod(mock, method, prototype) \ (mock).template stub<__COUNTER__>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define ConstOverloadedMethod(mock, method, prototype) \ (mock).template stub<__COUNTER__>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define Verify(...) \ Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) #define Using(...) \ Using( __VA_ARGS__ ) #define VerifyNoOtherInvocations(...) \ VerifyNoOtherInvocations( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) #define Fake(...) \ Fake( __VA_ARGS__ ) #define When(call) \ When(call) struct Struct {}; struct Interface { virtual Struct* foo() = 0; virtual const Struct* foo() const = 0; }; template<typename MyType> void doStuff() { auto actorMovementProxy = std::make_shared<fakeit::Mock<MyType>>(); fakeit::When(OverloadedMethod((*actorMovementProxy), foo, Struct * ())).AlwaysReturn(nullptr); } void boh() { doStuff<Interface>(); } int main() { }
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
About the author
Statistics
Changelog
Version tree