use crate::clang::clang_x86_pipeline::{
compile_to_x86_assembly, compile_to_x86_ir, compile_with_options, PipelineResult,
PipelineStage, StageResult, X86CompileOptions, X86IRGenerator, X86OptLevel, X86OutputFormat,
X86Pipeline,
};
use crate::clang::{
compile_c, compile_c_file, compile_c_string, compile_c_to_assembly, CLangStandard,
ClangCodeGen, ClangDriver, ClangOptions, ClangTargetInfo,
};
use crate::x86::{
x86_calling_convention::{X86ArgClass, X86ArgInfo, X86CallFrame, X86CallingConvention},
x86_frame_lowering::{CallConv, X86FrameInfo, X86FrameLowering},
x86_full_mc_decoder::X86FullMCDecoder,
x86_full_mc_encoder::X86FullMCEncoder,
x86_instr_info::{X86InstrDesc, X86InstrInfo, X86MemOperand, X86Opcode, X86Operand},
x86_isel::X86InstructionSelector,
x86_mc_decoder::X86MCDecoder,
x86_mc_encoder::X86MCEncoder,
x86_register_info::{X86RegisterInfo, X86_32_REG_COUNT, X86_64_REG_COUNT},
x86_subtarget::X86Subtarget,
x86_target_machine::X86TargetMachine,
};
use crate::{
basic_block::new_basic_block,
context::LLVMContext,
function::{new_function, Function},
instruction::Opcode,
ir_builder::IRBuilder,
module::Module,
types::{Type, TypeKind},
value::{Value, ValueRef},
verifier::{verify_function, verify_module, VerifierResult},
};
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
use std::fmt;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Output, Stdio};
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex, RwLock};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone)]
pub struct X86StdLibTest {
pub target_triple: String,
pub c_standard: CLangStandard,
pub opt_level: X86OptLevel,
pub verify_ir: bool,
pub verify_asm: bool,
pub verify_obj: bool,
pub extra_flags: Vec<String>,
pub include_dirs: Vec<String>,
pub lib_dirs: Vec<String>,
pub link_libs: Vec<String>,
pub timeout_ms: u64,
pub run_benchmarks: bool,
pub bench_iterations: u32,
pub results: Vec<X86StdLibTestResult>,
pub bench_results: Vec<X86StdLibBenchResult>,
pub total_tests: u64,
pub total_passed: u64,
pub total_benchmarks: u64,
}
impl X86StdLibTest {
pub fn new() -> Self {
Self {
target_triple: "x86_64-unknown-linux-gnu".into(),
c_standard: CLangStandard::C17,
opt_level: X86OptLevel::O2,
verify_ir: true,
verify_asm: false,
verify_obj: false,
extra_flags: Vec::new(),
include_dirs: Vec::new(),
lib_dirs: Vec::new(),
link_libs: Vec::new(),
timeout_ms: 30000,
run_benchmarks: false,
bench_iterations: 100,
results: Vec::new(),
bench_results: Vec::new(),
total_tests: 0,
total_passed: 0,
total_benchmarks: 0,
}
}
pub fn new_x86_32() -> Self {
Self {
target_triple: "i686-unknown-linux-gnu".into(),
..Self::new()
}
}
pub fn new_windows_x86_64() -> Self {
Self {
target_triple: "x86_64-pc-windows-msvc".into(),
..Self::new()
}
}
pub fn with_opt_level(mut self, level: X86OptLevel) -> Self {
self.opt_level = level;
self
}
pub fn with_ir_verification(mut self, enable: bool) -> Self {
self.verify_ir = enable;
self
}
pub fn with_asm_verification(mut self, enable: bool) -> Self {
self.verify_asm = enable;
self
}
pub fn with_benchmarks(mut self, enable: bool) -> Self {
self.run_benchmarks = enable;
self
}
pub fn with_bench_iterations(mut self, n: u32) -> Self {
self.bench_iterations = n;
self
}
pub fn with_flag(mut self, flag: &str) -> Self {
self.extra_flags.push(flag.to_string());
self
}
pub fn with_include_dir(mut self, dir: &str) -> Self {
self.include_dirs.push(dir.to_string());
self
}
pub fn with_link_lib(mut self, lib: &str) -> Self {
self.link_libs.push(lib.to_string());
self
}
pub fn run_c_test(&mut self, name: &str, source: &str, expected_exit: i32) -> &mut Self {
self.total_tests += 1;
let start = Instant::now();
let mut result = X86StdLibTestResult {
name: name.to_string(),
category: X86StdLibCategory::CLibrary,
passed: false,
compiled: false,
exit_code: None,
duration: Duration::ZERO,
messages: Vec::new(),
ir_output: None,
asm_output: None,
};
let mut opts = self.build_compile_options();
let compile_result = compile_with_options(source, &mut opts);
if let Ok(pipeline_result) = &compile_result {
result.compiled = true;
result.messages.push("Compilation succeeded".to_string());
if self.verify_ir {
if let Some(ir) = &pipeline_result.ir_text {
result.ir_output = Some(ir.clone());
if ir.contains("define") && ir.contains("target triple") {
result.messages.push("IR structure valid".to_string());
} else {
result.messages.push("IR structure incomplete".to_string());
}
}
}
if self.verify_asm {
if let Some(asm) = &pipeline_result.asm_text {
result.asm_output = Some(asm.clone());
if asm.contains(".text") || asm.contains(".globl") {
result.messages.push("Assembly structure valid".to_string());
}
}
}
} else {
result
.messages
.push(format!("Compilation failed: {:?}", compile_result.err()));
}
result.duration = start.elapsed();
result.passed = result.compiled;
self.total_passed += if result.passed { 1 } else { 0 };
self.results.push(result);
self
}
pub fn run_cpp_test(&mut self, name: &str, source: &str) -> &mut Self {
self.total_tests += 1;
let start = Instant::now();
let mut result = X86StdLibTestResult {
name: name.to_string(),
category: X86StdLibCategory::CppLibrary,
passed: false,
compiled: false,
exit_code: None,
duration: Duration::ZERO,
messages: Vec::new(),
ir_output: None,
asm_output: None,
};
let mut opts = self.build_compile_options();
opts.extra_flags.push("-x".to_string());
opts.extra_flags.push("c++".to_string());
opts.extra_flags.push("-std=c++17".to_string());
let compile_result = compile_with_options(source, &mut opts);
if let Ok(pipeline_result) = &compile_result {
result.compiled = true;
result
.messages
.push("C++ compilation succeeded".to_string());
if self.verify_ir {
if let Some(ir) = &pipeline_result.ir_text {
result.ir_output = Some(ir.clone());
if ir.contains("define") || ir.contains("declare") {
result.messages.push("C++ IR structure valid".to_string());
}
}
}
if self.verify_asm {
if let Some(asm) = &pipeline_result.asm_text {
result.asm_output = Some(asm.clone());
}
}
} else {
result.messages.push(format!(
"C++ compilation failed: {:?}",
compile_result.err()
));
}
result.duration = start.elapsed();
result.passed = result.compiled;
self.total_passed += if result.passed { 1 } else { 0 };
self.results.push(result);
self
}
fn build_compile_options(&self) -> X86CompileOptions {
let mut opts = X86CompileOptions::default();
opts.target_triple = self.target_triple.clone();
opts.opt_level = self.opt_level;
opts.output_format = X86OutputFormat::Object;
opts.emit_ir = self.verify_ir;
opts.emit_assembly = self.verify_asm;
opts.timeout_ms = self.timeout_ms;
for flag in &self.extra_flags {
opts.extra_flags.push(flag.clone());
}
for dir in &self.include_dirs {
opts.include_dirs.push(dir.clone());
}
for lib in &self.link_libs {
opts.link_libs.push(lib.clone());
}
opts
}
pub fn run_all_c_tests(&mut self) -> &mut Self {
self.run_stdio_tests();
self.run_stdlib_tests();
self.run_string_tests();
self.run_math_tests();
self.run_time_tests();
self.run_ctype_tests();
self.run_errno_tests();
self.run_assert_tests();
self.run_signal_tests();
self.run_setjmp_tests();
self.run_stdarg_tests();
self
}
pub fn run_all_cpp_tests(&mut self) -> &mut Self {
self.run_iostream_tests();
self.run_cpp_string_tests();
self.run_vector_tests();
self.run_map_set_tests();
self.run_unordered_tests();
self.run_algorithm_tests();
self.run_memory_tests();
self.run_thread_tests();
self.run_atomic_tests();
self.run_functional_tests();
self.run_type_traits_tests();
self.run_modern_cpp_tests();
self
}
pub fn run_all_benchmarks(&mut self) -> &mut Self {
if !self.run_benchmarks {
return self;
}
self.bench_malloc_free();
self.bench_memcpy();
self.bench_string_ops();
self.bench_sort_perf();
self
}
pub fn pass_rate(&self) -> f64 {
if self.total_tests == 0 {
100.0
} else {
(self.total_passed as f64 / self.total_tests as f64) * 100.0
}
}
pub fn all_passed(&self) -> bool {
self.total_passed == self.total_tests && self.total_tests > 0
}
pub fn print_summary(&self) -> String {
let mut s = String::new();
s.push_str(&format!("═══ X86 StdLib Test Summary ═══\n"));
s.push_str(&format!("Target: {}\n", self.target_triple));
s.push_str(&format!(
"Total tests: {}, Passed: {}, Failed: {}, Pass rate: {:.1}%\n",
self.total_tests,
self.total_passed,
self.total_tests - self.total_passed,
self.pass_rate()
));
let mut by_category: BTreeMap<X86StdLibCategory, Vec<&X86StdLibTestResult>> =
BTreeMap::new();
for r in &self.results {
by_category.entry(r.category).or_default().push(r);
}
for (cat, results) in &by_category {
let passed = results.iter().filter(|r| r.passed).count();
let total = results.len();
s.push_str(&format!(" {:?}: {}/{} passed\n", cat, passed, total));
}
if !self.bench_results.is_empty() {
s.push_str(&format!("\nBenchmarks: {} total\n", self.total_benchmarks));
for b in &self.bench_results {
s.push_str(&format!(
" {}: {:.2} us ({} iterations)\n",
b.name, b.avg_time_us, b.iterations
));
}
}
s
}
pub fn print_failures(&self) -> String {
let mut s = String::new();
let failures: Vec<_> = self.results.iter().filter(|r| !r.passed).collect();
if failures.is_empty() {
s.push_str("No failures.\n");
} else {
s.push_str(&format!("{} failure(s):\n", failures.len()));
for f in &failures {
s.push_str(&format!(" FAIL: {}\n", f.name));
for msg in &f.messages {
s.push_str(&format!(" {}\n", msg));
}
}
}
s
}
pub fn reset(&mut self) {
self.results.clear();
self.bench_results.clear();
self.total_tests = 0;
self.total_passed = 0;
self.total_benchmarks = 0;
}
pub fn run_stdio_tests(&mut self) {
self.run_c_test(
"stdio_printf_int",
r#"
#include <stdio.h>
int main(void) {
printf("%d\n", 42);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_string",
r#"
#include <stdio.h>
int main(void) {
printf("%s\n", "hello");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_float",
r#"
#include <stdio.h>
int main(void) {
printf("%f\n", 3.14159);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_char",
r#"
#include <stdio.h>
int main(void) {
printf("%c\n", 'A');
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_hex",
r#"
#include <stdio.h>
int main(void) {
printf("%x\n", 255);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_octal",
r#"
#include <stdio.h>
int main(void) {
printf("%o\n", 64);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_pointer",
r#"
#include <stdio.h>
int main(void) {
int x = 0;
printf("%p\n", (void*)&x);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_unsigned",
r#"
#include <stdio.h>
int main(void) {
printf("%u\n", 12345u);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_long",
r#"
#include <stdio.h>
int main(void) {
printf("%ld\n", 123456789L);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_multiple",
r#"
#include <stdio.h>
int main(void) {
printf("%d %s %c\n", 10, "test", 'Z');
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_width",
r#"
#include <stdio.h>
int main(void) {
printf("%10d\n", 42);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_precision",
r#"
#include <stdio.h>
int main(void) {
printf("%.3f\n", 1.234567);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_zero_pad",
r#"
#include <stdio.h>
int main(void) {
printf("%05d\n", 7);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_left_align",
r#"
#include <stdio.h>
int main(void) {
printf("%-10s\n", "left");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_printf_plus_sign",
r#"
#include <stdio.h>
int main(void) {
printf("%+d\n", 42);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_scanf_int",
r#"
#include <stdio.h>
int main(void) {
int x;
scanf("%d", &x);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_scanf_float",
r#"
#include <stdio.h>
int main(void) {
float f;
scanf("%f", &f);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_scanf_string",
r#"
#include <stdio.h>
int main(void) {
char buf[64];
scanf("%s", buf);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_scanf_char",
r#"
#include <stdio.h>
int main(void) {
char c;
scanf(" %c", &c);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_scanf_multiple",
r#"
#include <stdio.h>
int main(void) {
int a, b;
scanf("%d %d", &a, &b);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fopen_read",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "r");
if (f) fclose(f);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fopen_write",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "w");
if (f) fclose(f);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fopen_append",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "a");
if (f) fclose(f);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fopen_binary",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "rb");
if (f) fclose(f);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fread",
r#"
#include <stdio.h>
int main(void) {
char buf[16];
FILE *f = fopen("/dev/zero", "rb");
if (f) {
fread(buf, 1, 16, f);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fwrite",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "wb");
if (f) {
fwrite("hello", 1, 5, f);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_sprintf",
r#"
#include <stdio.h>
int main(void) {
char buf[64];
sprintf(buf, "%d + %d = %d", 2, 3, 5);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_snprintf",
r#"
#include <stdio.h>
int main(void) {
char buf[16];
snprintf(buf, sizeof(buf), "hello %s", "world");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_snprintf_trunc",
r#"
#include <stdio.h>
int main(void) {
char buf[8];
int n = snprintf(buf, sizeof(buf), "hello world");
return (n > 8) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdio_fprintf",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "w");
if (f) {
fprintf(f, "value: %d\n", 42);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fscanf",
r#"
#include <stdio.h>
int main(void) {
int x;
FILE *f = fopen("/dev/null", "r");
if (f) {
fscanf(f, "%d", &x);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fgets",
r#"
#include <stdio.h>
int main(void) {
char buf[64];
FILE *f = fopen("/dev/null", "r");
if (f) {
fgets(buf, sizeof(buf), f);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fputs",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "w");
if (f) {
fputs("hello\n", f);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_getc",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "r");
if (f) {
int c = getc(f);
fclose(f);
(void)c;
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_putc",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "w");
if (f) {
putc('A', f);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_getchar",
r#"
#include <stdio.h>
int main(void) {
/* getchar() would block; just test compilation */
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_putchar",
r#"
#include <stdio.h>
int main(void) {
putchar('X');
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_puts",
r#"
#include <stdio.h>
int main(void) {
puts("hello world");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fseek",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "r");
if (f) {
fseek(f, 0, SEEK_SET);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fseek_end",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "r");
if (f) {
fseek(f, 0, SEEK_END);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fseek_cur",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "r");
if (f) {
fseek(f, 0, SEEK_CUR);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_ftell",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "r");
if (f) {
long pos = ftell(f);
(void)pos;
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fflush",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "w");
if (f) {
fflush(f);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_fflush_null",
r#"
#include <stdio.h>
int main(void) {
fflush(NULL);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_setbuf",
r#"
#include <stdio.h>
int main(void) {
char buf[BUFSIZ];
FILE *f = fopen("/dev/null", "w");
if (f) {
setbuf(f, buf);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_setvbuf_full",
r#"
#include <stdio.h>
int main(void) {
char buf[1024];
FILE *f = fopen("/dev/null", "w");
if (f) {
setvbuf(f, buf, _IOFBF, sizeof(buf));
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_setvbuf_line",
r#"
#include <stdio.h>
int main(void) {
char buf[1024];
FILE *f = fopen("/dev/null", "w");
if (f) {
setvbuf(f, buf, _IOLBF, sizeof(buf));
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_setvbuf_none",
r#"
#include <stdio.h>
int main(void) {
FILE *f = fopen("/dev/null", "w");
if (f) {
setvbuf(f, NULL, _IONBF, 0);
fclose(f);
}
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_remove",
r#"
#include <stdio.h>
int main(void) {
remove("/tmp/llvm_native_test_does_not_exist");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_rename",
r#"
#include <stdio.h>
int main(void) {
rename("/tmp/old_nonexistent", "/tmp/new_nonexistent");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_tmpfile",
r#"
#include <stdio.h>
int main(void) {
FILE *f = tmpfile();
if (f) fclose(f);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_tmpnam",
r#"
#include <stdio.h>
int main(void) {
char name[L_tmpnam];
tmpnam(name);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_stderr",
r#"
#include <stdio.h>
int main(void) {
fprintf(stderr, "error test\n");
return 0;
}
"#,
0,
);
self.run_c_test(
"stdio_perror",
r#"
#include <stdio.h>
#include <errno.h>
int main(void) {
errno = EINVAL;
perror("test");
return 0;
}
"#,
0,
);
}
pub fn run_stdlib_tests(&mut self) {
self.run_c_test(
"stdlib_malloc",
r#"
#include <stdlib.h>
int main(void) {
void *p = malloc(64);
if (p) free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_malloc_zero",
r#"
#include <stdlib.h>
int main(void) {
void *p = malloc(0);
free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_malloc_large",
r#"
#include <stdlib.h>
int main(void) {
void *p = malloc(1024 * 1024);
if (p) free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_free_null",
r#"
#include <stdlib.h>
int main(void) {
free(NULL);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_calloc",
r#"
#include <stdlib.h>
int main(void) {
int *p = calloc(10, sizeof(int));
if (p) free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_calloc_zero",
r#"
#include <stdlib.h>
int main(void) {
void *p = calloc(0, 1);
if (p) free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_realloc_grow",
r#"
#include <stdlib.h>
int main(void) {
void *p = malloc(32);
void *q = realloc(p, 64);
if (q) free(q);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_realloc_shrink",
r#"
#include <stdlib.h>
int main(void) {
void *p = malloc(64);
void *q = realloc(p, 32);
if (q) free(q);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_realloc_null",
r#"
#include <stdlib.h>
int main(void) {
void *p = realloc(NULL, 64);
if (p) free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_realloc_zero",
r#"
#include <stdlib.h>
int main(void) {
void *p = malloc(32);
void *q = realloc(p, 0);
free(q);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_aligned_alloc",
r#"
#include <stdlib.h>
int main(void) {
void *p = aligned_alloc(16, 64);
if (p) free(p);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_atoi",
r#"
#include <stdlib.h>
int main(void) {
int x = atoi("42");
return (x == 42) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_atoi_negative",
r#"
#include <stdlib.h>
int main(void) {
int x = atoi("-123");
return (x == -123) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_atol",
r#"
#include <stdlib.h>
int main(void) {
long x = atol("123456789");
return (x == 123456789L) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_atoll",
r#"
#include <stdlib.h>
int main(void) {
long long x = atoll("12345678901234");
return (x == 12345678901234LL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtol",
r#"
#include <stdlib.h>
int main(void) {
char *end;
long x = strtol(" 123abc", &end, 10);
return (x == 123 && *end == 'a') ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtol_hex",
r#"
#include <stdlib.h>
int main(void) {
char *end;
long x = strtol("0xff", &end, 0);
return (x == 255) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtoll",
r#"
#include <stdlib.h>
int main(void) {
char *end;
long long x = strtoll("999999999", NULL, 10);
return (x == 999999999LL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtoul",
r#"
#include <stdlib.h>
int main(void) {
char *end;
unsigned long x = strtoul("4294967295", NULL, 10);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtoull",
r#"
#include <stdlib.h>
int main(void) {
char *end;
unsigned long long x = strtoull("18446744073709551615", NULL, 10);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtod",
r#"
#include <stdlib.h>
int main(void) {
char *end;
double x = strtod("3.14159", &end);
return (x > 3.0 && x < 4.0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtof",
r#"
#include <stdlib.h>
int main(void) {
char *end;
float x = strtof("2.71828", &end);
return (x > 2.0f && x < 3.0f) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_strtold",
r#"
#include <stdlib.h>
int main(void) {
char *end;
long double x = strtold("1.414213562373095", &end);
return (x > 1.0L && x < 2.0L) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_rand",
r#"
#include <stdlib.h>
int main(void) {
int x = rand();
return (x >= 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_srand",
r#"
#include <stdlib.h>
int main(void) {
srand(42);
int x = rand();
return (x >= 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_qsort_int",
r#"
#include <stdlib.h>
int cmp(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main(void) {
int arr[] = {5, 2, 8, 1, 9};
qsort(arr, 5, sizeof(int), cmp);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_qsort_float",
r#"
#include <stdlib.h>
int cmp(const void *a, const void *b) {
float fa = *(float*)a, fb = *(float*)b;
return (fa > fb) - (fa < fb);
}
int main(void) {
float arr[] = {3.1f, 1.4f, 2.7f};
qsort(arr, 3, sizeof(float), cmp);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_bsearch",
r#"
#include <stdlib.h>
int cmp(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main(void) {
int arr[] = {1, 2, 3, 4, 5};
int key = 3;
int *found = bsearch(&key, arr, 5, sizeof(int), cmp);
return (found != NULL && *found == 3) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_bsearch_not_found",
r#"
#include <stdlib.h>
int cmp(const void *a, const void *b) {
return (*(int*)a - *(int*)b);
}
int main(void) {
int arr[] = {1, 2, 3, 4, 5};
int key = 99;
int *found = bsearch(&key, arr, 5, sizeof(int), cmp);
return (found == NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_abs_pos",
r#"
#include <stdlib.h>
int main(void) {
int x = abs(42);
return (x == 42) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_abs_neg",
r#"
#include <stdlib.h>
int main(void) {
int x = abs(-42);
return (x == 42) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_abs_zero",
r#"
#include <stdlib.h>
int main(void) {
int x = abs(0);
return (x == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_labs",
r#"
#include <stdlib.h>
int main(void) {
long x = labs(-123456789L);
return (x == 123456789L) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_llabs",
r#"
#include <stdlib.h>
int main(void) {
long long x = llabs(-12345678901234LL);
return (x == 12345678901234LL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_div",
r#"
#include <stdlib.h>
int main(void) {
div_t d = div(10, 3);
return (d.quot == 3 && d.rem == 1) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_div_negative",
r#"
#include <stdlib.h>
int main(void) {
div_t d = div(-10, 3);
return (d.quot == -3 && d.rem == -1) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_ldiv",
r#"
#include <stdlib.h>
int main(void) {
ldiv_t d = ldiv(100L, 7L);
return (d.quot == 14L && d.rem == 2L) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_lldiv",
r#"
#include <stdlib.h>
int main(void) {
lldiv_t d = lldiv(1000LL, 33LL);
return (d.quot == 30LL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_exit",
r#"
#include <stdlib.h>
int main(void) {
exit(0);
return 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_exit_failure",
r#"
#include <stdlib.h>
int main(void) {
exit(EXIT_FAILURE);
}
"#,
1,
);
self.run_c_test(
"stdlib_atexit",
r#"
#include <stdlib.h>
void cleanup(void) { }
int main(void) {
atexit(cleanup);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_at_quick_exit",
r#"
#include <stdlib.h>
void cleanup(void) { }
int main(void) {
at_quick_exit(cleanup);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_system",
r#"
#include <stdlib.h>
int main(void) {
int ret = system(NULL);
return 0;
}
"#,
0,
);
self.run_c_test(
"stdlib_getenv",
r#"
#include <stdlib.h>
int main(void) {
char *path = getenv("PATH");
return (path != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_getenv_nonexist",
r#"
#include <stdlib.h>
int main(void) {
char *v = getenv("LLVM_NATIVE_NO_SUCH_VAR_XYZ");
return (v == NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_setenv",
r#"
#include <stdlib.h>
int main(void) {
int r = setenv("LLVM_NATIVE_TEST_VAR", "test_value", 1);
return (r == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_unsetenv",
r#"
#include <stdlib.h>
int main(void) {
int r = unsetenv("LLVM_NATIVE_TEST_VAR");
return (r == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdlib_mb_cur_max",
r#"
#include <stdlib.h>
int main(void) {
int m = MB_CUR_MAX;
return (m >= 1) ? 0 : 1;
}
"#,
0,
);
}
pub fn run_string_tests(&mut self) {
self.run_c_test(
"string_memcpy",
r#"
#include <string.h>
int main(void) {
char src[] = "hello";
char dst[16];
memcpy(dst, src, 6);
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memcpy_large",
r#"
#include <string.h>
int main(void) {
char src[1024], dst[1024];
memset(src, 0xAA, sizeof(src));
memcpy(dst, src, sizeof(src));
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memmove",
r#"
#include <string.h>
int main(void) {
char buf[] = "abcdefghij";
memmove(buf + 2, buf, 5);
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memmove_overlap_back",
r#"
#include <string.h>
int main(void) {
char buf[] = "abcdefghij";
memmove(buf, buf + 2, 5);
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memset",
r#"
#include <string.h>
int main(void) {
char buf[64];
memset(buf, 0, sizeof(buf));
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memset_value",
r#"
#include <string.h>
int main(void) {
char buf[64];
memset(buf, 0xFF, sizeof(buf));
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memset_int",
r#"
#include <string.h>
int main(void) {
int arr[16];
memset(arr, 0, sizeof(arr));
return 0;
}
"#,
0,
);
self.run_c_test(
"string_memcmp_equal",
r#"
#include <string.h>
int main(void) {
char a[] = "test", b[] = "test";
return (memcmp(a, b, 4) == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_memcmp_diff",
r#"
#include <string.h>
int main(void) {
char a[] = "abc", b[] = "abd";
return (memcmp(a, b, 3) < 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_memcmp_zero",
r#"
#include <string.h>
int main(void) {
char a[] = "x", b[] = "y";
return (memcmp(a, b, 0) == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_memchr_found",
r#"
#include <string.h>
int main(void) {
char buf[] = "hello";
char *p = memchr(buf, 'e', 5);
return (p != NULL && *p == 'e') ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_memchr_not_found",
r#"
#include <string.h>
int main(void) {
char buf[] = "hello";
char *p = memchr(buf, 'z', 5);
return (p == NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcpy",
r#"
#include <string.h>
int main(void) {
char dst[16];
strcpy(dst, "hello");
return 0;
}
"#,
0,
);
self.run_c_test(
"string_strncpy",
r#"
#include <string.h>
int main(void) {
char dst[16];
strncpy(dst, "hello world", 5);
dst[5] = '\0';
return 0;
}
"#,
0,
);
self.run_c_test(
"string_strncpy_full",
r#"
#include <string.h>
int main(void) {
char dst[32];
strncpy(dst, "short", sizeof(dst));
return 0;
}
"#,
0,
);
self.run_c_test(
"string_strcat",
r#"
#include <string.h>
int main(void) {
char buf[32] = "hello ";
strcat(buf, "world");
return 0;
}
"#,
0,
);
self.run_c_test(
"string_strncat",
r#"
#include <string.h>
int main(void) {
char buf[32] = "hello ";
strncat(buf, "world!!!", 5);
return 0;
}
"#,
0,
);
self.run_c_test(
"string_strcmp_equal",
r#"
#include <string.h>
int main(void) {
return (strcmp("abc", "abc") == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcmp_less",
r#"
#include <string.h>
int main(void) {
return (strcmp("abc", "abd") < 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcmp_greater",
r#"
#include <string.h>
int main(void) {
return (strcmp("abd", "abc") > 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcmp_empty",
r#"
#include <string.h>
int main(void) {
return (strcmp("", "") == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strncmp",
r#"
#include <string.h>
int main(void) {
return (strncmp("abcde", "abcxy", 3) == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strncmp_zero",
r#"
#include <string.h>
int main(void) {
return (strncmp("x", "y", 0) == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcoll",
r#"
#include <string.h>
int main(void) {
int r = strcoll("abc", "abc");
return (r == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strxfrm",
r#"
#include <string.h>
int main(void) {
char dst[64];
size_t n = strxfrm(dst, "hello", sizeof(dst));
return (n == 5) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strlen",
r#"
#include <string.h>
int main(void) {
size_t n = strlen("hello");
return (n == 5) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strlen_empty",
r#"
#include <string.h>
int main(void) {
size_t n = strlen("");
return (n == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strlen_long",
r#"
#include <string.h>
int main(void) {
const char *s = "this is a longer string for testing";
size_t n = strlen(s);
return (n > 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strchr_found",
r#"
#include <string.h>
int main(void) {
const char *s = "hello";
const char *p = strchr(s, 'l');
return (p != NULL && *p == 'l') ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strchr_not_found",
r#"
#include <string.h>
int main(void) {
const char *p = strchr("hello", 'z');
return (p == NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strchr_null",
r#"
#include <string.h>
int main(void) {
const char *p = strchr("abc", '\0');
return (p != NULL && *p == '\0') ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strrchr",
r#"
#include <string.h>
int main(void) {
const char *s = "hello";
const char *p = strrchr(s, 'l');
return (p != NULL && p == s + 3) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strstr_found",
r#"
#include <string.h>
int main(void) {
const char *p = strstr("hello world", "world");
return (p != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strstr_not_found",
r#"
#include <string.h>
int main(void) {
const char *p = strstr("hello world", "xyz");
return (p == NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strstr_empty",
r#"
#include <string.h>
int main(void) {
const char *p = strstr("hello", "");
return (p != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strtok",
r#"
#include <string.h>
int main(void) {
char buf[] = "one,two,three";
char *tok = strtok(buf, ",");
int count = 0;
while (tok) { count++; tok = strtok(NULL, ","); }
return (count == 3) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strtok_space",
r#"
#include <string.h>
int main(void) {
char buf[] = "a b c";
char *tok = strtok(buf, " ");
return (tok != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strerror",
r#"
#include <string.h>
#include <errno.h>
int main(void) {
const char *msg = strerror(EINVAL);
return (msg != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strerror_zero",
r#"
#include <string.h>
int main(void) {
const char *msg = strerror(0);
return (msg != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strpbrk_found",
r#"
#include <string.h>
int main(void) {
const char *p = strpbrk("hello", "aeiou");
return (p != NULL && *p == 'e') ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strpbrk_not_found",
r#"
#include <string.h>
int main(void) {
const char *p = strpbrk("hello", "xyz");
return (p == NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strspn",
r#"
#include <string.h>
int main(void) {
size_t n = strspn("123abc", "0123456789");
return (n == 3) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strspn_zero",
r#"
#include <string.h>
int main(void) {
size_t n = strspn("abc123", "0123456789");
return (n == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcspn",
r#"
#include <string.h>
int main(void) {
size_t n = strcspn("abc123", "0123456789");
return (n == 3) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_strcspn_none",
r#"
#include <string.h>
int main(void) {
size_t n = strcspn("abc", "0123456789");
return (n == 3) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"string_memmove_no_overlap",
r#"
#include <string.h>
int main(void) {
char src[] = "source";
char dst[16];
memmove(dst, src, 7);
return 0;
}
"#,
0,
);
}
pub fn run_math_tests(&mut self) {
self.run_c_test(
"math_sin",
r#"
#include <math.h>
int main(void) {
double x = sin(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_sin_pi2",
r#"
#include <math.h>
int main(void) {
double x = sin(1.57079632679);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_cos",
r#"
#include <math.h>
int main(void) {
double x = cos(0.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_cos_pi",
r#"
#include <math.h>
int main(void) {
double x = cos(3.14159265359);
return (x >= -1.01 && x <= -0.99) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_tan",
r#"
#include <math.h>
int main(void) {
double x = tan(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_tan_pi4",
r#"
#include <math.h>
int main(void) {
double x = tan(0.785398163397);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_asin",
r#"
#include <math.h>
int main(void) {
double x = asin(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_asin_half",
r#"
#include <math.h>
int main(void) {
double x = asin(0.5);
return (x >= 0.5 && x <= 0.55) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_acos",
r#"
#include <math.h>
int main(void) {
double x = acos(1.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_acos_half",
r#"
#include <math.h>
int main(void) {
double x = acos(0.5);
return (x >= 1.0 && x <= 1.1) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_atan",
r#"
#include <math.h>
int main(void) {
double x = atan(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_atan_one",
r#"
#include <math.h>
int main(void) {
double x = atan(1.0);
return (x >= 0.78 && x <= 0.79) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_atan2",
r#"
#include <math.h>
int main(void) {
double x = atan2(1.0, 1.0);
return (x >= 0.78 && x <= 0.79) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_atan2_zero",
r#"
#include <math.h>
int main(void) {
double x = atan2(0.0, 1.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_sinh",
r#"
#include <math.h>
int main(void) {
double x = sinh(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_sinh_one",
r#"
#include <math.h>
int main(void) {
double x = sinh(1.0);
return (x >= 1.1 && x <= 1.2) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_cosh",
r#"
#include <math.h>
int main(void) {
double x = cosh(0.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_cosh_one",
r#"
#include <math.h>
int main(void) {
double x = cosh(1.0);
return (x >= 1.5 && x <= 1.55) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_tanh",
r#"
#include <math.h>
int main(void) {
double x = tanh(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_tanh_one",
r#"
#include <math.h>
int main(void) {
double x = tanh(1.0);
return (x >= 0.76 && x <= 0.77) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_exp",
r#"
#include <math.h>
int main(void) {
double x = exp(0.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_exp_one",
r#"
#include <math.h>
int main(void) {
double x = exp(1.0);
return (x >= 2.71 && x <= 2.72) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_exp2",
r#"
#include <math.h>
int main(void) {
double x = exp2(3.0);
return (x >= 7.99 && x <= 8.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_exp2_zero",
r#"
#include <math.h>
int main(void) {
double x = exp2(0.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_expm1",
r#"
#include <math.h>
int main(void) {
double x = expm1(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_expm1_one",
r#"
#include <math.h>
int main(void) {
double x = expm1(1.0);
return (x >= 1.71 && x <= 1.72) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log",
r#"
#include <math.h>
int main(void) {
double x = log(1.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log_e",
r#"
#include <math.h>
int main(void) {
double x = log(2.71828182846);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log2",
r#"
#include <math.h>
int main(void) {
double x = log2(8.0);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log2_one",
r#"
#include <math.h>
int main(void) {
double x = log2(1.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log10",
r#"
#include <math.h>
int main(void) {
double x = log10(100.0);
return (x >= 1.99 && x <= 2.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log10_one",
r#"
#include <math.h>
int main(void) {
double x = log10(1.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log1p",
r#"
#include <math.h>
int main(void) {
double x = log1p(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_log1p_e_minus1",
r#"
#include <math.h>
int main(void) {
double x = log1p(1.71828182846);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_pow",
r#"
#include <math.h>
int main(void) {
double x = pow(2.0, 3.0);
return (x >= 7.99 && x <= 8.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_pow_square",
r#"
#include <math.h>
int main(void) {
double x = pow(5.0, 2.0);
return (x >= 24.99 && x <= 25.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_pow_zero",
r#"
#include <math.h>
int main(void) {
double x = pow(2.0, 0.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_sqrt",
r#"
#include <math.h>
int main(void) {
double x = sqrt(16.0);
return (x >= 3.99 && x <= 4.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_sqrt_zero",
r#"
#include <math.h>
int main(void) {
double x = sqrt(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_sqrt_one",
r#"
#include <math.h>
int main(void) {
double x = sqrt(1.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_cbrt",
r#"
#include <math.h>
int main(void) {
double x = cbrt(27.0);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_cbrt_zero",
r#"
#include <math.h>
int main(void) {
double x = cbrt(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_hypot",
r#"
#include <math.h>
int main(void) {
double x = hypot(3.0, 4.0);
return (x >= 4.99 && x <= 5.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_hypot_zero",
r#"
#include <math.h>
int main(void) {
double x = hypot(0.0, 0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fabs",
r#"
#include <math.h>
int main(void) {
double x = fabs(-3.14);
return (x >= 3.13 && x <= 3.15) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fabs_pos",
r#"
#include <math.h>
int main(void) {
double x = fabs(3.14);
return (x >= 3.13 && x <= 3.15) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fabs_zero",
r#"
#include <math.h>
int main(void) {
double x = fabs(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fmod",
r#"
#include <math.h>
int main(void) {
double x = fmod(10.0, 3.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fmod_exact",
r#"
#include <math.h>
int main(void) {
double x = fmod(8.0, 2.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_remainder",
r#"
#include <math.h>
int main(void) {
double x = remainder(10.0, 3.0);
return (x > -2.0 && x < 2.0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_copysign",
r#"
#include <math.h>
int main(void) {
double x = copysign(1.0, -2.0);
return (x < 0.0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_copysign_pos",
r#"
#include <math.h>
int main(void) {
double x = copysign(-1.0, 2.0);
return (x > 0.0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_ceil",
r#"
#include <math.h>
int main(void) {
double x = ceil(3.14);
return (x >= 3.99 && x <= 4.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_ceil_neg",
r#"
#include <math.h>
int main(void) {
double x = ceil(-3.14);
return (x >= -3.01 && x <= -2.99) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_floor",
r#"
#include <math.h>
int main(void) {
double x = floor(3.99);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_floor_neg",
r#"
#include <math.h>
int main(void) {
double x = floor(-3.14);
return (x >= -4.01 && x <= -3.99) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_trunc",
r#"
#include <math.h>
int main(void) {
double x = trunc(3.99);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_trunc_neg",
r#"
#include <math.h>
int main(void) {
double x = trunc(-3.99);
return (x >= -3.01 && x <= -2.99) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_round",
r#"
#include <math.h>
int main(void) {
double x = round(3.5);
return (x >= 3.99 && x <= 4.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_round_half",
r#"
#include <math.h>
int main(void) {
double x = round(3.4);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_rint",
r#"
#include <math.h>
int main(void) {
double x = rint(3.5);
return (x >= 3.99 && x <= 4.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_nearbyint",
r#"
#include <math.h>
int main(void) {
double x = nearbyint(3.5);
return (x >= 3.99 && x <= 4.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fma",
r#"
#include <math.h>
int main(void) {
double x = fma(2.0, 3.0, 4.0);
return (x >= 9.99 && x <= 10.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fmin",
r#"
#include <math.h>
int main(void) {
double x = fmin(3.0, 5.0);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fmax",
r#"
#include <math.h>
int main(void) {
double x = fmax(3.0, 5.0);
return (x >= 4.99 && x <= 5.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fdim",
r#"
#include <math.h>
int main(void) {
double x = fdim(5.0, 2.0);
return (x >= 2.99 && x <= 3.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_fdim_neg",
r#"
#include <math.h>
int main(void) {
double x = fdim(2.0, 5.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_erf",
r#"
#include <math.h>
int main(void) {
double x = erf(0.0);
return (x >= -0.001 && x <= 0.001) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_erf_half",
r#"
#include <math.h>
int main(void) {
double x = erf(0.5);
return (x >= 0.52 && x <= 0.53) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_erfc",
r#"
#include <math.h>
int main(void) {
double x = erfc(0.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_erfc_half",
r#"
#include <math.h>
int main(void) {
double x = erfc(0.5);
return (x >= 0.47 && x <= 0.48) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_tgamma",
r#"
#include <math.h>
int main(void) {
double x = tgamma(5.0);
return (x >= 23.99 && x <= 24.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_tgamma_one",
r#"
#include <math.h>
int main(void) {
double x = tgamma(1.0);
return (x >= 0.99 && x <= 1.01) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_lgamma",
r#"
#include <math.h>
int main(void) {
double x = lgamma(5.0);
return (x >= 3.17 && x <= 3.18) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"math_constants",
r#"
#include <math.h>
int main(void) {
double inf = INFINITY;
double nan = NAN;
double huge = HUGE_VAL;
(void)inf; (void)nan; (void)huge;
return 0;
}
"#,
0,
);
}
pub fn run_time_tests(&mut self) {
self.run_c_test(
"time_time",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
return (t > 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_time_ptr",
r#"
#include <time.h>
int main(void) {
time_t t1, t2;
t1 = time(&t2);
return (t1 == t2) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_clock",
r#"
#include <time.h>
int main(void) {
clock_t c = clock();
(void)c;
return 0;
}
"#,
0,
);
self.run_c_test(
"time_difftime",
r#"
#include <time.h>
int main(void) {
time_t t1 = 1000, t2 = 2000;
double diff = difftime(t2, t1);
return (diff == 1000.0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_difftime_neg",
r#"
#include <time.h>
int main(void) {
time_t t1 = 2000, t2 = 1000;
double diff = difftime(t2, t1);
return (diff == -1000.0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_mktime",
r#"
#include <time.h>
int main(void) {
struct tm t = {0};
t.tm_year = 2020 - 1900;
t.tm_mon = 0;
t.tm_mday = 1;
t.tm_hour = 12;
t.tm_min = 0;
t.tm_sec = 0;
time_t result = mktime(&t);
return (result > 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_localtime",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
return (lt != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_gmtime",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
struct tm *gt = gmtime(&t);
return (gt != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_strftime",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
char buf[64];
size_t n = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", lt);
return (n > 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_strftime_short",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
char buf[64];
strftime(buf, sizeof(buf), "%c", lt);
return 0;
}
"#,
0,
);
self.run_c_test(
"time_asctime",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
char *s = asctime(lt);
return (s != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_ctime",
r#"
#include <time.h>
int main(void) {
time_t t = time(NULL);
char *s = ctime(&t);
return (s != NULL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"time_types",
r#"
#include <time.h>
int main(void) {
time_t t = 0;
clock_t c = 0;
struct tm tm_val = {0};
(void)t; (void)c; (void)tm_val;
return 0;
}
"#,
0,
);
}
pub fn run_ctype_tests(&mut self) {
self.run_c_test(
"ctype_isalpha_upper",
r#"
#include <ctype.h>
int main(void) { return isalpha('A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isalpha_lower",
r#"
#include <ctype.h>
int main(void) { return isalpha('z') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isalpha_digit",
r#"
#include <ctype.h>
int main(void) { return !isalpha('5') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isdigit",
r#"
#include <ctype.h>
int main(void) { return isdigit('7') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isdigit_letter",
r#"
#include <ctype.h>
int main(void) { return !isdigit('A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isalnum_letter",
r#"
#include <ctype.h>
int main(void) { return isalnum('B') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isalnum_digit",
r#"
#include <ctype.h>
int main(void) { return isalnum('3') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isalnum_punct",
r#"
#include <ctype.h>
int main(void) { return !isalnum('!') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isspace",
r#"
#include <ctype.h>
int main(void) { return isspace(' ') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isspace_tab",
r#"
#include <ctype.h>
int main(void) { return isspace('\t') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isspace_newline",
r#"
#include <ctype.h>
int main(void) { return isspace('\n') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isspace_letter",
r#"
#include <ctype.h>
int main(void) { return !isspace('a') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isupper",
r#"
#include <ctype.h>
int main(void) { return isupper('Z') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isupper_lower",
r#"
#include <ctype.h>
int main(void) { return !isupper('a') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_islower",
r#"
#include <ctype.h>
int main(void) { return islower('a') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_islower_upper",
r#"
#include <ctype.h>
int main(void) { return !islower('Z') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_iscntrl",
r#"
#include <ctype.h>
int main(void) { return iscntrl('\0') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_iscntrl_letter",
r#"
#include <ctype.h>
int main(void) { return !iscntrl('A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isprint",
r#"
#include <ctype.h>
int main(void) { return isprint('A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isprint_control",
r#"
#include <ctype.h>
int main(void) { return !isprint('\0') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isgraph",
r#"
#include <ctype.h>
int main(void) { return isgraph('A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isgraph_space",
r#"
#include <ctype.h>
int main(void) { return !isgraph(' ') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_ispunct",
r#"
#include <ctype.h>
int main(void) { return ispunct('!') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_ispunct_letter",
r#"
#include <ctype.h>
int main(void) { return !ispunct('A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isxdigit_digit",
r#"
#include <ctype.h>
int main(void) { return isxdigit('9') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isxdigit_hex",
r#"
#include <ctype.h>
int main(void) { return isxdigit('F') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isxdigit_lower",
r#"
#include <ctype.h>
int main(void) { return isxdigit('a') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_isxdigit_not",
r#"
#include <ctype.h>
int main(void) { return !isxdigit('G') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_toupper",
r#"
#include <ctype.h>
int main(void) { return (toupper('a') == 'A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_toupper_upper",
r#"
#include <ctype.h>
int main(void) { return (toupper('A') == 'A') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_tolower",
r#"
#include <ctype.h>
int main(void) { return (tolower('Z') == 'z') ? 0 : 1; }
"#,
0,
);
self.run_c_test(
"ctype_tolower_lower",
r#"
#include <ctype.h>
int main(void) { return (tolower('z') == 'z') ? 0 : 1; }
"#,
0,
);
}
pub fn run_errno_tests(&mut self) {
self.run_c_test(
"errno_set",
r#"
#include <errno.h>
int main(void) {
errno = EINVAL;
return (errno == EINVAL) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"errno_edom",
r#"
#include <errno.h>
int main(void) {
errno = EDOM;
return (errno == EDOM) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"errno_erange",
r#"
#include <errno.h>
int main(void) {
errno = ERANGE;
return (errno == ERANGE) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"errno_zero",
r#"
#include <errno.h>
int main(void) {
errno = 0;
return (errno == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"errno_enomem",
r#"
#include <errno.h>
int main(void) {
errno = ENOMEM;
return (errno == ENOMEM) ? 0 : 1;
}
"#,
0,
);
}
pub fn run_assert_tests(&mut self) {
self.run_c_test(
"assert_true",
r#"
#include <assert.h>
int main(void) {
assert(1 == 1);
return 0;
}
"#,
0,
);
self.run_c_test(
"assert_nonzero",
r#"
#include <assert.h>
int main(void) {
int x = 42;
assert(x);
return 0;
}
"#,
0,
);
self.run_c_test(
"assert_ptr_nonnull",
r#"
#include <assert.h>
int main(void) {
int x = 0;
void *p = &x;
assert(p != NULL);
return 0;
}
"#,
0,
);
self.run_c_test(
"assert_static",
r#"
#include <assert.h>
int main(void) {
static_assert(sizeof(int) >= 4, "int too small");
return 0;
}
"#,
0,
);
self.run_c_test(
"ndebug",
r#"
#define NDEBUG
#include <assert.h>
int main(void) {
assert(0);
return 0;
}
"#,
0,
);
}
pub fn run_signal_tests(&mut self) {
self.run_c_test(
"signal_handler",
r#"
#include <signal.h>
void handler(int sig) { (void)sig; }
int main(void) {
signal(SIGINT, handler);
return 0;
}
"#,
0,
);
self.run_c_test(
"signal_sig_ign",
r#"
#include <signal.h>
int main(void) {
signal(SIGTERM, SIG_IGN);
return 0;
}
"#,
0,
);
self.run_c_test(
"signal_sig_dfl",
r#"
#include <signal.h>
int main(void) {
signal(SIGTERM, SIG_DFL);
return 0;
}
"#,
0,
);
self.run_c_test(
"raise_sigusr1",
r#"
#include <signal.h>
void handler(int sig) { (void)sig; }
int main(void) {
signal(SIGUSR1, handler);
raise(SIGUSR1);
return 0;
}
"#,
0,
);
self.run_c_test(
"signal_sig_err",
r#"
#include <signal.h>
int main(void) {
void *h = signal(SIGKILL, SIG_IGN);
return (h == SIG_ERR) ? 0 : 1;
}
"#,
0,
);
}
pub fn run_setjmp_tests(&mut self) {
self.run_c_test(
"setjmp_longjmp",
r#"
#include <setjmp.h>
#include <stdio.h>
jmp_buf buf;
void second(void) { longjmp(buf, 1); }
int main(void) {
if (setjmp(buf)) {
return 0;
}
second();
return 1;
}
"#,
0,
);
self.run_c_test(
"setjmp_direct",
r#"
#include <setjmp.h>
jmp_buf buf;
int main(void) {
int val = setjmp(buf);
return (val == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"sigsetjmp",
r#"
#include <setjmp.h>
#include <signal.h>
sigjmp_buf buf;
int main(void) {
int val = sigsetjmp(buf, 1);
return (val == 0) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"setjmp_nested",
r#"
#include <setjmp.h>
jmp_buf buf1, buf2;
void inner(void) {
if (setjmp(buf2) == 0)
longjmp(buf1, 1);
}
int main(void) {
if (setjmp(buf1)) return 0;
inner();
return 1;
}
"#,
0,
);
}
pub fn run_stdarg_tests(&mut self) {
self.run_c_test(
"stdarg_sum",
r#"
#include <stdarg.h>
int sum(int count, ...) {
va_list args;
va_start(args, count);
int total = 0;
for (int i = 0; i < count; i++)
total += va_arg(args, int);
va_end(args);
return total;
}
int main(void) {
int r = sum(3, 1, 2, 3);
return (r == 6) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdarg_mixed",
r#"
#include <stdarg.h>
double avg(int count, ...) {
va_list args;
va_start(args, count);
double sum = 0.0;
for (int i = 0; i < count; i++)
sum += va_arg(args, double);
va_end(args);
return sum / count;
}
int main(void) {
double r = avg(3, 1.0, 2.0, 3.0);
return (r >= 1.9 && r <= 2.1) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdarg_copy",
r#"
#include <stdarg.h>
int first(int count, ...) {
va_list args;
va_start(args, count);
int r = va_arg(args, int);
va_end(args);
return r;
}
int main(void) {
int r = first(3, 42, 99, 100);
return (r == 42) ? 0 : 1;
}
"#,
0,
);
self.run_c_test(
"stdarg_format",
r#"
#include <stdarg.h>
#include <stdio.h>
void my_printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
int main(void) {
my_printf("test: %d\n", 42);
return 0;
}
"#,
0,
);
}
pub fn run_iostream_tests(&mut self) {
self.run_cpp_test(
"iostream_cout",
r#"
#include <iostream>
int main() {
std::cout << "hello" << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_cout_int",
r#"
#include <iostream>
int main() {
std::cout << 42 << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_cout_float",
r#"
#include <iostream>
int main() {
std::cout << 3.14 << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_cout_multiple",
r#"
#include <iostream>
int main() {
std::cout << "x = " << 10 << ", y = " << 20.5 << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_cin",
r#"
#include <iostream>
int main() {
int x;
std::cin >> x;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_cin_string",
r#"
#include <iostream>
#include <string>
int main() {
std::string s;
std::cin >> s;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_cerr",
r#"
#include <iostream>
int main() {
std::cerr << "error message" << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_clog",
r#"
#include <iostream>
int main() {
std::clog << "log message" << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_stringstream",
r#"
#include <sstream>
#include <string>
int main() {
std::stringstream ss;
ss << "value: " << 42;
std::string s = ss.str();
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_istringstream",
r#"
#include <sstream>
#include <string>
int main() {
std::istringstream iss("42 3.14 hello");
int i; double d; std::string s;
iss >> i >> d >> s;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_ostringstream",
r#"
#include <sstream>
int main() {
std::ostringstream oss;
oss << "test " << 123;
std::string result = oss.str();
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_manip_hex",
r#"
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::hex << 255 << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_manip_setw",
r#"
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setw(10) << 42 << std::endl;
return 0;
}
"#,
);
self.run_cpp_test(
"iostream_manip_setprecision",
r#"
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::setprecision(3) << 3.14159 << std::endl;
return 0;
}
"#,
);
}
pub fn run_cpp_string_tests(&mut self) {
self.run_cpp_test(
"string_default_ctor",
r#"
#include <string>
int main() {
std::string s;
return 0;
}
"#,
);
self.run_cpp_test(
"string_cstr_ctor",
r#"
#include <string>
int main() {
std::string s("hello");
return (s == "hello") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_copy_ctor",
r#"
#include <string>
int main() {
std::string a("test");
std::string b(a);
return (b == "test") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_move_ctor",
r#"
#include <string>
#include <utility>
int main() {
std::string a("move");
std::string b(std::move(a));
return (b == "move") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_assign",
r#"
#include <string>
int main() {
std::string s;
s = "assigned";
return (s == "assigned") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_append",
r#"
#include <string>
int main() {
std::string s = "hello";
s += " world";
return (s == "hello world") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_size",
r#"
#include <string>
int main() {
std::string s = "hello";
return (s.size() == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_length",
r#"
#include <string>
int main() {
std::string s = "test";
return (s.length() == 4) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_empty",
r#"
#include <string>
int main() {
std::string s;
return s.empty() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_clear",
r#"
#include <string>
int main() {
std::string s = "nonempty";
s.clear();
return s.empty() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_find",
r#"
#include <string>
int main() {
std::string s = "hello world";
size_t pos = s.find("world");
return (pos == 6) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_find_not",
r#"
#include <string>
int main() {
std::string s = "hello";
size_t pos = s.find("xyz");
return (pos == std::string::npos) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_substr",
r#"
#include <string>
int main() {
std::string s = "hello world";
std::string sub = s.substr(0, 5);
return (sub == "hello") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_substr_tail",
r#"
#include <string>
int main() {
std::string s = "hello world";
std::string sub = s.substr(6);
return (sub == "world") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_compare",
r#"
#include <string>
int main() {
std::string a = "abc";
int r = a.compare("abd");
return (r < 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_compare_equal",
r#"
#include <string>
int main() {
std::string a = "same";
int r = a.compare("same");
return (r == 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_replace",
r#"
#include <string>
int main() {
std::string s = "hello world";
s.replace(6, 5, "there");
return (s == "hello there") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_at",
r#"
#include <string>
int main() {
std::string s = "abc";
return (s.at(1) == 'b') ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_iterators",
r#"
#include <string>
#include <algorithm>
int main() {
std::string s = "hello";
int count = 0;
for (auto c : s) { count++; }
return (count == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_reserve",
r#"
#include <string>
int main() {
std::string s;
s.reserve(128);
return (s.capacity() >= 128) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_c_str",
r#"
#include <string>
#include <cstring>
int main() {
std::string s = "test";
const char *c = s.c_str();
return (std::strcmp(c, "test") == 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_data",
r#"
#include <string>
int main() {
std::string s = "data";
const char *d = s.data();
return (d[0] == 'd') ? 0 : 1;
}
"#,
);
}
pub fn run_vector_tests(&mut self) {
self.run_cpp_test(
"vector_default",
r#"
#include <vector>
int main() {
std::vector<int> v;
return v.empty() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_push_back",
r#"
#include <vector>
int main() {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
return (v.size() == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_emplace_back",
r#"
#include <vector>
#include <string>
int main() {
std::vector<std::string> v;
v.emplace_back("hello");
return (v.size() == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_reserve",
r#"
#include <vector>
int main() {
std::vector<int> v;
v.reserve(100);
return (v.capacity() >= 100) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_at",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
return (v.at(0) == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_front_back",
r#"
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30};
return (v.front() == 10 && v.back() == 30) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_data",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
int *p = v.data();
return (p[1] == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_iterator",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
int sum = 0;
for (auto it = v.begin(); it != v.end(); ++it)
sum += *it;
return (sum == 15) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_range_for",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
int sum = 0;
for (int x : v) sum += x;
return (sum == 6) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_clear",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
v.clear();
return v.empty() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_pop_back",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
v.pop_back();
return (v.size() == 2 && v.back() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_insert",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 3};
v.insert(v.begin() + 1, 2);
return (v[1] == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_erase",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
v.erase(v.begin() + 1);
return (v.size() == 2 && v[1] == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_resize",
r#"
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
v.resize(5, 42);
return (v.size() == 5 && v[4] == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_initializer_list",
r#"
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30, 40, 50};
return (v.size() == 5 && v[2] == 30) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_swap",
r#"
#include <vector>
int main() {
std::vector<int> a = {1, 2};
std::vector<int> b = {3, 4, 5};
a.swap(b);
return (a.size() == 3 && b.size() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"vector_bool",
r#"
#include <vector>
int main() {
std::vector<bool> v = {true, false, true};
return (v[0] && !v[1] && v[2]) ? 0 : 1;
}
"#,
);
}
pub fn run_map_set_tests(&mut self) {
self.run_cpp_test(
"map_insert",
r#"
#include <map>
#include <string>
int main() {
std::map<std::string, int> m;
m["apple"] = 5;
m["banana"] = 3;
return (m.size() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_find",
r#"
#include <map>
int main() {
std::map<int, int> m = {{1, 10}, {2, 20}};
auto it = m.find(1);
return (it != m.end() && it->second == 10) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_find_not",
r#"
#include <map>
int main() {
std::map<int, int> m = {{1, 10}};
auto it = m.find(99);
return (it == m.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_erase",
r#"
#include <map>
int main() {
std::map<int, int> m = {{1, 10}, {2, 20}};
m.erase(1);
return (m.size() == 1 && m.find(1) == m.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_iterate",
r#"
#include <map>
int main() {
std::map<int, int> m = {{3, 30}, {1, 10}, {2, 20}};
int sum = 0;
for (auto &p : m) sum += p.first;
return (sum == 6) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_contains",
r#"
#include <map>
int main() {
std::map<int, int> m = {{1, 10}};
return m.contains(1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_lower_bound",
r#"
#include <map>
int main() {
std::map<int, int> m = {{10, 1}, {20, 2}, {30, 3}};
auto it = m.lower_bound(15);
return (it->first == 20) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_upper_bound",
r#"
#include <map>
int main() {
std::map<int, int> m = {{10, 1}, {20, 2}, {30, 3}};
auto it = m.upper_bound(20);
return (it->first == 30) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"map_emplace",
r#"
#include <map>
#include <string>
int main() {
std::map<int, std::string> m;
m.emplace(1, "one");
return (m[1] == "one") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"set_insert",
r#"
#include <set>
int main() {
std::set<int> s;
s.insert(5);
s.insert(3);
s.insert(7);
return (s.size() == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"set_duplicate",
r#"
#include <set>
int main() {
std::set<int> s = {1, 2, 2, 3};
return (s.size() == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"set_find",
r#"
#include <set>
int main() {
std::set<int> s = {1, 2, 3};
auto it = s.find(2);
return (it != s.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"set_erase",
r#"
#include <set>
int main() {
std::set<int> s = {1, 2, 3};
s.erase(2);
return (s.size() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"set_iterate",
r#"
#include <set>
int main() {
std::set<int> s = {3, 1, 2};
int prev = 0;
for (int x : s) {
if (x <= prev) return 1;
prev = x;
}
return 0;
}
"#,
);
self.run_cpp_test(
"multiset_duplicate",
r#"
#include <set>
int main() {
std::multiset<int> ms = {1, 2, 2, 3};
return (ms.size() == 4) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"multimap_duplicate",
r#"
#include <map>
int main() {
std::multimap<int, int> mm;
mm.insert({1, 10});
mm.insert({1, 20});
return (mm.size() == 2) ? 0 : 1;
}
"#,
);
}
pub fn run_unordered_tests(&mut self) {
self.run_cpp_test(
"unordered_map_insert",
r#"
#include <unordered_map>
#include <string>
int main() {
std::unordered_map<std::string, int> um;
um["apple"] = 5;
um["banana"] = 3;
return (um.size() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_map_find",
r#"
#include <unordered_map>
int main() {
std::unordered_map<int, int> um = {{1, 10}, {2, 20}};
auto it = um.find(1);
return (it != um.end() && it->second == 10) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_map_erase",
r#"
#include <unordered_map>
int main() {
std::unordered_map<int, int> um = {{1, 10}, {2, 20}};
um.erase(1);
return (um.size() == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_map_bucket",
r#"
#include <unordered_map>
int main() {
std::unordered_map<int, int> um = {{1, 10}};
size_t bc = um.bucket_count();
return (bc > 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_map_rehash",
r#"
#include <unordered_map>
int main() {
std::unordered_map<int, int> um;
um.rehash(64);
return (um.bucket_count() >= 64) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_set_insert",
r#"
#include <unordered_set>
int main() {
std::unordered_set<int> us;
us.insert(5);
us.insert(3);
us.insert(7);
return (us.size() == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_set_find",
r#"
#include <unordered_set>
int main() {
std::unordered_set<int> us = {1, 2, 3};
auto it = us.find(2);
return (it != us.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"unordered_set_erase",
r#"
#include <unordered_set>
int main() {
std::unordered_set<int> us = {1, 2, 3};
us.erase(2);
return (us.size() == 2) ? 0 : 1;
}
"#,
);
}
pub fn run_algorithm_tests(&mut self) {
self.run_cpp_test(
"algorithm_sort",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {5, 2, 8, 1, 9};
std::sort(v.begin(), v.end());
return (v[0] == 1 && v[4] == 9) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_sort_desc",
r#"
#include <algorithm>
#include <vector>
#include <functional>
int main() {
std::vector<int> v = {5, 2, 8, 1, 9};
std::sort(v.begin(), v.end(), std::greater<int>());
return (v[0] == 9 && v[4] == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_stable_sort",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {3, 1, 2, 1, 3};
std::stable_sort(v.begin(), v.end());
return (v[0] == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_find",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3);
return (it != v.end() && *it == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_find_not",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
auto it = std::find(v.begin(), v.end(), 99);
return (it == v.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_binary_search",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
return std::binary_search(v.begin(), v.end(), 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_binary_search_fail",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
return !std::binary_search(v.begin(), v.end(), 99) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_lower_bound",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30, 40};
auto it = std::lower_bound(v.begin(), v.end(), 25);
return (*it == 30) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_upper_bound",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30, 40};
auto it = std::upper_bound(v.begin(), v.end(), 20);
return (*it == 30) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_copy",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> src = {1, 2, 3, 4, 5};
std::vector<int> dst(5);
std::copy(src.begin(), src.end(), dst.begin());
return (dst[2] == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_transform",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
std::transform(v.begin(), v.end(), v.begin(),
[](int x) { return x * 2; });
return (v[0] == 2 && v[2] == 6) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_for_each",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
int sum = 0;
std::for_each(v.begin(), v.end(), [&sum](int x) { sum += x; });
return (sum == 6) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_count",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 2, 2, 3};
int cnt = std::count(v.begin(), v.end(), 2);
return (cnt == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_count_if",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
int cnt = std::count_if(v.begin(), v.end(),
[](int x) { return x % 2 == 0; });
return (cnt == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_min_max",
r#"
#include <algorithm>
int main() {
int a = 10, b = 20;
int mn = std::min(a, b);
int mx = std::max(a, b);
return (mn == 10 && mx == 20) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_swap",
r#"
#include <algorithm>
int main() {
int a = 1, b = 2;
std::swap(a, b);
return (a == 2 && b == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_reverse",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::reverse(v.begin(), v.end());
return (v[0] == 5 && v[4] == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_unique",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 1, 2, 2, 3};
auto it = std::unique(v.begin(), v.end());
v.erase(it, v.end());
return (v.size() == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_fill",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v(5);
std::fill(v.begin(), v.end(), 42);
return (v[3] == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_generate",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v(5);
int n = 0;
std::generate(v.begin(), v.end(), [&n]() { return n++; });
return (v[2] == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_is_sorted",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
return std::is_sorted(v.begin(), v.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_partial_sort",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {9, 2, 7, 1, 5};
std::partial_sort(v.begin(), v.begin() + 3, v.end());
return (v[0] == 1 && v[1] == 2 && v[2] == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_nth_element",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {9, 2, 7, 1, 5, 3, 8};
std::nth_element(v.begin(), v.begin() + 3, v.end());
return (v[3] == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_merge",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> a = {1, 3, 5}, b = {2, 4, 6};
std::vector<int> out(6);
std::merge(a.begin(), a.end(), b.begin(), b.end(), out.begin());
return (out[2] == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_includes",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> a = {1, 2, 3, 4, 5}, b = {2, 3, 4};
return std::includes(a.begin(), a.end(), b.begin(), b.end()) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_set_union",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> a = {1, 2, 3}, b = {3, 4, 5};
std::vector<int> out(5);
auto it = std::set_union(a.begin(), a.end(), b.begin(), b.end(), out.begin());
return (it - out.begin() == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_set_intersection",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> a = {1, 2, 3, 4}, b = {3, 4, 5, 6};
std::vector<int> out(2);
auto it = std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), out.begin());
return (it - out.begin() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_heap_make",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {3, 1, 4, 1, 5, 9};
std::make_heap(v.begin(), v.end());
return (v.front() == 9) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"algorithm_heap_push_pop",
r#"
#include <algorithm>
#include <vector>
int main() {
std::vector<int> v = {3, 1, 4};
std::make_heap(v.begin(), v.end());
v.push_back(10);
std::push_heap(v.begin(), v.end());
std::pop_heap(v.begin(), v.end());
int max = v.back();
v.pop_back();
return (max == 10) ? 0 : 1;
}
"#,
);
}
pub fn run_memory_tests(&mut self) {
self.run_cpp_test(
"memory_unique_ptr",
r#"
#include <memory>
int main() {
auto p = std::make_unique<int>(42);
return (*p == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_unique_ptr_array",
r#"
#include <memory>
int main() {
auto p = std::make_unique<int[]>(5);
p[0] = 10;
return (p[0] == 10) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_unique_ptr_move",
r#"
#include <memory>
#include <utility>
int main() {
auto p1 = std::make_unique<int>(100);
auto p2 = std::move(p1);
return (p1 == nullptr && *p2 == 100) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_unique_ptr_release",
r#"
#include <memory>
int main() {
auto p = std::make_unique<int>(42);
int *raw = p.release();
int val = *raw;
delete raw;
return (val == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_shared_ptr",
r#"
#include <memory>
int main() {
auto p = std::make_shared<int>(42);
return (*p == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_shared_ptr_copy",
r#"
#include <memory>
int main() {
auto p1 = std::make_shared<int>(10);
auto p2 = p1;
return (p1.use_count() == 2 && *p2 == 10) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_shared_ptr_reset",
r#"
#include <memory>
int main() {
auto p = std::make_shared<int>(42);
p.reset();
return (p == nullptr) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_shared_ptr_use_count",
r#"
#include <memory>
int main() {
auto p1 = std::make_shared<int>(5);
auto p2 = p1;
auto p3 = p1;
return (p1.use_count() == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_weak_ptr",
r#"
#include <memory>
int main() {
auto shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared;
return (weak.use_count() == 1) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_weak_ptr_lock",
r#"
#include <memory>
int main() {
auto shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared;
if (auto locked = weak.lock()) {
return (*locked == 42) ? 0 : 1;
}
return 1;
}
"#,
);
self.run_cpp_test(
"memory_weak_ptr_expired",
r#"
#include <memory>
int main() {
std::weak_ptr<int> weak;
{
auto shared = std::make_shared<int>(42);
weak = shared;
}
return weak.expired() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"memory_allocator",
r#"
#include <memory>
#include <vector>
int main() {
std::allocator<int> alloc;
int *p = alloc.allocate(5);
alloc.deallocate(p, 5);
return 0;
}
"#,
);
self.run_cpp_test(
"memory_allocator_construct",
r#"
#include <memory>
int main() {
std::allocator<int> alloc;
int *p = alloc.allocate(1);
alloc.construct(p, 42);
int val = *p;
alloc.destroy(p);
alloc.deallocate(p, 1);
return (val == 42) ? 0 : 1;
}
"#,
);
}
pub fn run_thread_tests(&mut self) {
self.run_cpp_test(
"thread_create_join",
r#"
#include <thread>
void work() {}
int main() {
std::thread t(work);
t.join();
return 0;
}
"#,
);
self.run_cpp_test(
"thread_lambda",
r#"
#include <thread>
int main() {
int result = 0;
std::thread t([&result]() { result = 42; });
t.join();
return (result == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"thread_move",
r#"
#include <thread>
#include <utility>
void work() {}
int main() {
std::thread t1(work);
std::thread t2 = std::move(t1);
t2.join();
return 0;
}
"#,
);
self.run_cpp_test(
"thread_hardware_concurrency",
r#"
#include <thread>
int main() {
unsigned int n = std::thread::hardware_concurrency();
return (n > 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"mutex_lock_unlock",
r#"
#include <mutex>
int main() {
std::mutex m;
m.lock();
m.unlock();
return 0;
}
"#,
);
self.run_cpp_test(
"mutex_lock_guard",
r#"
#include <mutex>
int main() {
std::mutex m;
{
std::lock_guard<std::mutex> lock(m);
}
return 0;
}
"#,
);
self.run_cpp_test(
"mutex_unique_lock",
r#"
#include <mutex>
int main() {
std::mutex m;
std::unique_lock<std::mutex> lock(m);
lock.unlock();
lock.lock();
return 0;
}
"#,
);
self.run_cpp_test(
"mutex_try_lock",
r#"
#include <mutex>
int main() {
std::mutex m;
if (m.try_lock()) {
m.unlock();
}
return 0;
}
"#,
);
self.run_cpp_test(
"mutex_recursive",
r#"
#include <mutex>
int main() {
std::recursive_mutex m;
m.lock();
m.lock();
m.unlock();
m.unlock();
return 0;
}
"#,
);
self.run_cpp_test(
"mutex_timed",
r#"
#include <mutex>
#include <chrono>
int main() {
std::timed_mutex m;
m.lock();
auto ok = m.try_lock_for(std::chrono::milliseconds(10));
if (!ok) {
m.unlock();
return 0;
}
return 1;
}
"#,
);
self.run_cpp_test(
"condition_variable",
r#"
#include <condition_variable>
#include <mutex>
#include <thread>
int main() {
std::mutex m;
std::condition_variable cv;
bool ready = false;
std::thread t([&]() {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&ready] { return ready; });
});
{
std::lock_guard<std::mutex> lock(m);
ready = true;
}
cv.notify_one();
t.join();
return 0;
}
"#,
);
self.run_cpp_test(
"condition_variable_any",
r#"
#include <condition_variable>
#include <mutex>
int main() {
std::mutex m;
std::condition_variable_any cv;
std::unique_lock<std::mutex> lock(m);
return 0;
}
"#,
);
self.run_cpp_test(
"future_async",
r#"
#include <future>
int compute() { return 42; }
int main() {
auto fut = std::async(std::launch::async, compute);
int result = fut.get();
return (result == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"future_deferred",
r#"
#include <future>
int compute() { return 99; }
int main() {
auto fut = std::async(std::launch::deferred, compute);
return (fut.get() == 99) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"future_promise",
r#"
#include <future>
#include <thread>
int main() {
std::promise<int> prom;
auto fut = prom.get_future();
std::thread t([&prom]() { prom.set_value(42); });
int result = fut.get();
t.join();
return (result == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"future_packaged_task",
r#"
#include <future>
int add(int a, int b) { return a + b; }
int main() {
std::packaged_task<int(int,int)> task(add);
auto fut = task.get_future();
task(2, 3);
return (fut.get() == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"future_wait_for",
r#"
#include <future>
#include <chrono>
int main() {
std::promise<int> prom;
auto fut = prom.get_future();
auto status = fut.wait_for(std::chrono::milliseconds(1));
return (status == std::future_status::timeout) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"future_shared_future",
r#"
#include <future>
int main() {
std::promise<int> prom;
std::shared_future<int> sf = prom.get_future().share();
prom.set_value(10);
return (sf.get() == 10) ? 0 : 1;
}
"#,
);
}
pub fn run_atomic_tests(&mut self) {
self.run_cpp_test(
"atomic_int",
r#"
#include <atomic>
int main() {
std::atomic<int> a(42);
return (a.load() == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_store_load",
r#"
#include <atomic>
int main() {
std::atomic<int> a(0);
a.store(100);
return (a.load() == 100) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_exchange",
r#"
#include <atomic>
int main() {
std::atomic<int> a(10);
int old = a.exchange(20);
return (old == 10 && a.load() == 20) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_compare_exchange_strong",
r#"
#include <atomic>
int main() {
std::atomic<int> a(10);
int expected = 10;
bool ok = a.compare_exchange_strong(expected, 20);
return (ok && a.load() == 20) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_compare_exchange_weak",
r#"
#include <atomic>
int main() {
std::atomic<int> a(10);
int expected = 10;
while (!a.compare_exchange_weak(expected, 20)) {
expected = 10;
}
return (a.load() == 20) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_fetch_add",
r#"
#include <atomic>
int main() {
std::atomic<int> a(5);
int old = a.fetch_add(3);
return (old == 5 && a.load() == 8) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_fetch_sub",
r#"
#include <atomic>
int main() {
std::atomic<int> a(10);
a.fetch_sub(3);
return (a.load() == 7) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_fetch_and",
r#"
#include <atomic>
int main() {
std::atomic<int> a(0xFF);
a.fetch_and(0x0F);
return (a.load() == 0x0F) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_fetch_or",
r#"
#include <atomic>
int main() {
std::atomic<int> a(0x0F);
a.fetch_or(0xF0);
return (a.load() == 0xFF) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_fetch_xor",
r#"
#include <atomic>
int main() {
std::atomic<int> a(0xFF);
a.fetch_xor(0x0F);
return (a.load() == 0xF0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_bool",
r#"
#include <atomic>
int main() {
std::atomic<bool> flag(false);
flag.store(true);
return flag.load() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_pointer",
r#"
#include <atomic>
int main() {
int x = 42;
std::atomic<int*> p(&x);
return (*p.load() == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_is_lock_free",
r#"
#include <atomic>
int main() {
std::atomic<int> a;
bool lf = a.is_lock_free();
return lf ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"atomic_flag",
r#"
#include <atomic>
int main() {
std::atomic_flag f = ATOMIC_FLAG_INIT;
if (!f.test_and_set()) {
f.clear();
}
return 0;
}
"#,
);
self.run_cpp_test(
"atomic_memory_order",
r#"
#include <atomic>
int main() {
std::atomic<int> a(0);
a.store(1, std::memory_order_release);
int v = a.load(std::memory_order_acquire);
return (v == 1) ? 0 : 1;
}
"#,
);
}
pub fn run_functional_tests(&mut self) {
self.run_cpp_test(
"functional_function",
r#"
#include <functional>
int add(int a, int b) { return a + b; }
int main() {
std::function<int(int,int)> f = add;
return (f(2, 3) == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_lambda",
r#"
#include <functional>
int main() {
std::function<int(int)> f = [](int x) { return x * 2; };
return (f(21) == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_bind",
r#"
#include <functional>
int add(int a, int b) { return a + b; }
int main() {
auto f = std::bind(add, std::placeholders::_1, 10);
return (f(5) == 15) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_bind_member",
r#"
#include <functional>
#include <string>
int main() {
std::string s = "hello";
auto f = std::bind(&std::string::size, std::placeholders::_1);
return (f(s) == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_ref",
r#"
#include <functional>
int main() {
int x = 42;
std::reference_wrapper<int> r(x);
r.get() = 100;
return (x == 100) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_hash",
r#"
#include <functional>
int main() {
std::hash<int> h;
size_t hv = h(42);
return (hv > 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_hash_string",
r#"
#include <functional>
#include <string>
int main() {
std::hash<std::string> h;
size_t a = h("hello");
size_t b = h("hello");
return (a == b) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_negate",
r#"
#include <functional>
int main() {
std::negate<int> neg;
return (neg(42) == -42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_plus",
r#"
#include <functional>
int main() {
std::plus<int> p;
return (p(2, 3) == 5) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"functional_less",
r#"
#include <functional>
int main() {
std::less<int> lt;
return (lt(1, 2)) ? 0 : 1;
}
"#,
);
}
pub fn run_type_traits_tests(&mut self) {
self.run_cpp_test(
"type_traits_is_integral",
r#"
#include <type_traits>
int main() {
static_assert(std::is_integral<int>::value, "int should be integral");
static_assert(!std::is_integral<float>::value, "float should not be integral");
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_floating_point",
r#"
#include <type_traits>
int main() {
static_assert(std::is_floating_point<double>::value);
static_assert(!std::is_floating_point<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_same",
r#"
#include <type_traits>
int main() {
static_assert(std::is_same<int, int>::value);
static_assert(!std::is_same<int, float>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_pointer",
r#"
#include <type_traits>
int main() {
static_assert(std::is_pointer<int*>::value);
static_assert(!std::is_pointer<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_const",
r#"
#include <type_traits>
int main() {
static_assert(std::is_const<const int>::value);
static_assert(!std::is_const<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_volatile",
r#"
#include <type_traits>
int main() {
static_assert(std::is_volatile<volatile int>::value);
static_assert(!std::is_volatile<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_array",
r#"
#include <type_traits>
int main() {
static_assert(std::is_array<int[]>::value);
static_assert(std::is_array<int[5]>::value);
static_assert(!std::is_array<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_signed",
r#"
#include <type_traits>
int main() {
static_assert(std::is_signed<int>::value);
static_assert(!std::is_signed<unsigned int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_unsigned",
r#"
#include <type_traits>
int main() {
static_assert(std::is_unsigned<unsigned int>::value);
static_assert(!std::is_unsigned<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_enum",
r#"
#include <type_traits>
enum Color { Red, Green, Blue };
int main() {
static_assert(std::is_enum<Color>::value);
static_assert(!std::is_enum<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_class",
r#"
#include <type_traits>
struct S {};
int main() {
static_assert(std::is_class<S>::value);
static_assert(!std::is_class<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_abstract",
r#"
#include <type_traits>
struct Abstract { virtual void f() = 0; };
struct Concrete {};
int main() {
static_assert(std::is_abstract<Abstract>::value);
static_assert(!std::is_abstract<Concrete>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_base_of",
r#"
#include <type_traits>
struct Base {};
struct Derived : Base {};
int main() {
static_assert(std::is_base_of<Base, Derived>::value);
static_assert(!std::is_base_of<Derived, Base>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_conditional",
r#"
#include <type_traits>
int main() {
using T = std::conditional<true, int, float>::type;
static_assert(std::is_same<T, int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_decay",
r#"
#include <type_traits>
int main() {
static_assert(std::is_same<std::decay_t<int[]>, int*>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_remove_const",
r#"
#include <type_traits>
int main() {
static_assert(std::is_same<std::remove_const_t<const int>, int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_add_pointer",
r#"
#include <type_traits>
int main() {
static_assert(std::is_same<std::add_pointer_t<int>, int*>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_underlying_type",
r#"
#include <type_traits>
enum class Color : int { Red, Green, Blue };
int main() {
static_assert(std::is_same<std::underlying_type_t<Color>, int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_trivially_copyable",
r#"
#include <type_traits>
int main() {
static_assert(std::is_trivially_copyable<int>::value);
return 0;
}
"#,
);
self.run_cpp_test(
"type_traits_is_move_constructible",
r#"
#include <type_traits>
int main() {
static_assert(std::is_move_constructible<int>::value);
return 0;
}
"#,
);
}
pub fn run_modern_cpp_tests(&mut self) {
self.run_cpp_test(
"optional_has_value",
r#"
#include <optional>
int main() {
std::optional<int> opt = 42;
return opt.has_value() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"optional_nullopt",
r#"
#include <optional>
int main() {
std::optional<int> opt = std::nullopt;
return !opt.has_value() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"optional_value",
r#"
#include <optional>
int main() {
std::optional<int> opt = 42;
return (opt.value() == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"optional_value_or",
r#"
#include <optional>
int main() {
std::optional<int> opt = std::nullopt;
int val = opt.value_or(99);
return (val == 99) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"optional_deref",
r#"
#include <optional>
int main() {
std::optional<int> opt = 42;
return (*opt == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"optional_emplace",
r#"
#include <optional>
#include <string>
int main() {
std::optional<std::string> opt;
opt.emplace("hello");
return (opt.value() == "hello") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"optional_reset",
r#"
#include <optional>
int main() {
std::optional<int> opt = 42;
opt.reset();
return !opt.has_value() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"variant_basic",
r#"
#include <variant>
int main() {
std::variant<int, float, std::string> v = 42;
return (std::get<int>(v) == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"variant_holds_alternative",
r#"
#include <variant>
int main() {
std::variant<int, float> v = 3.14f;
return std::holds_alternative<float>(v) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"variant_get_if",
r#"
#include <variant>
int main() {
std::variant<int, float> v = 42;
if (int *p = std::get_if<int>(&v)) {
return (*p == 42) ? 0 : 1;
}
return 1;
}
"#,
);
self.run_cpp_test(
"variant_visit",
r#"
#include <variant>
int main() {
std::variant<int, float> v = 3.14f;
auto result = std::visit([](auto &&arg) -> int {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>) return arg;
else return 0;
}, v);
return 0;
}
"#,
);
self.run_cpp_test(
"variant_index",
r#"
#include <variant>
int main() {
std::variant<int, float, char> v = 'A';
return (v.index() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"any_basic",
r#"
#include <any>
int main() {
std::any a = 42;
return std::any_cast<int>(a) == 42 ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"any_has_value",
r#"
#include <any>
int main() {
std::any a;
return !a.has_value() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"any_type",
r#"
#include <any>
#include <string>
int main() {
std::any a = std::string("hello");
return (a.type() == typeid(std::string)) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"any_reset",
r#"
#include <any>
int main() {
std::any a = 42;
a.reset();
return !a.has_value() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"any_make_any",
r#"
#include <any>
int main() {
auto a = std::make_any<int>(42);
return (std::any_cast<int>(a) == 42) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_default",
r#"
#include <string_view>
int main() {
std::string_view sv;
return sv.empty() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_from_cstr",
r#"
#include <string_view>
int main() {
std::string_view sv = "hello";
return (sv.size() == 5 && sv[0] == 'h') ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_from_string",
r#"
#include <string>
#include <string_view>
int main() {
std::string s = "hello";
std::string_view sv(s);
return (sv == "hello") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_substr",
r#"
#include <string_view>
int main() {
std::string_view sv = "hello world";
std::string_view sub = sv.substr(6);
return (sub == "world") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_find",
r#"
#include <string_view>
int main() {
std::string_view sv = "hello world";
return (sv.find("world") == 6) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_compare",
r#"
#include <string_view>
int main() {
std::string_view a = "abc";
std::string_view b = "abd";
return (a.compare(b) < 0) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_remove_prefix",
r#"
#include <string_view>
int main() {
std::string_view sv = "hello world";
sv.remove_prefix(6);
return (sv == "world") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"string_view_remove_suffix",
r#"
#include <string_view>
int main() {
std::string_view sv = "hello world";
sv.remove_suffix(6);
return (sv == "hello") ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"span_from_array",
r#"
#include <span>
int main() {
int arr[] = {1, 2, 3, 4, 5};
std::span<int> s(arr);
return (s.size() == 5 && s[2] == 3) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"span_from_vector",
r#"
#include <span>
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30};
std::span<int> s(v);
return (s.size() == 3 && s[1] == 20) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"span_subspan",
r#"
#include <span>
int main() {
int arr[] = {1, 2, 3, 4, 5};
std::span<int> s(arr);
auto sub = s.subspan(1, 3);
return (sub.size() == 3 && sub[0] == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"span_first_last",
r#"
#include <span>
int main() {
int arr[] = {1, 2, 3, 4, 5};
std::span<int> s(arr);
auto first = s.first(3);
auto last = s.last(2);
return (first.size() == 3 && last.size() == 2) ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"span_empty",
r#"
#include <span>
int main() {
std::span<int> s;
return s.empty() ? 0 : 1;
}
"#,
);
self.run_cpp_test(
"span_bytes",
r#"
#include <span>
int main() {
int arr[] = {0x01020304};
std::span<const std::byte> s(
reinterpret_cast<const std::byte*>(arr), sizeof(arr));
return (s.size() == sizeof(arr)) ? 0 : 1;
}
"#,
);
}
fn bench_malloc_free(&mut self) {
let mut result = X86StdLibBenchResult {
name: "malloc_free_throughput".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let sizes = [16, 32, 64, 128, 256, 512, 1024, 4096, 16384, 65536];
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations {
let start = Instant::now();
for &size in &sizes {
let _ = std::hint::black_box(size);
}
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
}
let avg = total_time.as_micros() as f64 / result.iterations as f64;
result.avg_time_us = avg;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
fn bench_memcpy(&mut self) {
let cases = vec![
("memcpy_small_aligned", 64, true),
("memcpy_small_unaligned", 63, false),
("memcpy_medium_aligned", 4096, true),
("memcpy_large_aligned", 1048576, true),
("memcpy_large_unaligned", 1048575, false),
];
for (name, size, _aligned) in cases {
let mut result = X86StdLibBenchResult {
name: name.into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let src = vec![0xAAu8; size];
let mut dst = vec![0u8; size];
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations {
let start = Instant::now();
dst.copy_from_slice(&src);
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
result.total_bytes += size as u64;
let us = elapsed.as_micros() as f64;
if us < result.min_time_us {
result.min_time_us = us;
}
if us > result.max_time_us {
result.max_time_us = us;
}
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
}
fn bench_string_ops(&mut self) {
let test_str = "The quick brown fox jumps over the lazy dog. ";
let long_str = test_str.repeat(100);
{
let mut result = X86StdLibBenchResult {
name: "strlen_bench".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations * 10 {
let start = Instant::now();
let _ = std::hint::black_box(long_str.len());
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
{
let mut result = X86StdLibBenchResult {
name: "strcmp_bench".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let other = long_str.clone();
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations * 10 {
let start = Instant::now();
let _ = std::hint::black_box(long_str == other);
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
}
fn bench_sort_perf(&mut self) {
{
let mut rng = X86RngState::new(12345);
let mut result = X86StdLibBenchResult {
name: "sort_random".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations {
let mut data: Vec<i32> = (0..10000).map(|_| rng.next_i32()).collect();
let start = Instant::now();
data.sort_unstable();
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
result.total_bytes += 40000;
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
{
let mut result = X86StdLibBenchResult {
name: "sort_sorted".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations {
let mut data: Vec<i32> = (0..10000).collect();
let start = Instant::now();
data.sort_unstable();
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
result.total_bytes += 40000;
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
{
let mut result = X86StdLibBenchResult {
name: "sort_reverse".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations {
let mut data: Vec<i32> = (0..10000).rev().collect();
let start = Instant::now();
data.sort_unstable();
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
result.total_bytes += 40000;
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
{
let mut rng = X86RngState::new(54321);
let mut result = X86StdLibBenchResult {
name: "sort_small".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
let mut total_time = Duration::ZERO;
for _ in 0..self.bench_iterations * 10 {
let mut data: Vec<i32> = (0..32).map(|_| rng.next_i32()).collect();
let start = Instant::now();
data.sort_unstable();
let elapsed = start.elapsed();
total_time += elapsed;
result.iterations += 1;
result.total_bytes += 128;
}
result.avg_time_us = total_time.as_micros() as f64 / result.iterations as f64;
self.total_benchmarks += 1;
self.bench_results.push(result);
}
}
}
impl Default for X86StdLibTest {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for X86StdLibTest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"X86StdLibTest(target={}, std={:?}, opt={:?}, tests={}, passed={})",
self.target_triple,
self.c_standard,
self.opt_level,
self.total_tests,
self.total_passed
)
}
}
#[derive(Debug, Clone)]
pub struct X86StdLibBenchmark {
pub name: String,
pub iterations: u32,
pub verbose: bool,
pub measurements: Vec<(f64, u64)>,
pub warmup_iterations: u32,
pub target_triple: String,
pub opt_level: X86OptLevel,
}
impl X86StdLibBenchmark {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
iterations: 100,
verbose: false,
measurements: Vec::new(),
warmup_iterations: 5,
target_triple: "x86_64-unknown-linux-gnu".into(),
opt_level: X86OptLevel::O2,
}
}
pub fn with_iterations(mut self, n: u32) -> Self {
self.iterations = n;
self
}
pub fn with_verbose(mut self, v: bool) -> Self {
self.verbose = v;
self
}
pub fn with_warmup(mut self, n: u32) -> Self {
self.warmup_iterations = n;
self
}
pub fn with_target(mut self, triple: &str) -> Self {
self.target_triple = triple.to_string();
self
}
pub fn with_opt_level(mut self, level: X86OptLevel) -> Self {
self.opt_level = level;
self
}
pub fn add_measurement(&mut self, time_us: f64, bytes: u64) {
self.measurements.push((time_us, bytes));
}
pub fn measure<F>(&mut self, mut f: F, name: &str, bytes_per_iter: u64)
where
F: FnMut(),
{
if self.verbose {
eprintln!("Benchmark [{}]: warming up...", name);
}
for _ in 0..self.warmup_iterations {
f();
}
if self.verbose {
eprintln!(
"Benchmark [{}]: measuring {} iterations...",
name, self.iterations
);
}
let start = Instant::now();
for _ in 0..self.iterations {
f();
}
let elapsed = start.elapsed();
let avg_us = elapsed.as_micros() as f64 / self.iterations as f64;
let total_bytes = bytes_per_iter * self.iterations as u64;
self.add_measurement(avg_us, total_bytes);
if self.verbose {
eprintln!(
"Benchmark [{}]: {:.2} us/iter, {} bytes processed",
name, avg_us, total_bytes
);
}
}
pub fn average_time_us(&self) -> f64 {
if self.measurements.is_empty() {
return 0.0;
}
let sum: f64 = self.measurements.iter().map(|(t, _)| *t).sum();
sum / self.measurements.len() as f64
}
pub fn min_time_us(&self) -> f64 {
self.measurements
.iter()
.map(|(t, _)| *t)
.fold(f64::MAX, f64::min)
}
pub fn max_time_us(&self) -> f64 {
self.measurements
.iter()
.map(|(t, _)| *t)
.fold(0.0, f64::max)
}
pub fn total_bytes_processed(&self) -> u64 {
self.measurements.iter().map(|(_, b)| *b).sum()
}
pub fn throughput_bytes_per_us(&self) -> f64 {
if self.measurements.is_empty() {
return 0.0;
}
let total_bytes = self.total_bytes_processed() as f64;
let total_time: f64 = self.measurements.iter().map(|(t, _)| *t).sum();
if total_time == 0.0 {
return 0.0;
}
total_bytes / total_time
}
pub fn is_faster_than(&self, other: &X86StdLibBenchmark) -> bool {
let self_avg = self.average_time_us();
let other_avg = other.average_time_us();
if self_avg == 0.0 || other_avg == 0.0 {
return false;
}
self_avg < other_avg
}
pub fn reset(&mut self) {
self.measurements.clear();
}
pub fn report(&self) -> String {
let avg = self.average_time_us();
let min = self.min_time_us();
let max = self.max_time_us();
let total_bytes = self.total_bytes_processed();
let tp = self.throughput_bytes_per_us();
if self.measurements.is_empty() {
return format!(
"Benchmark '{}': 0 measurements (target={})",
self.name, self.target_triple
);
}
format!(
"Benchmark '{}': avg={:.2} us, min={:.2} us, max={:.2} us, \
bytes={}, throughput={:.2} B/us, measurements={}",
self.name,
avg,
min,
max,
total_bytes,
tp,
self.measurements.len()
)
}
}
impl Default for X86StdLibBenchmark {
fn default() -> Self {
Self::new("default")
}
}
impl fmt::Display for X86StdLibBenchmark {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let avg = self.average_time_us();
write!(
f,
"X86StdLibBenchmark(name={}, avg={:.2} us, measurements={})",
self.name,
avg,
self.measurements.len()
)
}
}
#[derive(Debug, Clone)]
pub struct X86StdLibTestResult {
pub name: String,
pub category: X86StdLibCategory,
pub passed: bool,
pub compiled: bool,
pub exit_code: Option<i32>,
pub duration: Duration,
pub messages: Vec<String>,
pub ir_output: Option<String>,
pub asm_output: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum X86StdLibCategory {
CLibrary,
CppLibrary,
Benchmark,
Misc,
}
impl fmt::Display for X86StdLibCategory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
X86StdLibCategory::CLibrary => write!(f, "C Library"),
X86StdLibCategory::CppLibrary => write!(f, "C++ Library"),
X86StdLibCategory::Benchmark => write!(f, "Benchmark"),
X86StdLibCategory::Misc => write!(f, "Miscellaneous"),
}
}
}
#[derive(Debug, Clone)]
pub struct X86StdLibBenchResult {
pub name: String,
pub category: X86StdLibCategory,
pub avg_time_us: f64,
pub min_time_us: f64,
pub max_time_us: f64,
pub iterations: u64,
pub total_bytes: u64,
}
#[derive(Debug, Clone)]
pub struct X86RngState {
state: u64,
}
impl X86RngState {
pub fn new(seed: u64) -> Self {
Self { state: seed }
}
fn next_u64(&mut self) -> u64 {
self.state = self
.state
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
self.state ^= self.state >> 33;
self.state
}
fn next_u32(&mut self) -> u32 {
(self.next_u64() >> 32) as u32
}
pub fn next_i32(&mut self) -> i32 {
self.next_u32() as i32
}
}
pub fn build_and_run_x86_stdlib_suite() -> X86StdLibTest {
let mut tester = X86StdLibTest::new();
tester.run_stdio_tests();
tester.run_stdlib_tests();
tester.run_string_tests();
tester.run_math_tests();
tester.run_time_tests();
tester.run_ctype_tests();
tester.run_errno_tests();
tester.run_assert_tests();
tester.run_signal_tests();
tester.run_setjmp_tests();
tester.run_stdarg_tests();
tester.run_iostream_tests();
tester.run_cpp_string_tests();
tester.run_vector_tests();
tester.run_map_set_tests();
tester.run_unordered_tests();
tester.run_algorithm_tests();
tester.run_memory_tests();
tester.run_thread_tests();
tester.run_atomic_tests();
tester.run_functional_tests();
tester.run_type_traits_tests();
tester.run_modern_cpp_tests();
tester
}
pub fn build_and_run_x86_stdlib_suite_with_benchmarks() -> X86StdLibTest {
let mut tester = build_and_run_x86_stdlib_suite();
tester = tester.with_benchmarks(true).with_bench_iterations(50);
tester.run_all_benchmarks();
tester
}
pub fn build_x86_32_stdlib_suite() -> X86StdLibTest {
let mut tester = X86StdLibTest::new_x86_32();
tester.run_all_c_tests();
tester.run_all_cpp_tests();
tester
}
pub fn build_windows_x86_64_stdlib_suite() -> X86StdLibTest {
let mut tester = X86StdLibTest::new_windows_x86_64();
tester.run_all_c_tests();
tester
}
pub fn c_test_count() -> usize {
let mut tester = X86StdLibTest::new();
tester.run_all_c_tests();
tester.total_tests as usize
}
pub fn cpp_test_count() -> usize {
let mut tester = X86StdLibTest::new();
tester.run_all_cpp_tests();
tester.total_tests as usize
}
pub fn total_test_count() -> usize {
c_test_count() + cpp_test_count()
}
pub fn verify_ir_contains(ir: &str, patterns: &[&str]) -> (bool, Vec<String>) {
let mut all_found = true;
let mut missing = Vec::new();
for &pattern in patterns {
if !ir.contains(pattern) {
all_found = false;
missing.push(pattern.to_string());
}
}
(all_found, missing)
}
pub fn verify_ir_excludes(ir: &str, patterns: &[&str]) -> (bool, Vec<String>) {
let mut all_clean = true;
let mut found = Vec::new();
for &pattern in patterns {
if ir.contains(pattern) {
all_clean = false;
found.push(pattern.to_string());
}
}
(all_clean, found)
}
pub fn stdio_printf_format_source() -> &'static str {
r#"
#include <stdio.h>
int main(void) {
printf("int: %d, float: %f, str: %s\n", 42, 3.14, "hello");
return 0;
}
"#
}
pub fn stdlib_alloc_stress_source() -> &'static str {
r#"
#include <stdlib.h>
int main(void) {
for (int i = 0; i < 1000; i++) {
void *p = malloc(1024);
if (p) free(p);
}
return 0;
}
"#
}
pub fn string_combined_source() -> &'static str {
r#"
#include <string.h>
#include <stdio.h>
int main(void) {
char buf[128];
strcpy(buf, "hello");
strcat(buf, " world");
size_t len = strlen(buf);
printf("len=%zu, contains hello=%d\n", len, strstr(buf, "hello") != NULL);
return 0;
}
"#
}
pub fn math_combined_source() -> &'static str {
r#"
#include <math.h>
#include <stdio.h>
int main(void) {
double x = sin(1.0) * sin(1.0) + cos(1.0) * cos(1.0);
printf("sin^2 + cos^2 = %f\n", x);
return 0;
}
"#
}
pub fn vector_combined_source() -> &'static str {
r#"
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> v = {5, 3, 8, 1, 2};
std::sort(v.begin(), v.end());
for (int x : v) std::cout << x << " ";
return 0;
}
"#
}
pub fn smart_ptr_combined_source() -> &'static str {
r#"
#include <memory>
#include <iostream>
int main() {
auto shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared;
if (auto locked = weak.lock()) {
std::cout << *locked << std::endl;
}
return 0;
}
"#
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_x86_stdlib_test_new() {
let t = X86StdLibTest::new();
assert_eq!(t.target_triple, "x86_64-unknown-linux-gnu");
assert_eq!(t.total_tests, 0);
assert_eq!(t.total_passed, 0);
}
#[test]
fn test_x86_stdlib_test_new_x86_32() {
let t = X86StdLibTest::new_x86_32();
assert_eq!(t.target_triple, "i686-unknown-linux-gnu");
}
#[test]
fn test_x86_stdlib_test_new_windows() {
let t = X86StdLibTest::new_windows_x86_64();
assert_eq!(t.target_triple, "x86_64-pc-windows-msvc");
}
#[test]
fn test_x86_stdlib_test_pass_rate_empty() {
let t = X86StdLibTest::new();
assert_eq!(t.pass_rate(), 100.0);
}
#[test]
fn test_x86_stdlib_test_all_passed_empty() {
let t = X86StdLibTest::new();
assert!(!t.all_passed());
}
#[test]
fn test_x86_stdlib_test_with_opt_level() {
let t = X86StdLibTest::new().with_opt_level(X86OptLevel::O3);
assert_eq!(t.opt_level, X86OptLevel::O3);
}
#[test]
fn test_x86_stdlib_test_with_ir_verification() {
let t = X86StdLibTest::new().with_ir_verification(false);
assert!(!t.verify_ir);
}
#[test]
fn test_x86_stdlib_test_with_benchmarks() {
let t = X86StdLibTest::new().with_benchmarks(true);
assert!(t.run_benchmarks);
}
#[test]
fn test_x86_stdlib_test_with_flag() {
let t = X86StdLibTest::new().with_flag("-DDEBUG");
assert!(t.extra_flags.contains(&"-DDEBUG".to_string()));
}
#[test]
fn test_x86_stdlib_test_with_include_dir() {
let t = X86StdLibTest::new().with_include_dir("/usr/include");
assert!(t.include_dirs.contains(&"/usr/include".to_string()));
}
#[test]
fn test_x86_stdlib_test_with_link_lib() {
let t = X86StdLibTest::new().with_link_lib("m");
assert!(t.link_libs.contains(&"m".to_string()));
}
#[test]
fn test_x86_stdlib_test_reset() {
let mut t = X86StdLibTest::new();
t.total_tests = 100;
t.total_passed = 50;
t.results.push(X86StdLibTestResult {
name: "test".into(),
category: X86StdLibCategory::CLibrary,
passed: true,
compiled: true,
exit_code: None,
duration: Duration::ZERO,
messages: vec![],
ir_output: None,
asm_output: None,
});
t.reset();
assert_eq!(t.total_tests, 0);
assert_eq!(t.total_passed, 0);
assert!(t.results.is_empty());
}
#[test]
fn test_x86_stdlib_test_display() {
let t = X86StdLibTest::new();
let s = format!("{}", t);
assert!(s.contains("X86StdLibTest"));
assert!(s.contains("x86_64"));
}
#[test]
fn test_x86_stdlib_test_bench_iterations() {
let t = X86StdLibTest::new().with_bench_iterations(500);
assert_eq!(t.bench_iterations, 500);
}
#[test]
fn test_category_display_c() {
assert_eq!(format!("{}", X86StdLibCategory::CLibrary), "C Library");
}
#[test]
fn test_category_display_cpp() {
assert_eq!(format!("{}", X86StdLibCategory::CppLibrary), "C++ Library");
}
#[test]
fn test_category_display_bench() {
assert_eq!(format!("{}", X86StdLibCategory::Benchmark), "Benchmark");
}
#[test]
fn test_category_display_misc() {
assert_eq!(format!("{}", X86StdLibCategory::Misc), "Miscellaneous");
}
#[test]
fn test_category_ordering() {
let mut cats = vec![
X86StdLibCategory::Benchmark,
X86StdLibCategory::CLibrary,
X86StdLibCategory::Misc,
X86StdLibCategory::CppLibrary,
];
cats.sort();
assert_eq!(cats[0], X86StdLibCategory::Benchmark);
assert_eq!(cats[1], X86StdLibCategory::CLibrary);
assert_eq!(cats[2], X86StdLibCategory::CppLibrary);
assert_eq!(cats[3], X86StdLibCategory::Misc);
}
#[test]
fn test_c_test_count_positive() {
let count = c_test_count();
assert!(count > 0, "C test count should be positive, got {}", count);
}
#[test]
fn test_cpp_test_count_positive() {
let count = cpp_test_count();
assert!(
count > 0,
"C++ test count should be positive, got {}",
count
);
}
#[test]
fn test_total_test_count() {
let total = total_test_count();
let c = c_test_count();
let cpp = cpp_test_count();
assert_eq!(total, c + cpp);
}
#[test]
fn test_total_test_count_exceeds_180() {
let total = total_test_count();
assert!(total >= 180, "Expected at least 180 tests, got {}", total);
}
#[test]
fn test_stdio_test_count() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.total_tests >= 25, "Expected at least 25 stdio tests");
}
#[test]
fn test_stdlib_test_count() {
let mut t = X86StdLibTest::new();
t.run_stdlib_tests();
assert!(t.total_tests >= 25, "Expected at least 25 stdlib tests");
}
#[test]
fn test_string_test_count() {
let mut t = X86StdLibTest::new();
t.run_string_tests();
assert!(t.total_tests >= 20, "Expected at least 20 string tests");
}
#[test]
fn test_math_test_count() {
let mut t = X86StdLibTest::new();
t.run_math_tests();
assert!(t.total_tests >= 35, "Expected at least 35 math tests");
}
#[test]
fn test_time_test_count() {
let mut t = X86StdLibTest::new();
t.run_time_tests();
assert!(t.total_tests >= 10, "Expected at least 10 time tests");
}
#[test]
fn test_ctype_test_count() {
let mut t = X86StdLibTest::new();
t.run_ctype_tests();
assert!(t.total_tests >= 20, "Expected at least 20 ctype tests");
}
#[test]
fn test_errno_test_count() {
let mut t = X86StdLibTest::new();
t.run_errno_tests();
assert_eq!(t.total_tests, 5);
}
#[test]
fn test_assert_test_count() {
let mut t = X86StdLibTest::new();
t.run_assert_tests();
assert_eq!(t.total_tests, 5);
}
#[test]
fn test_signal_test_count() {
let mut t = X86StdLibTest::new();
t.run_signal_tests();
assert_eq!(t.total_tests, 5);
}
#[test]
fn test_setjmp_test_count() {
let mut t = X86StdLibTest::new();
t.run_setjmp_tests();
assert_eq!(t.total_tests, 4);
}
#[test]
fn test_stdarg_test_count() {
let mut t = X86StdLibTest::new();
t.run_stdarg_tests();
assert_eq!(t.total_tests, 4);
}
#[test]
fn test_all_c_tests_complete() {
let mut t = X86StdLibTest::new();
t.run_all_c_tests();
assert!(
t.total_tests >= 100,
"Expected 100+ C tests, got {}",
t.total_tests
);
}
#[test]
fn test_iostream_test_count() {
let mut t = X86StdLibTest::new();
t.run_iostream_tests();
assert!(t.total_tests >= 10, "Expected at least 10 iostream tests");
}
#[test]
fn test_cpp_string_test_count() {
let mut t = X86StdLibTest::new();
t.run_cpp_string_tests();
assert!(t.total_tests >= 15, "Expected at least 15 string tests");
}
#[test]
fn test_vector_test_count() {
let mut t = X86StdLibTest::new();
t.run_vector_tests();
assert!(t.total_tests >= 15, "Expected at least 15 vector tests");
}
#[test]
fn test_map_set_test_count() {
let mut t = X86StdLibTest::new();
t.run_map_set_tests();
assert!(t.total_tests >= 14, "Expected at least 14 map/set tests");
}
#[test]
fn test_unordered_test_count() {
let mut t = X86StdLibTest::new();
t.run_unordered_tests();
assert!(t.total_tests >= 6, "Expected at least 6 unordered tests");
}
#[test]
fn test_algorithm_test_count() {
let mut t = X86StdLibTest::new();
t.run_algorithm_tests();
assert!(t.total_tests >= 25, "Expected at least 25 algorithm tests");
}
#[test]
fn test_memory_test_count() {
let mut t = X86StdLibTest::new();
t.run_memory_tests();
assert!(t.total_tests >= 10, "Expected at least 10 memory tests");
}
#[test]
fn test_thread_test_count() {
let mut t = X86StdLibTest::new();
t.run_thread_tests();
assert!(t.total_tests >= 15, "Expected at least 15 thread tests");
}
#[test]
fn test_atomic_test_count() {
let mut t = X86StdLibTest::new();
t.run_atomic_tests();
assert!(t.total_tests >= 12, "Expected at least 12 atomic tests");
}
#[test]
fn test_functional_test_count() {
let mut t = X86StdLibTest::new();
t.run_functional_tests();
assert!(t.total_tests >= 8, "Expected at least 8 functional tests");
}
#[test]
fn test_type_traits_test_count() {
let mut t = X86StdLibTest::new();
t.run_type_traits_tests();
assert!(
t.total_tests >= 15,
"Expected at least 15 type_traits tests"
);
}
#[test]
fn test_modern_cpp_test_count() {
let mut t = X86StdLibTest::new();
t.run_modern_cpp_tests();
assert!(t.total_tests >= 20, "Expected at least 20 modern C++ tests");
}
#[test]
fn test_all_cpp_tests_complete() {
let mut t = X86StdLibTest::new();
t.run_all_cpp_tests();
assert!(
t.total_tests >= 80,
"Expected 80+ C++ tests, got {}",
t.total_tests
);
}
#[test]
fn test_build_and_run_x86_stdlib_suite() {
let t = build_and_run_x86_stdlib_suite();
assert!(t.total_tests >= 180, "Expected at least 180 total tests");
let has_c = t
.results
.iter()
.any(|r| matches!(r.category, X86StdLibCategory::CLibrary));
let has_cpp = t
.results
.iter()
.any(|r| matches!(r.category, X86StdLibCategory::CppLibrary));
assert!(has_c, "Should have C library tests");
assert!(has_cpp, "Should have C++ library tests");
}
#[test]
fn test_build_x86_32_suite() {
let t = build_x86_32_stdlib_suite();
assert_eq!(t.target_triple, "i686-unknown-linux-gnu");
assert!(t.total_tests >= 180);
}
#[test]
fn test_build_windows_suite() {
let t = build_windows_x86_64_stdlib_suite();
assert_eq!(t.target_triple, "x86_64-pc-windows-msvc");
assert!(t.total_tests >= 100);
}
#[test]
fn test_suite_with_benchmarks_enabled() {
let t = build_and_run_x86_stdlib_suite_with_benchmarks();
assert!(t.run_benchmarks);
assert!(t.total_benchmarks > 0, "Should have benchmark results");
}
#[test]
fn test_print_summary_empty() {
let t = X86StdLibTest::new();
let s = t.print_summary();
assert!(s.contains("Total tests: 0"));
assert!(s.contains("Pass rate: 100.0%"));
}
#[test]
fn test_print_summary_has_target() {
let t = X86StdLibTest::new();
let s = t.print_summary();
assert!(s.contains("x86_64-unknown-linux-gnu"));
}
#[test]
fn test_print_summary_with_results() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"dummy",
"#include <stdio.h>\nint main(void){return 0;}\n",
0,
);
let s = t.print_summary();
assert!(s.contains("Total tests: 1"));
}
#[test]
fn test_print_failures_empty() {
let t = X86StdLibTest::new();
let s = t.print_failures();
assert!(s.contains("No failures"));
}
#[test]
fn test_print_failures_with_failure() {
let mut t = X86StdLibTest::new();
t.total_tests = 1;
t.results.push(X86StdLibTestResult {
name: "fail_test".into(),
category: X86StdLibCategory::CLibrary,
passed: false,
compiled: false,
exit_code: None,
duration: Duration::ZERO,
messages: vec!["compilation error".into()],
ir_output: None,
asm_output: None,
});
let s = t.print_failures();
assert!(s.contains("fail_test"));
assert!(s.contains("compilation error"));
}
#[test]
fn test_stdio_printf_format_source_nonempty() {
let src = stdio_printf_format_source();
assert!(src.contains("printf"));
assert!(src.contains("main"));
}
#[test]
fn test_stdlib_alloc_stress_source_nonempty() {
let src = stdlib_alloc_stress_source();
assert!(src.contains("malloc"));
assert!(src.contains("free"));
assert!(src.contains("for"));
}
#[test]
fn test_string_combined_source_nonempty() {
let src = string_combined_source();
assert!(src.contains("strcpy"));
assert!(src.contains("strcat"));
assert!(src.contains("strlen"));
}
#[test]
fn test_math_combined_source_nonempty() {
let src = math_combined_source();
assert!(src.contains("sin"));
assert!(src.contains("cos"));
}
#[test]
fn test_vector_combined_source_nonempty() {
let src = vector_combined_source();
assert!(src.contains("vector"));
assert!(src.contains("sort"));
}
#[test]
fn test_smart_ptr_combined_source_nonempty() {
let src = smart_ptr_combined_source();
assert!(src.contains("shared_ptr"));
assert!(src.contains("weak_ptr"));
}
#[test]
fn test_verify_ir_contains_all_found() {
let ir = "define i32 @main() {\n ret i32 0\n}\n";
let (ok, missing) = verify_ir_contains(ir, &["define", "ret"]);
assert!(ok);
assert!(missing.is_empty());
}
#[test]
fn test_verify_ir_contains_some_missing() {
let ir = "define i32 @main() {\n ret i32 0\n}\n";
let (ok, missing) = verify_ir_contains(ir, &["define", "br"]);
assert!(!ok);
assert_eq!(missing, vec!["br"]);
}
#[test]
fn test_verify_ir_contains_empty_ir() {
let (ok, _) = verify_ir_contains("", &["define"]);
assert!(!ok);
}
#[test]
fn test_verify_ir_excludes_all_clean() {
let ir = "define i32 @main() {\n ret i32 0\n}\n";
let (ok, found) = verify_ir_excludes(ir, &["call", "@llvm"]);
assert!(ok);
assert!(found.is_empty());
}
#[test]
fn test_verify_ir_excludes_found() {
let ir = "call void @llvm.memset.p0i8.i64()\n";
let (ok, found) = verify_ir_excludes(ir, &["@llvm"]);
assert!(!ok);
assert_eq!(found, vec!["@llvm"]);
}
#[test]
fn test_rng_state_deterministic() {
let mut rng1 = X86RngState::new(42);
let mut rng2 = X86RngState::new(42);
for _ in 0..100 {
assert_eq!(rng1.next_u64(), rng2.next_u64());
}
}
#[test]
fn test_rng_state_diff_seed() {
let mut rng1 = X86RngState::new(1);
let mut rng2 = X86RngState::new(2);
assert_ne!(rng1.next_u64(), rng2.next_u64());
}
#[test]
fn test_rng_i32_produces_values() {
let mut rng = X86RngState::new(12345);
let mut values = Vec::new();
for _ in 0..100 {
values.push(rng.next_i32());
}
assert_eq!(values.len(), 100);
}
#[test]
fn test_benchmark_results_structure() {
let result = X86StdLibBenchResult {
name: "test_bench".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 1.5,
min_time_us: 1.0,
max_time_us: 2.0,
iterations: 100,
total_bytes: 4096,
};
assert_eq!(result.name, "test_bench");
assert_eq!(result.iterations, 100);
assert_eq!(result.total_bytes, 4096);
}
#[test]
fn test_run_benchmarks_produces_results() {
let mut t = X86StdLibTest::new()
.with_benchmarks(true)
.with_bench_iterations(10);
t.run_all_benchmarks();
assert!(t.total_benchmarks > 0);
assert!(!t.bench_results.is_empty());
}
#[test]
fn test_benchmarks_disabled_when_flag_off() {
let mut t = X86StdLibTest::new().with_benchmarks(false);
t.run_all_benchmarks();
assert_eq!(t.total_benchmarks, 0);
assert!(t.bench_results.is_empty());
}
#[test]
fn test_stdlib_test_default() {
let t = X86StdLibTest::default();
assert_eq!(t.target_triple, "x86_64-unknown-linux-gnu");
}
#[test]
fn test_run_single_c_test() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"simple_int",
"#include <stdio.h>\nint main(void) { return 0; }\n",
0,
);
assert_eq!(t.total_tests, 1);
assert!(t.results[0].name == "simple_int");
}
#[test]
fn test_run_single_cpp_test() {
let mut t = X86StdLibTest::new();
t.run_cpp_test(
"simple_cpp",
"#include <iostream>\nint main() { return 0; }\n",
);
assert_eq!(t.total_tests, 1);
assert_eq!(t.results[0].category, X86StdLibCategory::CppLibrary);
}
#[test]
fn test_run_all_c_tests_has_all_categories() {
let mut t = X86StdLibTest::new();
t.run_all_c_tests();
let c_count = t
.results
.iter()
.filter(|r| matches!(r.category, X86StdLibCategory::CLibrary))
.count();
assert_eq!(c_count as u64, t.total_tests);
}
#[test]
fn test_run_all_cpp_tests_has_correct_category() {
let mut t = X86StdLibTest::new();
t.run_all_cpp_tests();
let cpp_count = t
.results
.iter()
.filter(|r| matches!(r.category, X86StdLibCategory::CppLibrary))
.count();
assert_eq!(cpp_count as u64, t.total_tests);
}
#[test]
fn test_individual_test_categories() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
let count_a = t.total_tests;
t.reset();
t.run_stdlib_tests();
let count_b = t.total_tests;
t.reset();
t.run_string_tests();
let count_c = t.total_tests;
assert!(count_a > 0, "stdio tests should not be empty");
assert!(count_b > 0, "stdlib tests should not be empty");
assert!(count_c > 0, "string tests should not be empty");
}
#[test]
fn test_math_tests_includes_all_subcategories() {
let mut t = X86StdLibTest::new();
t.run_math_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n.contains("sin")));
assert!(names.iter().any(|n| n.contains("cos")));
assert!(names.iter().any(|n| n.contains("exp")));
assert!(names.iter().any(|n| n.contains("log")));
assert!(names.iter().any(|n| n.contains("pow")));
assert!(names.iter().any(|n| n.contains("sqrt")));
}
#[test]
fn test_ctype_comprehensive() {
let mut t = X86StdLibTest::new();
t.run_ctype_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n == "ctype_isalpha_upper"));
assert!(names.iter().any(|n| n == "ctype_isdigit"));
assert!(names.iter().any(|n| n == "ctype_isupper"));
assert!(names.iter().any(|n| n == "ctype_toupper"));
assert!(names.iter().any(|n| n == "ctype_tolower"));
}
#[test]
fn test_vector_cpp_comprehensive() {
let mut t = X86StdLibTest::new();
t.run_vector_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n == "vector_push_back"));
assert!(names.iter().any(|n| n == "vector_emplace_back"));
assert!(names.iter().any(|n| n == "vector_reserve"));
assert!(names.iter().any(|n| n == "vector_iterator"));
assert!(names.iter().any(|n| n == "vector_data"));
}
#[test]
fn test_algorithm_cpp_comprehensive() {
let mut t = X86StdLibTest::new();
t.run_algorithm_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n.contains("sort")));
assert!(names.iter().any(|n| n.contains("find")));
assert!(names.iter().any(|n| n.contains("copy")));
assert!(names.iter().any(|n| n.contains("transform")));
assert!(names.iter().any(|n| n.contains("binary_search")));
}
#[test]
fn test_memory_cpp_comprehensive() {
let mut t = X86StdLibTest::new();
t.run_memory_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n.contains("unique_ptr")));
assert!(names.iter().any(|n| n.contains("shared_ptr")));
assert!(names.iter().any(|n| n.contains("weak_ptr")));
}
#[test]
fn test_thread_cpp_comprehensive() {
let mut t = X86StdLibTest::new();
t.run_thread_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n.contains("mutex")));
assert!(names.iter().any(|n| n.contains("thread")));
assert!(names.iter().any(|n| n.contains("condition_variable")));
assert!(names.iter().any(|n| n.contains("future")));
}
#[test]
fn test_modern_cpp_comprehensive() {
let mut t = X86StdLibTest::new();
t.run_modern_cpp_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| n.contains("optional")));
assert!(names.iter().any(|n| n.contains("variant")));
assert!(names.iter().any(|n| n.contains("any")));
assert!(names.iter().any(|n| n.contains("string_view")));
assert!(names.iter().any(|n| n.contains("span")));
}
#[test]
fn test_print_summary_with_benchmarks() {
let mut t = X86StdLibTest::new().with_benchmarks(true);
t.bench_results.push(X86StdLibBenchResult {
name: "test_bench".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 1.23,
min_time_us: 1.0,
max_time_us: 2.0,
iterations: 10,
total_bytes: 1000,
});
t.total_benchmarks = 1;
let s = t.print_summary();
assert!(s.contains("Benchmarks"));
assert!(s.contains("1.23"));
}
#[test]
fn test_each_math_function_present() {
let mut t = X86StdLibTest::new();
t.run_math_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| *n == "math_sin"));
assert!(names.iter().any(|n| *n == "math_cos"));
assert!(names.iter().any(|n| *n == "math_tan"));
assert!(names.iter().any(|n| *n == "math_asin"));
assert!(names.iter().any(|n| *n == "math_acos"));
assert!(names.iter().any(|n| *n == "math_atan"));
assert!(names.iter().any(|n| *n == "math_atan2"));
assert!(names.iter().any(|n| *n == "math_sinh"));
assert!(names.iter().any(|n| *n == "math_cosh"));
assert!(names.iter().any(|n| *n == "math_tanh"));
assert!(names.iter().any(|n| *n == "math_exp"));
assert!(names.iter().any(|n| *n == "math_exp2"));
assert!(names.iter().any(|n| *n == "math_expm1"));
assert!(names.iter().any(|n| *n == "math_log"));
assert!(names.iter().any(|n| *n == "math_log2"));
assert!(names.iter().any(|n| *n == "math_log10"));
assert!(names.iter().any(|n| *n == "math_log1p"));
assert!(names.iter().any(|n| *n == "math_pow"));
assert!(names.iter().any(|n| *n == "math_sqrt"));
assert!(names.iter().any(|n| *n == "math_cbrt"));
assert!(names.iter().any(|n| *n == "math_hypot"));
assert!(names.iter().any(|n| *n == "math_fabs"));
assert!(names.iter().any(|n| *n == "math_ceil"));
assert!(names.iter().any(|n| *n == "math_floor"));
assert!(names.iter().any(|n| *n == "math_trunc"));
assert!(names.iter().any(|n| *n == "math_round"));
assert!(names.iter().any(|n| *n == "math_rint"));
assert!(names.iter().any(|n| *n == "math_fma"));
assert!(names.iter().any(|n| *n == "math_erf"));
assert!(names.iter().any(|n| *n == "math_erfc"));
assert!(names.iter().any(|n| *n == "math_tgamma"));
assert!(names.iter().any(|n| *n == "math_lgamma"));
assert!(names.iter().any(|n| *n == "math_constants"));
}
#[test]
fn test_each_string_function_present() {
let mut t = X86StdLibTest::new();
t.run_string_tests();
let names: Vec<&str> = t.results.iter().map(|r| r.name.as_str()).collect();
assert!(names.iter().any(|n| *n == "string_memcpy"));
assert!(names.iter().any(|n| *n == "string_memmove"));
assert!(names.iter().any(|n| *n == "string_memset"));
assert!(names.iter().any(|n| *n == "string_memcmp"));
assert!(names.iter().any(|n| *n == "string_memchr"));
assert!(names.iter().any(|n| *n == "string_strcpy"));
assert!(names.iter().any(|n| *n == "string_strncpy"));
assert!(names.iter().any(|n| *n == "string_strcat"));
assert!(names.iter().any(|n| *n == "string_strncat"));
assert!(names.iter().any(|n| *n == "string_strcmp"));
assert!(names.iter().any(|n| *n == "string_strncmp"));
assert!(names.iter().any(|n| *n == "string_strlen"));
assert!(names.iter().any(|n| *n == "string_strchr"));
assert!(names.iter().any(|n| *n == "string_strrchr"));
assert!(names.iter().any(|n| *n == "string_strstr"));
assert!(names.iter().any(|n| *n == "string_strtok"));
assert!(names.iter().any(|n| *n == "string_strerror"));
assert!(names.iter().any(|n| *n == "string_strpbrk"));
assert!(names.iter().any(|n| *n == "string_strspn"));
assert!(names.iter().any(|n| *n == "string_strcspn"));
}
#[test]
fn test_complete_suite_has_all_categories_in_summary() {
let t = build_and_run_x86_stdlib_suite();
let s = t.print_summary();
assert!(s.contains("C Library"));
assert!(s.contains("C++ Library"));
}
#[test]
fn test_benchmark_results_have_names() {
let mut t = X86StdLibTest::new()
.with_benchmarks(true)
.with_bench_iterations(5);
t.run_all_benchmarks();
for b in &t.bench_results {
assert!(!b.name.is_empty());
}
}
#[test]
fn test_benchmark_results_have_positive_iters() {
let mut t = X86StdLibTest::new()
.with_benchmarks(true)
.with_bench_iterations(5);
t.run_all_benchmarks();
for b in &t.bench_results {
assert!(b.iterations > 0);
}
}
#[test]
fn test_benchmark_struct_new() {
let b = X86StdLibBenchmark::new("test_bench");
assert_eq!(b.name, "test_bench");
assert_eq!(b.iterations, 100);
assert!(!b.verbose);
}
#[test]
fn test_benchmark_struct_with_iterations() {
let b = X86StdLibBenchmark::new("test").with_iterations(500);
assert_eq!(b.iterations, 500);
}
#[test]
fn test_benchmark_struct_verbose() {
let b = X86StdLibBenchmark::new("test").with_verbose(true);
assert!(b.verbose);
}
#[test]
fn test_benchmark_struct_add_measurement() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(1.5, 1024);
assert_eq!(b.measurements.len(), 1);
assert_eq!(b.measurements[0].0, 1.5);
assert_eq!(b.measurements[0].1, 1024);
}
#[test]
fn test_benchmark_struct_avg_time() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(1.0, 100);
b.add_measurement(2.0, 100);
b.add_measurement(3.0, 100);
assert!((b.average_time_us() - 2.0).abs() < 0.001);
}
#[test]
fn test_benchmark_struct_avg_time_empty() {
let b = X86StdLibBenchmark::new("test");
assert_eq!(b.average_time_us(), 0.0);
}
#[test]
fn test_benchmark_struct_min_time() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(5.0, 100);
b.add_measurement(1.0, 100);
b.add_measurement(3.0, 100);
assert!((b.min_time_us() - 1.0).abs() < 0.001);
}
#[test]
fn test_benchmark_struct_max_time() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(1.0, 100);
b.add_measurement(5.0, 100);
b.add_measurement(3.0, 100);
assert!((b.max_time_us() - 5.0).abs() < 0.001);
}
#[test]
fn test_benchmark_struct_total_bytes() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(1.0, 1024);
b.add_measurement(2.0, 2048);
assert_eq!(b.total_bytes_processed(), 3072);
}
#[test]
fn test_benchmark_struct_throughput() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(100.0, 1024);
b.add_measurement(100.0, 1024);
let tp = b.throughput_bytes_per_us();
assert!((tp - 10.24).abs() < 0.1);
}
#[test]
fn test_benchmark_struct_throughput_empty() {
let b = X86StdLibBenchmark::new("test");
assert_eq!(b.throughput_bytes_per_us(), 0.0);
}
#[test]
fn test_benchmark_struct_reset() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(1.0, 100);
b.reset();
assert!(b.measurements.is_empty());
}
#[test]
fn test_benchmark_struct_report() {
let mut b = X86StdLibBenchmark::new("test");
b.add_measurement(1.5, 1024);
let report = b.report();
assert!(report.contains("test"));
assert!(report.contains("1.5"));
}
#[test]
fn test_benchmark_struct_report_empty() {
let b = X86StdLibBenchmark::new("empty");
let report = b.report();
assert!(report.contains("empty"));
assert!(report.contains("0 measurements"));
}
#[test]
fn test_benchmark_struct_display() {
let mut b = X86StdLibBenchmark::new("display_bench");
b.add_measurement(2.5, 512);
let s = format!("{}", b);
assert!(s.contains("display_bench"));
assert!(s.contains("2.5"));
}
#[test]
fn test_benchmark_struct_clone() {
let mut b1 = X86StdLibBenchmark::new("clone_test");
b1.add_measurement(1.0, 100);
let b2 = b1.clone();
assert_eq!(b2.name, b1.name);
assert_eq!(b2.measurements.len(), b1.measurements.len());
}
#[test]
fn test_benchmark_struct_is_faster_than() {
let mut b1 = X86StdLibBenchmark::new("fast");
let mut b2 = X86StdLibBenchmark::new("slow");
b1.add_measurement(1.0, 100);
b2.add_measurement(10.0, 100);
assert!(b1.is_faster_than(&b2));
assert!(!b2.is_faster_than(&b1));
}
#[test]
fn test_benchmark_struct_is_faster_than_empty() {
let b1 = X86StdLibBenchmark::new("a");
let b2 = X86StdLibBenchmark::new("b");
assert!(!b1.is_faster_than(&b2));
}
#[test]
fn test_test_result_passed_default_false() {
let r = X86StdLibTestResult {
name: "test".into(),
category: X86StdLibCategory::CLibrary,
passed: false,
compiled: false,
exit_code: None,
duration: Duration::ZERO,
messages: vec![],
ir_output: None,
asm_output: None,
};
assert!(!r.passed);
}
#[test]
fn test_test_result_with_ir_output() {
let r = X86StdLibTestResult {
name: "ir_test".into(),
category: X86StdLibCategory::CLibrary,
passed: true,
compiled: true,
exit_code: Some(0),
duration: Duration::from_millis(10),
messages: vec!["ok".into()],
ir_output: Some("define i32 @main()".into()),
asm_output: None,
};
assert!(r.ir_output.is_some());
assert!(r.asm_output.is_none());
}
#[test]
fn test_test_result_duration_positive() {
let r = X86StdLibTestResult {
name: "timed".into(),
category: X86StdLibCategory::Benchmark,
passed: true,
compiled: true,
exit_code: Some(0),
duration: Duration::from_millis(42),
messages: vec![],
ir_output: None,
asm_output: None,
};
assert!(r.duration.as_millis() > 0);
}
#[test]
fn test_bench_result_min_max_tracking() {
let mut r = X86StdLibBenchResult {
name: "tracking".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 0.0,
min_time_us: f64::MAX,
max_time_us: 0.0,
iterations: 0,
total_bytes: 0,
};
for t in [3.0, 1.0, 5.0, 2.0, 4.0].iter() {
if *t < r.min_time_us {
r.min_time_us = *t;
}
if *t > r.max_time_us {
r.max_time_us = *t;
}
r.iterations += 1;
}
assert_eq!(r.iterations, 5);
assert_eq!(r.min_time_us, 1.0);
assert_eq!(r.max_time_us, 5.0);
}
#[test]
fn test_bench_result_large_bytes() {
let r = X86StdLibBenchResult {
name: "large".into(),
category: X86StdLibCategory::Benchmark,
avg_time_us: 100.0,
min_time_us: 50.0,
max_time_us: 200.0,
iterations: 1000,
total_bytes: 1_000_000_000,
};
assert_eq!(r.total_bytes, 1_000_000_000);
}
#[test]
fn test_x86_32_target_configuration() {
let t = X86StdLibTest::new_x86_32();
assert_eq!(t.target_triple, "i686-unknown-linux-gnu");
assert_eq!(t.c_standard, CLangStandard::C17);
}
#[test]
fn test_windows_target_configuration() {
let t = X86StdLibTest::new_windows_x86_64();
assert_eq!(t.target_triple, "x86_64-pc-windows-msvc");
}
#[test]
fn test_opt_level_chainable() {
let t = X86StdLibTest::new()
.with_opt_level(X86OptLevel::O0)
.with_opt_level(X86OptLevel::Os)
.with_opt_level(X86OptLevel::Oz);
assert_eq!(t.opt_level, X86OptLevel::Oz);
}
#[test]
fn test_flag_accumulation() {
let t = X86StdLibTest::new()
.with_flag("-Wall")
.with_flag("-Wextra")
.with_flag("-Werror");
assert_eq!(t.extra_flags.len(), 3);
}
#[test]
fn test_include_dir_accumulation() {
let t = X86StdLibTest::new()
.with_include_dir("/usr/include")
.with_include_dir("/usr/local/include");
assert_eq!(t.include_dirs.len(), 2);
}
#[test]
fn test_link_lib_accumulation() {
let t = X86StdLibTest::new()
.with_link_lib("pthread")
.with_link_lib("m")
.with_link_lib("dl");
assert_eq!(t.link_libs.len(), 3);
}
#[test]
fn test_many_results_handling() {
let mut t = X86StdLibTest::new();
for i in 0..1000 {
t.results.push(X86StdLibTestResult {
name: format!("test_{}", i),
category: X86StdLibCategory::CLibrary,
passed: i % 2 == 0,
compiled: true,
exit_code: Some(0),
duration: Duration::ZERO,
messages: vec![],
ir_output: None,
asm_output: None,
});
t.total_tests += 1;
if i % 2 == 0 {
t.total_passed += 1;
}
}
let rate = t.pass_rate();
assert!((rate - 50.0).abs() < 1.0);
}
#[test]
fn test_many_benchmark_results() {
let mut t = X86StdLibTest::new();
for i in 0..500 {
t.bench_results.push(X86StdLibBenchResult {
name: format!("bench_{}", i),
category: X86StdLibCategory::Benchmark,
avg_time_us: i as f64,
min_time_us: (i as f64) * 0.5,
max_time_us: (i as f64) * 2.0,
iterations: 100,
total_bytes: 4096,
});
t.total_benchmarks += 1;
}
let s = t.print_summary();
assert!(s.contains("500 total"));
}
#[test]
fn test_consecutive_resets() {
let mut t = X86StdLibTest::new();
t.total_tests = 100;
t.total_passed = 100;
t.results.push(X86StdLibTestResult {
name: "x".into(),
category: X86StdLibCategory::CLibrary,
passed: true,
compiled: true,
exit_code: Some(0),
duration: Duration::ZERO,
messages: vec![],
ir_output: None,
asm_output: None,
});
t.reset();
assert_eq!(t.total_tests, 0);
t.reset();
assert_eq!(t.total_tests, 0);
}
#[test]
fn test_empty_source_compilation() {
let mut t = X86StdLibTest::new();
t.run_c_test("empty", "int main(void) { return 0; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_zero_length_string() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"empty_str",
"#include <string.h>\nint main(void) { return (strlen(\"\") == 0) ? 0 : 1; }\n",
0,
);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_null_pointer_handling() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"null_free",
"#include <stdlib.h>\nint main(void) { free(NULL); return 0; }\n",
0,
);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_max_size_allocation() {
let mut t = X86StdLibTest::new();
t.run_c_test("max_alloc",
"#include <stdlib.h>\nint main(void) { void *p = malloc((size_t)-1); free(p); return 0; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_negative_seek() {
let mut t = X86StdLibTest::new();
t.run_c_test("neg_seek",
"#include <stdio.h>\nint main(void) { FILE *f = fopen(\"/dev/null\", \"r\"); if (f) { fseek(f, -1, SEEK_SET); fclose(f); } return 0; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_infinity_operations() {
let mut t = X86StdLibTest::new();
t.run_c_test("inf_ops",
"#include <math.h>\nint main(void) { double x = INFINITY; double y = -INFINITY; return (x > y) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_nan_comparison() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"nan_cmp",
"#include <math.h>\nint main(void) { double x = NAN; return (x != x) ? 0 : 1; }\n",
0,
);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_negative_time() {
let mut t = X86StdLibTest::new();
t.run_c_test("neg_time",
"#include <time.h>\nint main(void) { time_t t = -1; double d = difftime(0, 100); return (d < 0) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_verify_ir_contains_multiple_patterns() {
let ir =
"target triple = \"x86_64-unknown-linux-gnu\"\ndefine i32 @main() {\n ret i32 0\n}\n";
let (ok, _) = verify_ir_contains(ir, &["target triple", "define", "ret"]);
assert!(ok);
}
#[test]
fn test_verify_ir_contains_empty_patterns() {
let (ok, _) = verify_ir_contains("anything", &[]);
assert!(ok);
}
#[test]
fn test_verify_ir_excludes_empty_patterns() {
let (ok, _) = verify_ir_excludes("anything", &[]);
assert!(ok);
}
#[test]
fn test_verify_ir_excludes_case_sensitivity() {
let ir = "define i32 @MAIN() { ret i32 0 }";
let (ok, _) = verify_ir_excludes(ir, &["@main"]);
assert!(ok);
}
#[test]
fn test_printf_empty_format() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"printf_empty",
"#include <stdio.h>\nint main(void) { printf(\"\"); return 0; }\n",
0,
);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_printf_percent_percent() {
let mut t = X86StdLibTest::new();
t.run_c_test(
"printf_pct",
"#include <stdio.h>\nint main(void) { printf(\"100%%\\n\"); return 0; }\n",
0,
);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_calloc_zeroed() {
let mut t = X86StdLibTest::new();
t.run_c_test("calloc_zeroed",
"#include <stdlib.h>\nint main(void) { int *p = calloc(10, sizeof(int)); if (!p) return 1; for (int i = 0; i < 10; i++) if (p[i] != 0) { free(p); return 1; } free(p); return 0; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_realloc_to_same_size() {
let mut t = X86StdLibTest::new();
t.run_c_test("realloc_same",
"#include <stdlib.h>\nint main(void) { void *p = malloc(64); void *q = realloc(p, 64); if (q) free(q); return 0; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strtol_base_16() {
let mut t = X86StdLibTest::new();
t.run_c_test("strtol_base16",
"#include <stdlib.h>\nint main(void) { char *end; long x = strtol(\"0xFF\", &end, 16); return (x == 255) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strtol_base_8() {
let mut t = X86StdLibTest::new();
t.run_c_test("strtol_base8",
"#include <stdlib.h>\nint main(void) { char *end; long x = strtol(\"077\", &end, 8); return (x == 63) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_qsort_single_element() {
let mut t = X86StdLibTest::new();
t.run_c_test("qsort_one",
"#include <stdlib.h>\nint cmp(const void *a, const void *b) { return (*(int*)a - *(int*)b); }\nint main(void) { int arr[] = {42}; qsort(arr, 1, sizeof(int), cmp); return (arr[0] == 42) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_qsort_empty() {
let mut t = X86StdLibTest::new();
t.run_c_test("qsort_empty",
"#include <stdlib.h>\nint cmp(const void *a, const void *b) { return 0; }\nint main(void) { qsort(NULL, 0, sizeof(int), cmp); return 0; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_bsearch_single_element() {
let mut t = X86StdLibTest::new();
t.run_c_test("bsearch_one",
"#include <stdlib.h>\nint cmp(const void *a, const void *b) { return (*(int*)a - *(int*)b); }\nint main(void) { int arr[] = {42}; int key = 42; int *found = bsearch(&key, arr, 1, sizeof(int), cmp); return (found != NULL && *found == 42) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_memcmp_identical_buffers() {
let mut t = X86StdLibTest::new();
t.run_c_test("memcmp_identical",
"#include <string.h>\nint main(void) { char a[64], b[64]; memset(a, 0xAB, 64); memset(b, 0xAB, 64); return (memcmp(a, b, 64) == 0) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_memchr_boundary() {
let mut t = X86StdLibTest::new();
t.run_c_test("memchr_bound",
"#include <string.h>\nint main(void) { char buf[] = {0, 1, 2, 3, 0}; char *p = memchr(buf, 0, 5); return (p == buf) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strncpy_exact_fit() {
let mut t = X86StdLibTest::new();
t.run_c_test("strncpy_exact",
"#include <string.h>\nint main(void) { char dst[6]; strncpy(dst, \"hello\", 6); return (dst[5] == '\\0') ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strtok_empty_string() {
let mut t = X86StdLibTest::new();
t.run_c_test("strtok_empty",
"#include <string.h>\nint main(void) { char buf[] = \"\"; char *tok = strtok(buf, \",\"); return (tok == NULL) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strtok_no_delimiters() {
let mut t = X86StdLibTest::new();
t.run_c_test("strtok_nodelim",
"#include <string.h>\nint main(void) { char buf[] = \"hello\"; char *tok = strtok(buf, \",\"); return (tok != NULL && strcmp(tok, \"hello\") == 0) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strpbrk_empty_accept() {
let mut t = X86StdLibTest::new();
t.run_c_test("strpbrk_emptyacc",
"#include <string.h>\nint main(void) { const char *p = strpbrk(\"hello\", \"\"); return (p == NULL) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strspn_entire_string() {
let mut t = X86StdLibTest::new();
t.run_c_test("strspn_entire",
"#include <string.h>\nint main(void) { size_t n = strspn(\"abc\", \"abcdef\"); return (n == 3) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_strcspn_entire_string() {
let mut t = X86StdLibTest::new();
t.run_c_test("strcspn_entire",
"#include <string.h>\nint main(void) { size_t n = strcspn(\"abc\", \"xyz\"); return (n == 3) ? 0 : 1; }\n", 0);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_string_default_empty() {
let mut t = X86StdLibTest::new();
t.run_cpp_test(
"string_default_empty",
"#include <string>\nint main() { std::string s; return s.empty() ? 0 : 1; }\n",
);
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_string_max_size() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("string_maxsize",
"#include <string>\nint main() { std::string s; size_t m = s.max_size(); return (m > 0) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_vector_shrink_to_fit() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("vector_shrink",
"#include <vector>\nint main() { std::vector<int> v; v.reserve(100); v.push_back(1); v.shrink_to_fit(); return (v.size() == 1) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_map_empty_find() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("map_empty_find",
"#include <map>\nint main() { std::map<int,int> m; auto it = m.find(5); return (it == m.end()) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_map_equal_range() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("map_eqrange",
"#include <map>\nint main() { std::map<int,int> m = {{1,10},{2,20}}; auto p = m.equal_range(1); return (p.first != m.end()) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_set_lower_bound() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("set_lower_bound",
"#include <set>\nint main() { std::set<int> s = {1,2,3,4,5}; auto it = s.lower_bound(3); return (*it == 3) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_unordered_map_load_factor() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("umap_loadfactor",
"#include <unordered_map>\nint main() { std::unordered_map<int,int> um = {{1,10}}; float lf = um.load_factor(); return (lf > 0.0f) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_unordered_map_max_load_factor() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("umap_maxlf",
"#include <unordered_map>\nint main() { std::unordered_map<int,int> um; um.max_load_factor(0.5f); return (um.max_load_factor() >= 0.49f) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_any_of() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_any_of",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,3,5}; bool r = std::any_of(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); return !r ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_all_of() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_all_of",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,3,5}; bool r = std::all_of(v.begin(), v.end(), [](int x){ return x % 2 == 1; }); return r ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_none_of() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_none_of",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,3,5}; bool r = std::none_of(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); return r ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_find_if() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_find_if",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,2,3,4,5}; auto it = std::find_if(v.begin(), v.end(), [](int x){ return x > 3; }); return (*it == 4) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_copy_if() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_copy_if",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,2,3,4,5}; std::vector<int> out(5); auto it = std::copy_if(v.begin(), v.end(), out.begin(), [](int x){ return x % 2 == 0; }); return ((it - out.begin()) == 2) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_remove_if() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_remove_if",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,2,3,4,5}; auto it = std::remove_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); v.erase(it, v.end()); return (v.size() == 3) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_replace() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_replace",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,2,2,3}; std::replace(v.begin(), v.end(), 2, 99); return (v[1] == 99 && v[2] == 99) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_rotate() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_rotate",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,2,3,4,5}; std::rotate(v.begin(), v.begin() + 2, v.end()); return (v[0] == 3 && v[4] == 2) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_next_permutation() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_next_perm",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {1,2,3}; std::next_permutation(v.begin(), v.end()); return (v[0] == 1 && v[1] == 3 && v[2] == 2) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_prev_permutation() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_prev_perm",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> v = {3,2,1}; std::prev_permutation(v.begin(), v.end()); return (v[0] == 3 && v[1] == 1 && v[2] == 2) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_shuffle() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_shuffle",
"#include <algorithm>\n#include <random>\n#include <vector>\nint main() { std::vector<int> v = {1,2,3,4,5}; std::random_device rd; std::mt19937 g(rd()); std::shuffle(v.begin(), v.end(), g); return (v.size() == 5) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_sample() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_sample",
"#include <algorithm>\n#include <random>\n#include <vector>\nint main() { std::vector<int> pop = {1,2,3,4,5,6,7,8,9,10}; std::vector<int> out(3); std::random_device rd; std::mt19937 g(rd()); std::sample(pop.begin(), pop.end(), out.begin(), 3, g); return (out.size() == 3) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_lexicographical_compare() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_lexcmp",
"#include <algorithm>\n#include <vector>\nint main() { std::vector<int> a = {1,2,3}, b = {1,2,4}; bool r = std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); return r ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_clamp() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_clamp",
"#include <algorithm>\nint main() { int v = std::clamp(50, 0, 100); return (v == 50) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_clamp_low() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_clamp_low",
"#include <algorithm>\nint main() { int v = std::clamp(-10, 0, 100); return (v == 0) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_algorithm_clamp_high() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("algo_clamp_high",
"#include <algorithm>\nint main() { int v = std::clamp(200, 0, 100); return (v == 100) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_memory_allocator_traits() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("allocator_traits",
"#include <memory>\nint main() { using at = std::allocator_traits<std::allocator<int>>; auto a = at::allocate(std::allocator<int>(), 1); at::deallocate(std::allocator<int>(), a, 1); return 0; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_unique_ptr_deleter() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("unique_ptr_deleter",
"#include <memory>\nstruct D { void operator()(int *p) { delete p; } };\nint main() { std::unique_ptr<int, D> p(new int(42)); return (*p == 42) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_shared_ptr_aliasing() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("shared_ptr_alias",
"#include <memory>\nstruct S { int a; int b; };\nint main() { auto p = std::make_shared<S>(); p->a = 1; p->b = 2; std::shared_ptr<int> alias(p, &p->b); return (*alias == 2) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_weak_ptr_owner_before() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("weak_ptr_owner_before",
"#include <memory>\nint main() { auto s1 = std::make_shared<int>(1); auto s2 = std::make_shared<int>(2); std::weak_ptr<int> w1 = s1, w2 = s2; bool b = w1.owner_before(w2) || w2.owner_before(w1); return b ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_mutex_scoped_lock() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("scoped_lock",
"#include <mutex>\nint main() { std::mutex m1, m2; std::scoped_lock lock(m1, m2); return 0; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_call_once() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("call_once",
"#include <mutex>\nint counter = 0; std::once_flag flag;\nvoid init() { counter++; }\nint main() { std::call_once(flag, init); return (counter == 1) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_atomic_thread_fence() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("atomic_fence",
"#include <atomic>\nint main() { std::atomic_thread_fence(std::memory_order_seq_cst); return 0; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_atomic_signal_fence() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("atomic_sigfence",
"#include <atomic>\nint main() { std::atomic_signal_fence(std::memory_order_seq_cst); return 0; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_functional_mem_fn() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("mem_fn",
"#include <functional>\n#include <string>\nint main() { std::string s = \"hello\"; auto f = std::mem_fn(&std::string::size); return (f(s) == 5) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_functional_not_fn() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("not_fn",
"#include <functional>\nint main() { auto f = std::not_fn([](bool b) { return b; }); return !f(true) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_functional_invoke() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("invoke",
"#include <functional>\nint add(int a, int b) { return a + b; }\nint main() { return (std::invoke(add, 2, 3) == 5) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_type_traits_enable_if() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("enable_if",
"#include <type_traits>\ntemplate<typename T> typename std::enable_if<std::is_integral<T>::value, T>::type id(T v) { return v; }\nint main() { return (id(42) == 42) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_optional_swap() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("optional_swap",
"#include <optional>\nint main() { std::optional<int> a = 1, b = 2; a.swap(b); return (*a == 2 && *b == 1) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_variant_holds_no_value() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("variant_noval",
"#include <variant>\nint main() { std::variant<int, float> v; return std::holds_alternative<int>(v) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_string_view_starts_with() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("sv_starts_with",
"#include <string_view>\nint main() { std::string_view sv = \"hello world\"; return sv.starts_with(\"hello\") ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_string_view_ends_with() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("sv_ends_with",
"#include <string_view>\nint main() { std::string_view sv = \"hello world\"; return sv.ends_with(\"world\") ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_span_static_extent() {
let mut t = X86StdLibTest::new();
t.run_cpp_test("span_static_ext",
"#include <span>\nint main() { int arr[5] = {1,2,3,4,5}; std::span<int, 5> s(arr); return (s.size() == 5 && s[2] == 3) ? 0 : 1; }\n");
assert_eq!(t.total_tests, 1);
}
#[test]
fn test_suite_x86_32_target() {
let t = build_x86_32_stdlib_suite();
assert_eq!(t.target_triple, "i686-unknown-linux-gnu");
assert!(t.total_tests > 0);
}
#[test]
fn test_suite_windows_target() {
let t = build_windows_x86_64_stdlib_suite();
assert_eq!(t.target_triple, "x86_64-pc-windows-msvc");
}
#[test]
fn test_suite_with_benchmarks_builder() {
let t = build_and_run_x86_stdlib_suite_with_benchmarks();
assert!(t.run_benchmarks);
assert_eq!(t.bench_iterations, 50);
assert!(t.total_benchmarks > 0);
}
#[test]
fn test_stdio_has_printf() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("printf")));
}
#[test]
fn test_stdio_has_scanf() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("scanf")));
}
#[test]
fn test_stdio_has_fopen() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("fopen")));
}
#[test]
fn test_stdio_has_fread_fwrite() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("fread")));
assert!(t.results.iter().any(|r| r.name.contains("fwrite")));
}
#[test]
fn test_stdio_has_sprintf_snprintf() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("sprintf")));
assert!(t.results.iter().any(|r| r.name.contains("snprintf")));
}
#[test]
fn test_stdio_has_fprintf_fscanf() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("fprintf")));
assert!(t.results.iter().any(|r| r.name.contains("fscanf")));
}
#[test]
fn test_stdio_has_fgets_fputs() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("fgets")));
assert!(t.results.iter().any(|r| r.name.contains("fputs")));
}
#[test]
fn test_stdio_has_getc_putc_getchar_putchar_puts() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("getc")));
assert!(t.results.iter().any(|r| r.name.contains("putc")));
assert!(t.results.iter().any(|r| r.name.contains("getchar")));
assert!(t.results.iter().any(|r| r.name.contains("putchar")));
assert!(t.results.iter().any(|r| r.name.contains("puts")));
}
#[test]
fn test_stdio_has_fseek_ftell_fflush() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("fseek")));
assert!(t.results.iter().any(|r| r.name.contains("ftell")));
assert!(t.results.iter().any(|r| r.name.contains("fflush")));
}
#[test]
fn test_stdio_has_setbuf_setvbuf() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("setbuf")));
assert!(t.results.iter().any(|r| r.name.contains("setvbuf")));
}
#[test]
fn test_stdio_has_remove_rename() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("remove")));
assert!(t.results.iter().any(|r| r.name.contains("rename")));
}
#[test]
fn test_stdio_has_tmpfile_tmpnam() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("tmpfile")));
assert!(t.results.iter().any(|r| r.name.contains("tmpnam")));
}
#[test]
fn test_stdio_has_stderr_perror() {
let mut t = X86StdLibTest::new();
t.run_stdio_tests();
assert!(t.results.iter().any(|r| r.name.contains("stderr")));
assert!(t.results.iter().any(|r| r.name.contains("perror")));
}
}